89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package broker
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
|
|
"github.com/mochi-mqtt/server/v2/packets"
|
|
)
|
|
|
|
type redactHandler struct {
|
|
inner slog.Handler
|
|
}
|
|
|
|
func newRedactHandler(inner slog.Handler) slog.Handler {
|
|
if inner == nil {
|
|
inner = slog.Default().Handler()
|
|
}
|
|
return &redactHandler{inner: inner}
|
|
}
|
|
|
|
func (h *redactHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
|
return h.inner.Enabled(ctx, level)
|
|
}
|
|
|
|
func (h *redactHandler) Handle(ctx context.Context, r slog.Record) error {
|
|
rec := slog.NewRecord(r.Time, r.Level, r.Message, r.PC)
|
|
r.Attrs(func(a slog.Attr) bool {
|
|
rec.AddAttrs(redactSlogAttr(a))
|
|
return true
|
|
})
|
|
return h.inner.Handle(ctx, rec)
|
|
}
|
|
|
|
func (h *redactHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
out := make([]slog.Attr, len(attrs))
|
|
for i, a := range attrs {
|
|
out[i] = redactSlogAttr(a)
|
|
}
|
|
return &redactHandler{inner: h.inner.WithAttrs(out)}
|
|
}
|
|
|
|
func (h *redactHandler) WithGroup(name string) slog.Handler {
|
|
return &redactHandler{inner: h.inner.WithGroup(name)}
|
|
}
|
|
|
|
func redactSlogAttr(a slog.Attr) slog.Attr {
|
|
a.Value = a.Value.Resolve()
|
|
switch v := a.Value.Any().(type) {
|
|
case packets.Packet:
|
|
return slog.Any(a.Key, summarizePacket(v))
|
|
case *packets.Packet:
|
|
if v == nil {
|
|
return a
|
|
}
|
|
return slog.Any(a.Key, summarizePacket(*v))
|
|
}
|
|
if a.Value.Kind() == slog.KindGroup {
|
|
group := a.Value.Group()
|
|
out := make([]slog.Attr, len(group))
|
|
for i, g := range group {
|
|
out[i] = redactSlogAttr(g)
|
|
}
|
|
return slog.Attr{Key: a.Key, Value: slog.GroupValue(out...)}
|
|
}
|
|
return a
|
|
}
|
|
|
|
type mqttPacketLog struct {
|
|
Type string `json:"type"`
|
|
QoS byte `json:"qos"`
|
|
PacketID uint16 `json:"packet_id"`
|
|
Topic string `json:"topic,omitempty"`
|
|
PayloadLen int `json:"payload_len"`
|
|
}
|
|
|
|
func summarizePacket(pk packets.Packet) mqttPacketLog {
|
|
name := packets.PacketNames[pk.FixedHeader.Type]
|
|
if name == "" {
|
|
name = "unknown"
|
|
}
|
|
return mqttPacketLog{
|
|
Type: name,
|
|
QoS: pk.FixedHeader.Qos,
|
|
PacketID: pk.PacketID,
|
|
Topic: pk.TopicName,
|
|
PayloadLen: len(pk.Payload),
|
|
}
|
|
}
|