Skip to main content
The bb_ai_sdk.logging module scrubs secrets from log lines and stamps trace and span IDs on each record. The same redaction engine covers OpenTelemetry span attributes when you call bb_ai_sdk.logging.init() at startup. Tracing setup lives on the Observability page. This page covers log formats, redaction patterns, coverage, and how logging cooperates with configure_observability().

What the SDK provides

After logging.basicConfig (or dictConfig) and one call to bb_ai_sdk.logging.init(): Built-in patterns cover common secrets: API keys, tokens, passwords, secrets, and Langfuse credentials. Replacements use typed tags such as [REDACTED:api_key] so audits show what was redacted.
Deep reference (architecture, performance, troubleshooting) lives in the bb-ai-sdk repository under docs/logging/ (OVERVIEW.md, LOGGING_GUIDE.md).

Startup

Use the same order as What you call at startup on the Observability page:
  1. logging.basicConfig (or dictConfig) with a format preset that includes %(trace_id)s and %(span_id)s
  2. bb_ai_sdk.logging.init() — once, before serving traffic
  3. configure_observability(...) — tracing and instrumentors
Use logging.getLogger(__name__) everywhere. This module does not export a shared logger object.
Call bb_ai_sdk.logging.init() even when you only care about span redaction. Without it, observability falls back to built-in default patterns only—BB_AI_SDK_REDACTION_PATTERNS* env vars and custom patterns from init(redaction_patterns=...) are not applied to spans.

init() parameters

init() is idempotent—the first call wins. To reconfigure, call disable_redaction() first.

Log format presets

Import ready-made format strings from bb_ai_sdk.logging and pass them to logging.basicConfig or dictConfig. Every preset includes %(trace_id)s and %(span_id)s—those fields are populated after you call init(). LOG_FORMATS maps short names to the same strings: standard, compact, minimal, message_trace. When no OpenTelemetry span is active, trace_id and span_id appear as "-". That is expected for startup logs before the first request span.

Operator-driven patterns (no redeploy)

Add patterns via environment variables (merged with built-ins when init() runs):
Or at runtime (applies to logs and spans immediately):

What gets redacted

Span attributes also redact by key name (for example api_key, token, password) even when the value would pass content patterns unchanged.

Optional: audit trail on records

Pass record_redactions=True on the first init() call:
Each redacted record gets metadata listing which pattern names fired—useful for security reviews.

Troubleshooting

Trace IDs always show "-" in logs — No active OpenTelemetry span when the line was emitted (startup noise), or configure_observability() is not initialized. IDs populate inside instrumented request or agent spans. Secrets visible in Langfuse but redacted in stdoutlogging.init() was not called; observability used the lazy default filter for spans only. Call logging.init() at startup. Custom env patterns ignored on spans — Same cause. Env vars are read inside logging.init(), not inside configure_observability(). Malformed BB_AI_SDK_REDACTION_PATTERNSinit() raises ValueError at startup with the JSON index and reason. Fix the env var before serving traffic.

Starters

Wire bb_ai_sdk.logging.init() in your central logger.py (or main.py) after basicConfig. Use STANDARD_FORMAT and DEFAULT_DATEFMT, drive level from LOG_LEVEL in app settings, and call init(capture_warnings=True). See the Multi agent starter for a full example.

Observability

Tracing, bb.* attributes, and export setup