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
Afterlogging.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:logging.basicConfig(or dictConfig) with a format preset that includes%(trace_id)sand%(span_id)sbb_ai_sdk.logging.init()— once, before serving trafficconfigure_observability(...)— tracing and instrumentors
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 frombb_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 wheninit() runs):
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
Passrecord_redactions=True on the first init() call:
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 stdout — logging.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_PATTERNS — init() raises ValueError at startup with the JSON index and reason. Fix the env var before serving traffic.
Starters
Wirebb_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