05cc62aab3
RedactionEnricher now projects each property into a mutable view the ILogRedactor
can edit: scalars stay as their CLR value, while StructureValue/SequenceValue/
DictionaryValue become nested IDictionary<string,object?>/IList<object?> the
redactor descends into recursively. A field nested inside a destructured {@Object}
can now be masked or removed — closing the gap documented as a limitation.
- Project/Rebuild round-trip preserves StructureValue.TypeTag and original
dictionary keys; redactor-synthesised plain dicts/lists are rebuilt too.
- Untouched properties are not reallocated: structural ValueEquals skips write-back
unless a property actually changed. Scalar fast path and no-redactor/no-property
short-circuits retained.
- +5 nested-reach tests (mask/remove a field, sequence element, dictionary value,
two-levels-deep); the old 'cannot reach' limitation test replaced. Serilog 34, 0 warnings.
- ILogRedactor XML doc + library README updated to document the recursive reach.
32 lines
2.0 KiB
C#
32 lines
2.0 KiB
C#
namespace ZB.MOM.WW.Telemetry.Serilog;
|
|
|
|
/// <summary>
|
|
/// Seam for project-specific log-event redaction. The shared library applies this via
|
|
/// <see cref="RedactionEnricher"/>; each project provides its own implementation that knows which
|
|
/// fields (by property name) or which command payloads must not leave the process in log events.
|
|
/// If no <see cref="ILogRedactor"/> is registered in DI, <see cref="RedactionEnricher"/> is a no-op.
|
|
/// </summary>
|
|
public interface ILogRedactor
|
|
{
|
|
/// <summary>
|
|
/// Inspects and mutates the supplied log-event <paramref name="properties"/> in place — remove
|
|
/// or replace any sensitive values. Called on every log event before it reaches any sink.
|
|
/// Both removing a key (the property is dropped from the event) and replacing its value are
|
|
/// honoured by <see cref="RedactionEnricher"/>.
|
|
/// <para>
|
|
/// <b>Reach — top-level and nested.</b> A scalar property (e.g. <c>{apiKey}</c>) appears as its
|
|
/// unwrapped CLR value, which you can read and replace directly. A <b>destructured</b> property is
|
|
/// projected into a mutable view you can descend into: a <c>{@Object}</c> arrives as an
|
|
/// <c>IDictionary<string, object?></c> of its fields, a logged collection as an
|
|
/// <c>IList<object?></c>, and a logged dictionary as an <c>IDictionary<string, object?></c>
|
|
/// keyed by the string form of each key — all recursively. You can therefore mask or remove a field
|
|
/// nested inside a destructured object, for example:
|
|
/// <code>if (properties["command"] is IDictionary<string, object?> command) command["apiKey"] = "***";</code>
|
|
/// The structure's type tag and a dictionary's original keys are preserved when the event is
|
|
/// rebuilt, and properties you do not touch are left intact.
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="properties">The mutable property dictionary for the current log event.</param>
|
|
void Redact(IDictionary<string, object?> properties);
|
|
}
|