chore: release 0.29.0.rc0 (#1600)

This commit is contained in:
Jan-Otto Kröpke
2024-09-11 00:34:10 +02:00
committed by GitHub
parent 83b0aa8f62
commit f712c07c38
119 changed files with 5113 additions and 2255 deletions

View File

@@ -1,21 +1,14 @@
//go:build windows
// +build windows
// Package eventlog provides a Logger that writes to Windows Event Log.
package eventlog
import (
"bytes"
"errors"
"fmt"
"io"
"sync"
"syscall"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"golang.org/x/sys/windows"
goeventlog "golang.org/x/sys/windows/svc/eventlog"
)
const (
@@ -25,109 +18,36 @@ const (
neLogOemCode = uint32(3299)
)
type Priority struct {
etype int
// Interface guard.
var _ io.Writer = (*Writer)(nil)
type Writer struct {
handle windows.Handle
}
// NewEventLogLogger returns a new Logger which writes to Windows EventLog in event log format.
// The body of the log message is the formatted output from the Logger returned
// by newLogger.
func NewEventLogLogger(w *goeventlog.Log, newLogger func(io.Writer) log.Logger) log.Logger {
l := &eventlogLogger{
w: w,
newLogger: newLogger,
prioritySelector: defaultPrioritySelector,
bufPool: sync.Pool{New: func() interface{} {
return &loggerBuf{}
}},
// NewEventLogWriter returns a new Writer which writes to Windows EventLog.
func NewEventLogWriter(handle windows.Handle) *Writer {
return &Writer{handle: handle}
}
func (w *Writer) Write(p []byte) (int, error) {
var eType uint16
switch {
case bytes.Contains(p, []byte(" level=error")) || bytes.Contains(p, []byte(`"level":"error"`)):
eType = windows.EVENTLOG_ERROR_TYPE
case bytes.Contains(p, []byte(" level=warn")) || bytes.Contains(p, []byte(`"level":"warn"`)):
eType = windows.EVENTLOG_WARNING_TYPE
default:
eType = windows.EVENTLOG_INFORMATION_TYPE
}
return l
}
type eventlogLogger struct {
w *goeventlog.Log
newLogger func(io.Writer) log.Logger
prioritySelector PrioritySelector
bufPool sync.Pool
}
func (l *eventlogLogger) Log(keyvals ...interface{}) error {
priority := l.prioritySelector(keyvals...)
lb, err := l.getLoggerBuf()
msg, err := windows.UTF16PtrFromString(string(p))
if err != nil {
return err
}
defer l.putLoggerBuf(lb)
if err := lb.logger.Log(keyvals...); err != nil {
return err
}
// golang.org/x/sys/windows/svc/eventlog does not provide func which allows to send more than one string.
// See: https://github.com/golang/go/issues/59780
msg, err := syscall.UTF16PtrFromString(lb.buf.String())
if err != nil {
return fmt.Errorf("error convert string to UTF-16: %w", err)
return 0, fmt.Errorf("error convert string to UTF-16: %w", err)
}
ss := []*uint16{msg, nil, nil, nil, nil, nil, nil, nil, nil}
return windows.ReportEvent(l.w.Handle, uint16(priority.etype), 0, neLogOemCode, 0, 9, 0, &ss[0], nil)
}
type loggerBuf struct {
buf *bytes.Buffer
logger log.Logger
}
func (l *eventlogLogger) getLoggerBuf() (*loggerBuf, error) {
lb, ok := l.bufPool.Get().(*loggerBuf)
if !ok {
return nil, errors.New("failed to get loggerBuf from pool")
}
if lb.buf == nil {
lb.buf = &bytes.Buffer{}
lb.logger = l.newLogger(lb.buf)
} else {
lb.buf.Reset()
}
return lb, nil
}
func (l *eventlogLogger) putLoggerBuf(lb *loggerBuf) {
l.bufPool.Put(lb)
}
// PrioritySelector inspects the list of keyvals and selects an eventlog priority.
type PrioritySelector func(keyvals ...interface{}) Priority
// defaultPrioritySelector convert a kit/log level into a Windows Eventlog level.
func defaultPrioritySelector(keyvals ...interface{}) Priority {
l := len(keyvals)
eType := windows.EVENTLOG_SUCCESS
for i := 0; i < l; i += 2 {
if keyvals[i] == level.Key() {
var val interface{}
if i+1 < l {
val = keyvals[i+1]
}
if v, ok := val.(level.Value); ok {
switch v {
case level.ErrorValue():
eType = windows.EVENTLOG_ERROR_TYPE
case level.WarnValue():
eType = windows.EVENTLOG_WARNING_TYPE
case level.InfoValue():
eType = windows.EVENTLOG_INFORMATION_TYPE
}
}
}
}
return Priority{etype: eType}
return len(p), windows.ReportEvent(w.handle, eType, 0, neLogOemCode, 0, 9, 0, &ss[0], nil)
}