1
0
Fork 0
telegraf/logger/structured_logger.go
Daniel Baumann 4978089aab
Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-24 07:26:29 +02:00

98 lines
2.1 KiB
Go

package logger
import (
"context"
"fmt"
"io"
"log"
"log/slog"
"os"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/rotate"
)
type structuredLogger struct {
handler slog.Handler
output io.Writer
errlog *log.Logger
}
func (l *structuredLogger) Close() error {
// Close the writer if possible and avoid closing stderr
if l.output == os.Stderr {
return nil
}
if closer, ok := l.output.(io.Closer); ok {
return closer.Close()
}
return nil
}
func (l *structuredLogger) Print(level telegraf.LogLevel, ts time.Time, _ string, attr map[string]interface{}, args ...interface{}) {
record := slog.Record{
Time: ts,
Message: fmt.Sprint(args...),
Level: slog.Level(level),
}
for k, v := range attr {
record.Add(k, v)
}
if err := l.handler.Handle(context.Background(), record); err != nil {
l.errlog.Printf("E! Writing log message failed: %v", err)
}
}
var defaultReplaceAttr = func(_ []string, attr slog.Attr) slog.Attr {
// Translate the Telegraf log-levels to strings
if attr.Key == slog.LevelKey {
if level, ok := attr.Value.Any().(slog.Level); ok {
attr.Value = slog.StringValue(telegraf.LogLevel(level).String())
}
}
return attr
}
var defaultStructuredHandlerOptions = &slog.HandlerOptions{
Level: slog.Level(-99),
ReplaceAttr: defaultReplaceAttr,
}
func init() {
add("structured", func(cfg *Config) (sink, error) {
var writer io.Writer = os.Stderr
if cfg.Logfile != "" {
w, err := rotate.NewFileWriter(
cfg.Logfile,
cfg.RotationInterval,
cfg.RotationMaxSize,
cfg.RotationMaxArchives,
)
if err != nil {
return nil, err
}
writer = w
}
structuredHandlerOptions := defaultStructuredHandlerOptions
if cfg.StructuredLogMessageKey != "" {
structuredHandlerOptions.ReplaceAttr = func(groups []string, attr slog.Attr) slog.Attr {
if attr.Key == slog.MessageKey {
attr.Key = cfg.StructuredLogMessageKey
}
return defaultReplaceAttr(groups, attr)
}
}
return &structuredLogger{
handler: slog.NewJSONHandler(writer, structuredHandlerOptions),
output: writer,
errlog: log.New(os.Stderr, "", 0),
}, nil
})
}