Advanced logging

Logging multiple projects

The first logger you initialize in your program becomes the "current" (default) logger. Any subsequent traced function calls will use the current logger. If you'd like to log to multiple projects, you will need to create multiple loggers, in which case setting just one as the current leads to unexpected behavior.

When you initialize a logger, you can specify not to set it as the current logger:

import { initLogger } from "braintrust";
 
async function main() {
  const logger = initLogger({
    projectName: "My Project",
    apiKey: process.env.BRAINTRUST_API_KEY,
    setCurrent: false,
  });
 
  // NOTE: When you `setCurrent` to false, you need to call `traced` on the logger,
  // since the global `traced` function will not pick up this logger. Within this
  // callback, however, calling globally `traced` or `wrapTraced` functions will
  // work as usual.
  await logger.traced(async (span) => {
    // Do some work
    span.log({ output: "Hello, world!" });
  });
}

Caching loggers

When you initialize a logger, it performs some background work to (a) login to Braintrust if you haven't already, and (b) fetch project metadata. This background work does not block your code; however, if you initialize a logger on each request, it will slow down logging performance quite a bit. Instead, it's a best practice to cache these loggers and reuse them:

import { initLogger, Logger } from "braintrust";
 
// See docs below for more information on setting the async flush flag to true or false
const loggers = new Map<string, Logger<true>>();
 
function getLogger(projectName: string): Logger<true> {
  if (!loggers.has(projectName)) {
    loggers.set(
      projectName,
      initLogger({
        projectName,
        apiKey: process.env.BRAINTRUST_API_KEY,
        setCurrent: false,
        asyncFlush: true,
      }),
    );
  }
  return loggers.get(projectName)!;
}

Initializing login

Last, but not least, the logger lazily authorizes against Braintrust when it is first used. This information is shared across loggers, but you may want to explicitly call login() once to avoid having to pass in an API key to each logger (or to use the BRAINTRUST_API_KEY environment variable).

There is a lower-level mechanism which can even let you use different API keys for different loggers, but it's not documented or officially supported. Get in touch if you need this.

import { login } from "braintrust";
 
// Run this function once at the beginning of your application
async function init() {
  await login({
    apiKey: process.env.BRAINTRUST_API_KEY,
  });
}

On this page