@@ -144,6 +144,102 @@ 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 .Str ()
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
+ value .SetStr (s .maskValue (value .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
+ s .redactLogBodyRecursive (ctx , fmt .Sprintf ("%s.[%d]" , key , i ), value .Slice ().At (i ), redactedKeys , maskedKeys , allowedKeys , ignoredKeys )
232
+ }
233
+ default :
234
+ strVal := value .Str ()
235
+ if s .shouldAllowValue (strVal ) {
236
+ * allowedKeys = append (* allowedKeys , key )
237
+ return
238
+ }
239
+ processedValue := s .processStringValue (strVal )
240
+ if strVal != processedValue {
241
+ * maskedKeys = append (* maskedKeys , key )
242
+ value .SetStr (processedValue )
147
243
}
148
244
}
149
245
}
@@ -192,10 +288,7 @@ func (s *redaction) processResourceMetric(ctx context.Context, rm pmetric.Resour
192
288
// processAttrs redacts the attributes of a resource span or a span
193
289
func (s * redaction ) processAttrs (_ context.Context , attributes pcommon.Map ) {
194
290
// TODO: Use the context for recording metrics
195
- var toDelete []string
196
- var toBlock []string
197
- var allowed []string
198
- var ignoring []string
291
+ var redactedKeys , maskedKeys , allowedKeys , ignoredKeys []string
199
292
200
293
// Identify attributes to redact and mask in the following sequence
201
294
// 1. Make a list of attribute keys to redact
@@ -206,67 +299,42 @@ func (s *redaction) processAttrs(_ context.Context, attributes pcommon.Map) {
206
299
// - Only range through all attributes once
207
300
// - Don't mask any values if the whole attribute is slated for deletion
208
301
attributes .Range (func (k string , value pcommon.Value ) bool {
209
- // don't delete or redact the attribute if it should be ignored
210
- if _ , ignored := s .ignoreList [k ]; ignored {
211
- ignoring = append (ignoring , k )
212
- // Skip to the next attribute
302
+ if s .shouldIgnoreKey (k ) {
303
+ ignoredKeys = append (ignoredKeys , k )
213
304
return true
214
305
}
215
-
216
- // Make a list of attribute keys to redact
217
- if ! s .config .AllowAllKeys {
218
- if _ , allowed := s .allowList [k ]; ! allowed {
219
- toDelete = append (toDelete , k )
220
- // Skip to the next attribute
221
- return true
222
- }
306
+ if s .shouldRedactKey (k ) {
307
+ redactedKeys = append (redactedKeys , k )
308
+ return true
223
309
}
224
-
225
310
strVal := value .Str ()
226
- // Allow any values matching the allowed list regex
227
- for _ , compiledRE := range s .allowRegexList {
228
- if match := compiledRE .MatchString (strVal ); match {
229
- allowed = append (allowed , k )
230
- return true
231
- }
311
+ if s .shouldAllowValue (strVal ) {
312
+ allowedKeys = append (allowedKeys , k )
313
+ return true
232
314
}
233
-
234
- // Mask any blocked keys for the other attributes
235
- for _ , compiledRE := range s .blockKeyRegexList {
236
- if match := compiledRE .MatchString (k ); match {
237
- toBlock = append (toBlock , k )
238
- maskedValue := s .maskValue (strVal , regexp .MustCompile (".*" ))
239
- value .SetStr (maskedValue )
240
- return true
241
- }
315
+ if s .shouldMaskKey (k ) {
316
+ maskedKeys = append (maskedKeys , k )
317
+ maskedValue := s .maskValue (strVal , regexp .MustCompile (".*" ))
318
+ value .SetStr (maskedValue )
319
+ return true
242
320
}
243
-
244
- // Mask any blocked values for the other attributes
245
- var matched bool
246
- for _ , compiledRE := range s .blockRegexList {
247
- if compiledRE .MatchString (strVal ) {
248
- if ! matched {
249
- matched = true
250
- toBlock = append (toBlock , k )
251
- }
252
-
253
- maskedValue := s .maskValue (strVal , compiledRE )
254
- value .SetStr (maskedValue )
255
- strVal = maskedValue
256
- }
321
+ processedString := s .processStringValue (strVal )
322
+ if processedString != strVal {
323
+ maskedKeys = append (maskedKeys , k )
324
+ value .SetStr (processedString )
257
325
}
258
326
return true
259
327
})
260
328
261
329
// Delete the attributes on the redaction list
262
- for _ , k := range toDelete {
330
+ for _ , k := range redactedKeys {
263
331
attributes .Remove (k )
264
332
}
265
333
// 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 )
334
+ s .addMetaAttrs (redactedKeys , attributes , redactionRedactedKeys , redactionRedactedCount )
335
+ s .addMetaAttrs (maskedKeys , attributes , redactionMaskedKeys , redactionMaskedCount )
336
+ s .addMetaAttrs (allowedKeys , attributes , redactionAllowedKeys , redactionAllowedCount )
337
+ s .addMetaAttrs (ignoredKeys , attributes , "" , redactionIgnoredCount )
270
338
}
271
339
272
340
//nolint:gosec
@@ -314,16 +382,70 @@ func (s *redaction) addMetaAttrs(redactedAttrs []string, attributes pcommon.Map,
314
382
}
315
383
}
316
384
385
+ func (s * redaction ) processStringValue (strVal string ) string {
386
+ // Mask any blocked values for the other attributes
387
+ for _ , compiledRE := range s .blockRegexList {
388
+ match := compiledRE .MatchString (strVal )
389
+ if match {
390
+ strVal = s .maskValue (strVal , compiledRE )
391
+ }
392
+ }
393
+ return strVal
394
+ }
395
+
396
+ func (s * redaction ) shouldMaskKey (k string ) bool {
397
+ // Mask any blocked keys for the other attributes
398
+ for _ , compiledRE := range s .blockKeyRegexList {
399
+ if match := compiledRE .MatchString (k ); match {
400
+ return true
401
+ }
402
+ }
403
+ return false
404
+ }
405
+
406
+ func (s * redaction ) shouldAllowValue (strVal string ) bool {
407
+ // Allow any values matching the allowed list regex
408
+ for _ , compiledRE := range s .allowRegexList {
409
+ if match := compiledRE .MatchString (strVal ); match {
410
+ return true
411
+ }
412
+ }
413
+ return false
414
+ }
415
+
416
+ func (s * redaction ) shouldIgnoreKey (k string ) bool {
417
+ if _ , ignored := s .ignoreList [k ]; ignored {
418
+ return true
419
+ }
420
+ return false
421
+ }
422
+
423
+ func (s * redaction ) shouldRedactKey (k string ) bool {
424
+ if ! s .config .AllowAllKeys {
425
+ if _ , found := s .allowList [k ]; ! found {
426
+ return true
427
+ }
428
+ }
429
+ return false
430
+ }
431
+
317
432
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"
433
+ debug = "debug"
434
+ info = "info"
435
+ redactionRedactedKeys = "redaction.redacted.keys"
436
+ redactionRedactedCount = "redaction.redacted.count"
437
+ redactionMaskedKeys = "redaction.masked.keys"
438
+ redactionMaskedCount = "redaction.masked.count"
439
+ redactionAllowedKeys = "redaction.allowed.keys"
440
+ redactionAllowedCount = "redaction.allowed.count"
441
+ redactionIgnoredCount = "redaction.ignored.count"
442
+ redactionBodyRedactedKeys = "redaction.body.redacted.keys"
443
+ redactionBodyRedactedCount = "redaction.body.redacted.count"
444
+ redactionBodyMaskedKeys = "redaction.body.masked.keys"
445
+ redactionBodyMaskedCount = "redaction.body.masked.count"
446
+ redactionBodyAllowedKeys = "redaction.body.allowed.keys"
447
+ redactionBodyAllowedCount = "redaction.body.allowed.count"
448
+ redactionBodyIgnoredCount = "redaction.body.ignored.count"
327
449
)
328
450
329
451
// makeAllowList sets up a lookup table of allowed span attribute keys
@@ -338,7 +460,7 @@ func makeAllowList(c *Config) map[string]string {
338
460
// span attributes (e.g. `notes`, `description`), then it will those
339
461
// attribute keys in `redaction.masked.keys` and set the
340
462
// `redaction.masked.count` to 2
341
- redactionKeys := []string {redactedKeys , redactedKeyCount , maskedValues , maskedValueCount , ignoredKeyCount }
463
+ redactionKeys := []string {redactionRedactedKeys , redactionRedactedCount , redactionMaskedKeys , redactionMaskedCount , redactionIgnoredCount }
342
464
// allowList consists of the keys explicitly allowed by the configuration
343
465
// as well as of the new span attributes that the processor creates to
344
466
// summarize its changes
0 commit comments