20
20
unknownValue = slog .StringValue ("UNKNOWN" )
21
21
)
22
22
23
+ // KeyFormatter functions provide a way to alter a [slog.Attr] key depending
24
+ // on the to be logged field of a [protoreflect.Message].
25
+ type KeyFormatter func (key string , fd protoreflect.FieldDescriptor , value protoreflect.Value ) string
26
+
23
27
// Option functions customize generation of a [slog.Value] from a
24
28
// [proto.Message] beyond the default behavior.
25
29
type Option func (o * options )
@@ -61,6 +65,12 @@ func WithAnyResolver(resolver protoregistry.MessageTypeResolver) Option {
61
65
return func (o * options ) { o .AnyResolver = resolver }
62
66
}
63
67
68
+ // WithKeyFormatter is used to alter a [slog.Attr] key depending
69
+ // on the to be logged field of a [protoreflect.Message].
70
+ func WithKeyFormatter (formatter KeyFormatter ) Option {
71
+ return func (o * options ) { o .KeyFormatter = formatter }
72
+ }
73
+
64
74
type options struct {
65
75
// DisableRedaction indicates that fields annotated with the debug_redact
66
76
// option should not be redacted from the slog.Value. When false, redacted
@@ -84,6 +94,10 @@ type options struct {
84
94
// protoregistry.GlobalTypes is used. If the type cannot be found in the
85
95
// resolver or if unmarshaling fails, only an "@type" field is emitted.
86
96
AnyResolver protoregistry.MessageTypeResolver
97
+
98
+ // KeyFormatter is used to alter a [slog.Attr] key depending
99
+ // on the to be logged field of a [protoreflect.Message].
100
+ KeyFormatter KeyFormatter
87
101
}
88
102
89
103
func newOptions (opts []Option ) (o options ) {
@@ -102,6 +116,9 @@ func mergeOptions(base, other options) (o options) {
102
116
if other .AnyResolver != nil {
103
117
o .AnyResolver = other .AnyResolver
104
118
}
119
+ if other .KeyFormatter != nil {
120
+ o .KeyFormatter = other .KeyFormatter
121
+ }
105
122
return o
106
123
}
107
124
@@ -139,7 +156,11 @@ func (o options) MessageValue(msg protoreflect.Message) slog.Value {
139
156
default :
140
157
val = o .singularValue (field , msg .Get (field ))
141
158
}
142
- attrs = append (attrs , slog.Attr {Key : string (field .Name ()), Value : val })
159
+ key := string (field .Name ())
160
+ if o .KeyFormatter != nil {
161
+ key = o .KeyFormatter (key , field , msg .Get (field ))
162
+ }
163
+ attrs = append (attrs , slog.Attr {Key : key , Value : val })
143
164
}
144
165
return slog .GroupValue (attrs ... )
145
166
}
0 commit comments