Applies to:
- Plan -
- Deployment -
Summary
Braintrust Python SDK loggers buffer events and send them asynchronously through SDK-managed state. Because logger calls do not send HTTP requests directly, the logger API does not support setting arbitrary HTTP headers per individual log call. If an application needs to route logs to different Braintrust backends, such as a standard Braintrust deployment and a BYOC deployment, treat that as a routing or deployment concern rather than per-call header mutation. The safest supported patterns are to isolate routing by process/service configuration, or to use separate advanced logging state setup with guidance from Braintrust Support.What is happening
- Logger calls enqueue events locally.
- A background flusher sends those events to Braintrust.
- The flusher uses the SDK state and HTTP connection configuration active for that logger.
- Custom HTTP adapters apply at the connection/state level, not at each individual logger call.
- A single global HTTP adapter is not enough when one Python process must send different log streams to different backends.
- Changing environment variables such as
BRAINTRUST_API_URLduring runtime is not safe for request-by-request routing, especially in multithreaded or async services.
Fix or suggestion
Recommended: isolate backend routing by runtime configuration
When possible, run separate workers, services, or processes for each Braintrust backend. Configure each runtime with the appropriate Braintrust API URL, credentials, and HTTP adapter. This is the simplest and safest model because each process has one clear logging destination. Use this when:- A service only logs to one Braintrust backend.
- You can split traffic before it reaches the logging process.
- You want to avoid shared global SDK state or runtime environment changes.
Advanced: use separate logging contexts for separate backends
If one Python process must log to multiple Braintrust backends, model each backend as a separate logging context/state and route application events to the logger associated with the correct backend. Conceptually:BRAINTRUST_API_URL or inject headers globally for each individual request.
Because this is an advanced setup and may depend on SDK version and deployment details, contact Braintrust Support before relying on manual state construction or internal SDK APIs.
Not recommended
Avoid these patterns:- Setting a global HTTP adapter and expecting it to route individual log calls differently.
- Changing
BRAINTRUST_API_URLwhile the service is running to affect individual requests. - Depending on every upstream service in a distributed trace to preserve a custom routing header unless you have verified that end to end.
- Using internal SDK methods or direct state mutation without Braintrust guidance.
How to confirm it worked
- Send test logs through each configured logger or runtime.
- Confirm each log appears in the expected Braintrust backend.
- Inspect your adapter, proxy, or network logs to verify requests are sent to the expected API URL.
- In distributed systems, verify routing works across the full call chain, not just in the first service.
- Test service startup behavior when Braintrust is temporarily unreachable, especially if your application must remain available even when logging cannot initialize.
Notes
- The Python SDK does not currently expose a general per-log-call
extra_headersoption for logger traffic. set_http_adapterconfigures SDK HTTP behavior broadly; it is useful for retries, timeouts, proxies, certificates, or mTLS, but it is not a per-request routing mechanism.- For BYOC migrations, routing by header may be fragile if traffic passes through many services or tracing integrations. Consider whether routing can happen at a higher level, such as service boundary, proxy, project, or deployment configuration.
- If your migration requires one process to write to multiple Braintrust backends, involve Braintrust Support so we can recommend a setup that matches your SDK version and deployment model.