feat(logger): add buffering exporter with TLS support for OTLP logs
Add buffering exporter to queue OTLP logs until tracing is configured. Support TLS configuration for OpenTelemetry log export with client certificate authentication. Improve logfmt formatting and tracing setup.
This commit is contained in:
@@ -16,23 +16,28 @@ type logfmt struct {
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// createTextHandlerOptions creates the common slog.HandlerOptions used by all logfmt handlers
|
||||
func createTextHandlerOptions() *slog.HandlerOptions {
|
||||
return &slog.HandlerOptions{
|
||||
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||
if a.Key == slog.TimeKey && len(groups) == 0 {
|
||||
return slog.Attr{}
|
||||
}
|
||||
if a.Key == slog.LevelKey && len(groups) == 0 {
|
||||
return slog.Attr{}
|
||||
}
|
||||
return a
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newLogFmtHandler(next slog.Handler) slog.Handler {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
h := &logfmt{
|
||||
buf: buf,
|
||||
next: next,
|
||||
txt: slog.NewTextHandler(buf, &slog.HandlerOptions{
|
||||
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||
if a.Key == slog.TimeKey && len(groups) == 0 {
|
||||
return slog.Attr{}
|
||||
}
|
||||
if a.Key == slog.LevelKey && len(groups) == 0 {
|
||||
return slog.Attr{}
|
||||
}
|
||||
return a
|
||||
},
|
||||
}),
|
||||
txt: slog.NewTextHandler(buf, createTextHandlerOptions()),
|
||||
}
|
||||
|
||||
return h
|
||||
@@ -43,10 +48,11 @@ func (h *logfmt) Enabled(ctx context.Context, lvl slog.Level) bool {
|
||||
}
|
||||
|
||||
func (h *logfmt) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
return &logfmt{
|
||||
buf: bytes.NewBuffer([]byte{}),
|
||||
buf: buf,
|
||||
next: h.next.WithAttrs(slices.Clone(attrs)),
|
||||
txt: h.txt.WithAttrs(slices.Clone(attrs)),
|
||||
txt: slog.NewTextHandler(buf, createTextHandlerOptions()).WithAttrs(slices.Clone(attrs)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,10 +60,11 @@ func (h *logfmt) WithGroup(g string) slog.Handler {
|
||||
if g == "" {
|
||||
return h
|
||||
}
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
return &logfmt{
|
||||
buf: bytes.NewBuffer([]byte{}),
|
||||
buf: buf,
|
||||
next: h.next.WithGroup(g),
|
||||
txt: h.txt.WithGroup(g),
|
||||
txt: slog.NewTextHandler(buf, createTextHandlerOptions()).WithGroup(g),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,10 +76,22 @@ func (h *logfmt) Handle(ctx context.Context, r slog.Record) error {
|
||||
panic("buffer wasn't empty")
|
||||
}
|
||||
|
||||
h.txt.Handle(ctx, r)
|
||||
r.Message = h.buf.String()
|
||||
r.Message = strings.TrimSuffix(r.Message, "\n")
|
||||
// Format using text handler to get the formatted message
|
||||
err := h.txt.Handle(ctx, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formattedMessage := h.buf.String()
|
||||
formattedMessage = strings.TrimSuffix(formattedMessage, "\n")
|
||||
h.buf.Reset()
|
||||
|
||||
return h.next.Handle(ctx, r)
|
||||
// Create a new record with the formatted message
|
||||
newRecord := slog.NewRecord(r.Time, r.Level, formattedMessage, r.PC)
|
||||
r.Attrs(func(a slog.Attr) bool {
|
||||
newRecord.AddAttrs(a)
|
||||
return true
|
||||
})
|
||||
|
||||
return h.next.Handle(ctx, newRecord)
|
||||
}
|
||||
|
Reference in New Issue
Block a user