Skip to main content

@cues/sawdust-datadog

The Datadog provider. It ships everything vendor-specific that used to be baked into core — server logs, browser logs, APM trace injection, and Real User Monitoring — as factories you clip onto the extraTransports / plugins seams. Core never imports a Datadog SDK; you only pull this package (and its optional peers) when you actually use it.

Install

pnpm add @cues/sawdust @cues/sawdust-datadog

The browser SDKs are optional peer dependencies — install them only for the browser logs transport or RUM:

pnpm add @datadog/browser-logs @datadog/browser-rum

Subpaths

ImportProvides
@cues/sawdust-datadogdatadogTransport() (server logs), datadogTraceInjectorPlugin() (APM)
@cues/sawdust-datadog/browserdatadogBrowserTransport()
@cues/sawdust-datadog/rumgetRumClient, setRumClient, createRumClient, resetRumClientLocator, datadogRumErrorPlugin()
@cues/sawdust-datadog/typesDatadog + RUM type definitions

Server logs — datadogTransport(options)

Returns a LogLayerTransport for extraTransports, or undefined when no apiKey is supplied (Sawdust skips falsy entries, so a missing key simply disables it).

import { configureLogger } from '@cues/sawdust/logger'
import { datadogTransport } from '@cues/sawdust-datadog'

configureLogger({
transports: { console: { enabled: true } },
extraTransports: [
datadogTransport({
service: 'orders-api',
logLevel: 'info',
apiKey: process.env.DD_API_KEY,
enabled: process.env.NODE_ENV === 'production',
options: { ddsource: 'nodejs', ddtags: 'env:prod' },
}),
],
})
OptionTypeNotes
servicestringRequired. Logical service name (tags + payload metadata).
logLevelLogLevelTypeRequired. Minimum level the transport emits.
apiKeystringDatadog API key. Omit → transport is skipped.
enabledbooleanBuild but suppress emission when false.
optionsDatadogTransportOptions['options']Datadog intake config (ddsource, ddtags, host, …).
onDebug(event: DatadogDebugEvent) => voidSurface transport diagnostics.

The remaining fields come from DatadogTransportOptions (@cues/sawdust-datadog/types).

APM trace injection — datadogTraceInjectorPlugin(options)

Correlates logs with APM traces. Returns a LogLayerPlugin for plugins, or undefined unless both apiKey and a dd-trace tracer are provided. Node only.

import tracer from 'dd-trace'
import { configureLogger } from '@cues/sawdust/logger'
import { datadogTraceInjectorPlugin } from '@cues/sawdust-datadog'

tracer.init() // initialise dd-trace early, before the logger

configureLogger({
plugins: [
datadogTraceInjectorPlugin({
apiKey: process.env.DD_API_KEY,
tracer,
service: 'orders-api',
environment: 'production',
}),
],
})
OptionTypeNotes
apiKeystringRequired (plugin skipped otherwise).
tracerdd-trace tracerRequired. Initialise it before the logger.
servicestringService label in debug payloads.
environmentstringDeployment environment label.
enabled, onError, …DatadogTraceInjectionOptionsRemaining trace-injection options.

Browser logs — datadogBrowserTransport(options)

From the /browser subpath. Requires the optional peer @datadog/browser-logs. Returns a LogLayerTransport, or undefined when the mandatory init options are missing.

import { configureLogger } from '@cues/sawdust/logger'
import { datadogBrowserTransport } from '@cues/sawdust-datadog/browser'

configureLogger({
transports: { console: { enabled: true } },
extraTransports: [
datadogBrowserTransport({
service: 'web-app',
environment: 'prod',
version: '1.4.2',
logLevel: 'info',
init: {
clientToken: process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN,
forwardErrorsToLogs: true,
},
}),
],
})
OptionTypeNotes
servicestringRequired. Tagging service name.
environmentstringRequired. Mapped to Datadog env.
versionstringRequired. App version for traceability.
logLevelLogLevelTypeRequired. Minimum emitted level.
initDatadogBrowserTransportOptions['init']Browser SDK init (clientToken, forwardErrorsToLogs, …).

RUM — @cues/sawdust-datadog/rum

Requires the optional peer @datadog/browser-rum. A service-locator subsystem matching the logger pattern — bootstrap once, resolve everywhere.

// app/rum/bootstrap.ts
import { getRumClient } from '@cues/sawdust-datadog/rum'

export function ensureRum() {
return getRumClient({
enabled: true,
init: {
clientToken: process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN!,
applicationId: process.env.NEXT_PUBLIC_DD_APP_ID!,
service: 'web-app',
env: process.env.NEXT_PUBLIC_ENVIRONMENT,
},
})
}
ExportPurpose
getRumClient(options?)Get (and lazily init) the singleton RUM client.
setRumClient(client)Install an externally-created client.
createRumClient(options?)Build a client without registering it (tests).
resetRumClientLocator()Reset the locator (tests).
datadogRumErrorPlugin()LogLayer plugin — forwards logged errors to RUM (opt-in).

RumClient methods: init, reset, isEnabled, addAction, addTiming, addError, startView, stopSession, setViewContext, setViewName, setUser, clearUser, setGlobalContext, getGlobalContext, setGlobalAttribute, removeGlobalAttribute.

Forwarding logged errors to RUM (opt-in)

This was automatic in the old built-in browser logger; it is now an explicit plugin:

import { configureLogger } from '@cues/sawdust/logger'
import { datadogRumErrorPlugin } from '@cues/sawdust-datadog/rum'

configureLogger({
transports: { console: { enabled: true } },
plugins: [datadogRumErrorPlugin()], // logger.error(...) → rum.addError(...)
})

It is a no-op until a client is installed and isEnabled() is true. Full walkthrough in the RUM guide.

Migrating from the old built-in API

Old (core built-in)New (this package)
transports.datadogextraTransports: [datadogTransport({ … })]
transports.datadogBrowserextraTransports: [datadogBrowserTransport({ … })] (/browser)
datadogTraceInjectionplugins: [datadogTraceInjectorPlugin({ … })]
automatic RUM error forwardingplugins: [datadogRumErrorPlugin()] (/rum)
RumClient / RumUser from @cues/sawdustfrom @cues/sawdust-datadog/rum (or /types)

See the Providers concept for the model, and @cues/sawdust-otel for a second provider built on the same seams.