Logging
configure_logging(), LogSettings, the BAND_LOG_* variables, and OpenTelemetry correlation
Band logging is opt-in. Two entry points apply the same process-wide configuration: configure_logging() takes it as arguments, and LogSettings reads and validates it from the BAND_LOG_* variables. Without one of them, the Agent started line that confirms a connection never prints.
configure_logging()
For an embedded SDK, show Band logs and leave other loggers at WARNING:
For an agent, runner, or CLI that owns the process, also raise every other logger:
root_level applies to all non-Band loggers, so third-party dependencies such as httpx become as verbose as the level you pass. Use extra_loggers to pin individual dependencies back down, or chatty_logger_levels() for the Band HTTP and WebSocket dependencies (httpx, httpcore, phoenix_channels_python_client) as a group.
The rich and json styles require the logging extra, uv add "band-sdk[logging]==6.0.1". Without it, configuration raises BandConfigError, for example Logging style <LoggingStyle.JSON: 'json'> requires optional dependency 'python-json-logger>=3.1.0'. Install it with: pip install 'band-sdk[logging]'.
Both entry points call logging.config.dictConfig, which replaces the root handlers, so configure Band logging first and attach your host application’s handlers after. build_logging_config() and LogSettings().build_config() return the dictConfig dictionary without applying it. Log files Band creates are owner-only (mode 0600, in a 0700 directory), because Band logs message content at DEBUG.
The public logging types are LogLevel (an int or a level name), LogStream (stderr, stdout), LoggingStyle (standard, rich, json), FileStyle (standard, json), FormatStyle (%, {, $), and LoggingConfig (the dictConfig mapping). All are importable from band.
LogSettings
LogSettings maps the same configuration onto environment variables. LogSettings().configure() suits an embedded SDK; LogSettings().for_application().configure() raises all non-Band loggers to BAND_LOG_LEVEL for a process that owns its logs, unless BAND_LOG_ROOT_LEVEL is set. configure_logging_from_env() is shorthand for LogSettings().configure().
Explicit LogSettings constructor values take precedence over environment variables, which take precedence over the defaults above, and an empty variable falls back to the default. LogSettings.create(...) drops None fields, so an optional CLI flag that was not passed leaves the environment value alone:
BAND_LOG_OVERRIDES is merged with the extra_loggers mapping passed to configure(), and the environment wins when both name the same logger.
OpenTelemetry Correlation
The host application owns OpenTelemetry providers, processors, exporters, and handlers, and Band exports no telemetry of its own. Band provides correlation: the json style writes otelTraceID, otelSpanID, otelTraceSampled, and otelServiceName in every record, plus trace_context, which holds the active W3C traceparent for the current turn or a generated ID when no span is active. Without instrumentation the four otel* fields serialize as null.
Select the json style with BAND_LOG_CONSOLE_STYLE=json or LogSettings(log_console_style=LoggingStyle.JSON), and configure Band logging before attaching an OpenTelemetry log handler, because dictConfig would drop it:
If you replace the default JSON field list with json_fields=..., splice OTEL_CORRELATION_FIELDS from band.logging_config back in or the correlation keys are dropped.
PydanticAIAdapter forwards its instrument argument to Pydantic AI. Other frameworks are instrumented through their own OpenTelemetry integration, and out-of-process model backends emit their spans outside the SDK process. The OpenTelemetry example at band-sdk-v6.0.1 shows console exporters, trace-context injection, and provider shutdown.