telemetry-safe 0.2.0

Compile-time safe telemetry formatting facade crate
Documentation

telemetry-safe

telemetry-safe is the main facade crate for defining which values are allowed to flow into telemetry.

It re-exports:

  • ToTelemetry
  • telemetry(&value)
  • telemetry_debug(&value)
  • #[derive(ToTelemetry)]

Use this crate when you want compile-time enforcement that only explicitly approved representations can be emitted through logging, tracing, metrics, or other observability paths.

Why this crate exists

Plain tracing, logging, or metrics code makes it easy to accidentally send PII through Debug, Display, or default instrumentation behavior.

telemetry-safe takes an opt-in, type-driven approach instead:

  • values must implement ToTelemetry before they can be emitted
  • raw String / &str are not blanket-approved
  • unsafe paths fail at compile time rather than depending on review discipline

Basic example

use telemetry_safe::{telemetry, ToTelemetry};
use std::fmt::{self, Formatter};

#[derive(ToTelemetry)]
struct UserId(u64);

struct OutcomeLabel(&'static str);

impl ToTelemetry for OutcomeLabel {
    fn fmt_telemetry(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_str(self.0)
    }
}

#[derive(ToTelemetry)]
struct LoginAttempt {
    user_id: UserId,
    outcome: OutcomeLabel,
    #[telemetry(skip)]
    email: String,
}

let attempt = LoginAttempt {
    user_id: UserId(42),
    outcome: OutcomeLabel("accepted"),
    email: "user@example.com".to_owned(),
};

assert_eq!(
    telemetry(&attempt).to_string(),
    "LoginAttempt { user_id: UserId(42), outcome: accepted }",
);

Related crates

  • telemetry-safe-core
    • the minimal backend-agnostic core
  • telemetry-safe-tracing
    • tracing integration, including #[safe_instrument]

For the full project overview and workspace-level documentation, see the repository README at https://github.com/milabo/telemetry-safe-rs.