tracing-sanitize 0.1.1

A tracing layer that automatically sanitizes PII from log output
Documentation

tracing-sanitize

CI codecov Crates.io docs.rs

A tracing layer that automatically strips PII from log output using sanitize-pii.

The problem

You add structured logging to your app. Somewhere, an email, IP address, or API key ends up in your logs. Now you have a GDPR issue, a security incident, or both. tracing-sanitize catches it automatically.

Usage

Add to your Cargo.toml:

[dependencies]
tracing-sanitize = "0.1"
tracing = "0.1"
tracing-subscriber = "0.3"

Basic setup (all PII detectors)

use tracing_subscriber::prelude::*;
use tracing_sanitize::SanitizeLayer;

tracing_subscriber::registry()
    .with(SanitizeLayer::default())
    .with(tracing_subscriber::fmt::layer())
    .init();

// PII in span and event fields is automatically masked
tracing::info!(email = "joe@gmail.com", "user logged in");
// Output: email=j***@***.com "user logged in"

Custom configuration (pick detectors)

use tracing_subscriber::prelude::*;
use tracing_sanitize::SanitizeLayer;
use sanitize_pii::Sanitizer;

let sanitizer = Sanitizer::builder()
    .email()
    .credit_card()
    .build();

tracing_subscriber::registry()
    .with(SanitizeLayer::new(sanitizer))
    .with(tracing_subscriber::fmt::layer())
    .init();

What gets sanitized

All built-in detectors from sanitize-pii are supported:

Type Example Masked
Email joe@gmail.com j***@***.com
Credit card 4111 1111 1111 1111 4111-****-****-1111
Phone +33 612 345 678 +** *** *** 78
IPv4 192.168.1.42 192.***.***.42
IPv6 2001:0db8:... ***:***:***:***
API keys sk_live_abc123... sk_l****...

Custom patterns are also supported via Sanitizer::builder().custom(name, regex).

How it works

tracing-sanitize implements a tracing_subscriber::Layer that intercepts span and event fields. String and debug fields are passed through sanitize-pii before reaching downstream layers (like fmt). Numeric and boolean fields pass through untouched.

License

MIT