@@ -144,6 +144,103 @@ func (s *redaction) processResourceLog(ctx context.Context, rl plog.ResourceLogs
144
144
for k := 0 ; k < ils .LogRecords ().Len (); k ++ {
145
145
log := ils .LogRecords ().At (k )
146
146
s .processAttrs (ctx , log .Attributes ())
147
+ s .processLogBody (ctx , log .Body (), log .Attributes ())
148
+ }
149
+ }
150
+ }
151
+
152
+ func (s * redaction ) processLogBody (ctx context.Context , body pcommon.Value , attributes pcommon.Map ) {
153
+ var redactedKeys , maskedKeys , allowedKeys , ignoredKeys []string
154
+
155
+ switch body .Type () {
156
+ case pcommon .ValueTypeMap :
157
+ var redactedBodyKeys []string
158
+ body .Map ().Range (func (k string , v pcommon.Value ) bool {
159
+ if s .shouldIgnoreKey (k ) {
160
+ ignoredKeys = append (ignoredKeys , k )
161
+ return true
162
+ }
163
+ if s .shouldRedactKey (k ) {
164
+ redactedBodyKeys = append (redactedBodyKeys , k )
165
+ return true
166
+ }
167
+ if s .shouldMaskKey (k ) {
168
+ maskedKeys = append (maskedKeys , k )
169
+ v .SetStr (s .maskValue (v .Str (), regexp .MustCompile (".*" )))
170
+ return true
171
+ }
172
+ s .redactLogBodyRecursive (ctx , k , v , & redactedKeys , & maskedKeys , & allowedKeys , & ignoredKeys )
173
+ return true
174
+ })
175
+ for _ , k := range redactedBodyKeys {
176
+ body .Map ().Remove (k )
177
+ redactedKeys = append (redactedKeys , k )
178
+ }
179
+ case pcommon .ValueTypeSlice :
180
+ for i := 0 ; i < body .Slice ().Len (); i ++ {
181
+ s .redactLogBodyRecursive (ctx , fmt .Sprintf ("[%d]" , i ), body .Slice ().At (i ), & redactedKeys , & maskedKeys , & allowedKeys , & ignoredKeys )
182
+ }
183
+ default :
184
+ strVal := body .AsString ()
185
+ if s .shouldAllowValue (strVal ) {
186
+ allowedKeys = append (allowedKeys , "body" )
187
+ return
188
+ }
189
+ processedValue := s .processStringValue (strVal )
190
+ if strVal != processedValue {
191
+ maskedKeys = append (maskedKeys , "body" )
192
+ body .SetStr (processedValue )
193
+ }
194
+ }
195
+
196
+ s .addMetaAttrs (redactedKeys , attributes , redactionBodyRedactedKeys , redactionBodyRedactedCount )
197
+ s .addMetaAttrs (maskedKeys , attributes , redactionBodyMaskedKeys , redactionBodyMaskedCount )
198
+ s .addMetaAttrs (allowedKeys , attributes , redactionBodyAllowedKeys , redactionBodyAllowedCount )
199
+ s .addMetaAttrs (ignoredKeys , attributes , "" , redactionBodyIgnoredCount )
200
+ }
201
+
202
+ func (s * redaction ) redactLogBodyRecursive (ctx context.Context , key string , value pcommon.Value , redactedKeys , maskedKeys , allowedKeys , ignoredKeys * []string ) {
203
+ switch value .Type () {
204
+ case pcommon .ValueTypeMap :
205
+ var redactedCurrentValueKeys []string
206
+ value .Map ().Range (func (k string , v pcommon.Value ) bool {
207
+ keyWithPath := fmt .Sprintf ("%s.%s" , key , k )
208
+ if s .shouldIgnoreKey (k ) {
209
+ * ignoredKeys = append (* ignoredKeys , keyWithPath )
210
+ return true
211
+ }
212
+ if s .shouldRedactKey (k ) {
213
+ redactedCurrentValueKeys = append (redactedCurrentValueKeys , k )
214
+ return true
215
+ }
216
+ if s .shouldMaskKey (k ) {
217
+ * maskedKeys = append (* maskedKeys , keyWithPath )
218
+ v .SetStr (s .maskValue (v .Str (), regexp .MustCompile (".*" )))
219
+ return true
220
+ }
221
+ s .redactLogBodyRecursive (ctx , keyWithPath , v , redactedKeys , maskedKeys , allowedKeys , ignoredKeys )
222
+ return true
223
+ })
224
+ for _ , k := range redactedCurrentValueKeys {
225
+ value .Map ().Remove (k )
226
+ keyWithPath := fmt .Sprintf ("%s.%s" , key , k )
227
+ * redactedKeys = append (* redactedKeys , keyWithPath )
228
+ }
229
+ case pcommon .ValueTypeSlice :
230
+ for i := 0 ; i < value .Slice ().Len (); i ++ {
231
+ keyWithPath := fmt .Sprintf ("%s.[%d]" , key , i )
232
+ s .redactLogBodyRecursive (ctx , keyWithPath , value .Slice ().At (i ), redactedKeys , maskedKeys , allowedKeys , ignoredKeys )
233
+ }
234
+ default :
235
+ strVal := value .AsString ()
236
+ if s .shouldAllowValue (strVal ) {
237
+ * allowedKeys = append (* allowedKeys , key )
238
+ return
239
+ }
240
+ processedValue := s .processStringValue (strVal )
241
+ if strVal != processedValue {
242
+ * maskedKeys = append (* maskedKeys , key )
243
+ value .SetStr (processedValue )
147
244
}
148
245
}
149
246
}
@@ -192,10 +289,7 @@ func (s *redaction) processResourceMetric(ctx context.Context, rm pmetric.Resour
192
289
// processAttrs redacts the attributes of a resource span or a span
193
290
func (s * redaction ) processAttrs (_ context.Context , attributes pcommon.Map ) {
194
291
// TODO: Use the context for recording metrics
195
- var toDelete []string
196
- var toBlock []string
197
- var allowed []string
198
- var ignoring []string
292
+ var redactedKeys , maskedKeys , allowedKeys , ignoredKeys []string
199
293
200
294
// Identify attributes to redact and mask in the following sequence
201
295
// 1. Make a list of attribute keys to redact
@@ -207,66 +301,41 @@ func (s *redaction) processAttrs(_ context.Context, attributes pcommon.Map) {
207
301
// - Don't mask any values if the whole attribute is slated for deletion
208
302
AttributeLoop:
209
303
for k , value := range attributes .All () {
210
- // don't delete or redact the attribute if it should be ignored
211
- if _ , ignored := s .ignoreList [k ]; ignored {
212
- ignoring = append (ignoring , k )
213
- // Skip to the next attribute
304
+ if s .shouldIgnoreKey (k ) {
305
+ ignoredKeys = append (ignoredKeys , k )
214
306
continue AttributeLoop
215
307
}
216
-
217
- // Make a list of attribute keys to redact
218
- if ! s .config .AllowAllKeys {
219
- if _ , allowed := s .allowList [k ]; ! allowed {
220
- toDelete = append (toDelete , k )
221
- // Skip to the next attribute
222
- continue AttributeLoop
223
- }
308
+ if s .shouldRedactKey (k ) {
309
+ redactedKeys = append (redactedKeys , k )
310
+ continue AttributeLoop
224
311
}
225
-
226
312
strVal := value .Str ()
227
- // Allow any values matching the allowed list regex
228
- for _ , compiledRE := range s .allowRegexList {
229
- if match := compiledRE .MatchString (strVal ); match {
230
- allowed = append (allowed , k )
231
- continue AttributeLoop
232
- }
313
+ if s .shouldAllowValue (strVal ) {
314
+ allowedKeys = append (allowedKeys , k )
315
+ continue AttributeLoop
233
316
}
234
-
235
- // Mask any blocked keys for the other attributes
236
- for _ , compiledRE := range s .blockKeyRegexList {
237
- if match := compiledRE .MatchString (k ); match {
238
- toBlock = append (toBlock , k )
239
- maskedValue := s .maskValue (strVal , regexp .MustCompile (".*" ))
240
- value .SetStr (maskedValue )
241
- continue AttributeLoop
242
- }
317
+ if s .shouldMaskKey (k ) {
318
+ maskedKeys = append (maskedKeys , k )
319
+ maskedValue := s .maskValue (strVal , regexp .MustCompile (".*" ))
320
+ value .SetStr (maskedValue )
321
+ continue AttributeLoop
243
322
}
244
-
245
- // Mask any blocked values for the other attributes
246
- var matched bool
247
- for _ , compiledRE := range s .blockRegexList {
248
- if compiledRE .MatchString (strVal ) {
249
- if ! matched {
250
- matched = true
251
- toBlock = append (toBlock , k )
252
- }
253
-
254
- maskedValue := s .maskValue (strVal , compiledRE )
255
- value .SetStr (maskedValue )
256
- strVal = maskedValue
257
- }
323
+ processedString := s .processStringValue (strVal )
324
+ if processedString != strVal {
325
+ maskedKeys = append (maskedKeys , k )
326
+ value .SetStr (processedString )
258
327
}
259
328
}
260
329
261
330
// Delete the attributes on the redaction list
262
- for _ , k := range toDelete {
331
+ for _ , k := range redactedKeys {
263
332
attributes .Remove (k )
264
333
}
265
334
// Add diagnostic information to the span
266
- s .addMetaAttrs (toDelete , attributes , redactedKeys , redactedKeyCount )
267
- s .addMetaAttrs (toBlock , attributes , maskedValues , maskedValueCount )
268
- s .addMetaAttrs (allowed , attributes , allowedValues , allowedValueCount )
269
- s .addMetaAttrs (ignoring , attributes , "" , ignoredKeyCount )
335
+ s .addMetaAttrs (redactedKeys , attributes , redactionRedactedKeys , redactionRedactedCount )
336
+ s .addMetaAttrs (maskedKeys , attributes , redactionMaskedKeys , redactionMaskedCount )
337
+ s .addMetaAttrs (allowedKeys , attributes , redactionAllowedKeys , redactionAllowedCount )
338
+ s .addMetaAttrs (ignoredKeys , attributes , "" , redactionIgnoredCount )
270
339
}
271
340
272
341
//nolint:gosec
@@ -314,16 +383,70 @@ func (s *redaction) addMetaAttrs(redactedAttrs []string, attributes pcommon.Map,
314
383
}
315
384
}
316
385
386
+ func (s * redaction ) processStringValue (strVal string ) string {
387
+ // Mask any blocked values for the other attributes
388
+ for _ , compiledRE := range s .blockRegexList {
389
+ match := compiledRE .MatchString (strVal )
390
+ if match {
391
+ strVal = s .maskValue (strVal , compiledRE )
392
+ }
393
+ }
394
+ return strVal
395
+ }
396
+
397
+ func (s * redaction ) shouldMaskKey (k string ) bool {
398
+ // Mask any blocked keys for the other attributes
399
+ for _ , compiledRE := range s .blockKeyRegexList {
400
+ if match := compiledRE .MatchString (k ); match {
401
+ return true
402
+ }
403
+ }
404
+ return false
405
+ }
406
+
407
+ func (s * redaction ) shouldAllowValue (strVal string ) bool {
408
+ // Allow any values matching the allowed list regex
409
+ for _ , compiledRE := range s .allowRegexList {
410
+ if match := compiledRE .MatchString (strVal ); match {
411
+ return true
412
+ }
413
+ }
414
+ return false
415
+ }
416
+
417
+ func (s * redaction ) shouldIgnoreKey (k string ) bool {
418
+ if _ , ignored := s .ignoreList [k ]; ignored {
419
+ return true
420
+ }
421
+ return false
422
+ }
423
+
424
+ func (s * redaction ) shouldRedactKey (k string ) bool {
425
+ if ! s .config .AllowAllKeys {
426
+ if _ , found := s .allowList [k ]; ! found {
427
+ return true
428
+ }
429
+ }
430
+ return false
431
+ }
432
+
317
433
const (
318
- debug = "debug"
319
- info = "info"
320
- redactedKeys = "redaction.redacted.keys"
321
- redactedKeyCount = "redaction.redacted.count"
322
- maskedValues = "redaction.masked.keys"
323
- maskedValueCount = "redaction.masked.count"
324
- allowedValues = "redaction.allowed.keys"
325
- allowedValueCount = "redaction.allowed.count"
326
- ignoredKeyCount = "redaction.ignored.count"
434
+ debug = "debug"
435
+ info = "info"
436
+ redactionRedactedKeys = "redaction.redacted.keys"
437
+ redactionRedactedCount = "redaction.redacted.count"
438
+ redactionMaskedKeys = "redaction.masked.keys"
439
+ redactionMaskedCount = "redaction.masked.count"
440
+ redactionAllowedKeys = "redaction.allowed.keys"
441
+ redactionAllowedCount = "redaction.allowed.count"
442
+ redactionIgnoredCount = "redaction.ignored.count"
443
+ redactionBodyRedactedKeys = "redaction.body.redacted.keys"
444
+ redactionBodyRedactedCount = "redaction.body.redacted.count"
445
+ redactionBodyMaskedKeys = "redaction.body.masked.keys"
446
+ redactionBodyMaskedCount = "redaction.body.masked.count"
447
+ redactionBodyAllowedKeys = "redaction.body.allowed.keys"
448
+ redactionBodyAllowedCount = "redaction.body.allowed.count"
449
+ redactionBodyIgnoredCount = "redaction.body.ignored.count"
327
450
)
328
451
329
452
// makeAllowList sets up a lookup table of allowed span attribute keys
@@ -338,7 +461,7 @@ func makeAllowList(c *Config) map[string]string {
338
461
// span attributes (e.g. `notes`, `description`), then it will those
339
462
// attribute keys in `redaction.masked.keys` and set the
340
463
// `redaction.masked.count` to 2
341
- redactionKeys := []string {redactedKeys , redactedKeyCount , maskedValues , maskedValueCount , ignoredKeyCount }
464
+ redactionKeys := []string {redactionRedactedKeys , redactionRedactedCount , redactionMaskedKeys , redactionMaskedCount , redactionIgnoredCount }
342
465
// allowList consists of the keys explicitly allowed by the configuration
343
466
// as well as of the new span attributes that the processor creates to
344
467
// summarize its changes
0 commit comments