# Node.js SDK Instrument Node.js applications with @prilog/monitoring, automatic instrumentation, correlated logs, and exception capture. ## Install ```bash npm install @prilog/monitoring ``` Provision a monitoring connection and copy its DSN into your server's `PRILOG_DSN` environment variable. See [monitoring setup](/docs/monitoring/#provision-a-connection). ## Initialize before application imports Create `instrumentation.ts` in your TypeScript ESM project (`"type": "module"` in `package.json`): ```typescript import prilog from '@prilog/monitoring'; const monitoring = prilog.init({ dsn: process.env.PRILOG_DSN, serviceName: 'checkout-api', }); export default monitoring; ``` With Node.js 22.18 or later, preload it before your application's entry point. Replace `./src/server.ts` with your actual entry point: ```bash node --import ./instrumentation.ts ./src/server.ts ``` This uses [Node's built-in TypeScript support](https://nodejs.org/api/typescript.html), which runs erasable TypeScript syntax without type checking. Keep type checking in your existing TypeScript build. If your application uses a TypeScript runner or compiles before startup, preload the instrumentation through that startup flow before application imports. The SDK currently needs a local module declaration for strict TypeScript compilation; see [TypeScript setup](/docs/monitoring/#typescript-setup). Supported framework/client instrumentation, console capture, and uncaught-exception capture are enabled by default. Initialization sends a startup log and span. ## Spans, logs, and handled exceptions ```typescript import prilog from '@prilog/monitoring'; const { withSpan, log, captureException } = prilog; withSpan('checkout.validate', () => { log('info', 'Order validated', { 'order.id': 'example-order' }); }); // Record an exception in an existing handled-error path. captureException(new Error('Payment declined')); ``` - `withSpan(name, callback, attributes?)` supports synchronous and asynchronous callbacks, returns their result, and records and rethrows errors. - `log(level, message, attributes?)` accepts `trace`, `debug`, `info`, `warn`, `error`, and `fatal`. - `captureException(error, attributes?)` records a handled error and its stack trace. ## Configuration reference Pass these options to `init`: - `dsn` — connection DSN; `PRILOG_DSN` takes precedence. No DSN means disabled monitoring. - `serviceName` — defaults to `application`; `OTEL_SERVICE_NAME` takes precedence. - `environment` — defaults to `NODE_ENV` or `production`. - `release` — defaults to `PRILOG_RELEASE`, `GITHUB_SHA`, or `unknown`. - `sampleRate` — root trace sampling ratio between 0 and 1; defaults to `1`. - `captureConsole` — defaults to `true`. - `captureUncaught` — defaults to `true`. - `autoInstrument` — defaults to `true`. - `instrumentations` — OpenTelemetry auto-instrumentation overrides; defaults to an empty object. - `resourceAttributes` — additional OpenTelemetry resource attributes; defaults to an empty object. Server SDKs accept `OTEL_EXPORTER_OTLP_ENDPOINT` to override the OTLP base endpoint. Preserve the DSN's connection token when exporting to Prilog. ## Shutdown and fatal errors Keep the monitoring instance returned by `init` and await `monitoring.shutdown()` in your existing graceful-shutdown handler. This flushes pending telemetry. When the SDK owns the uncaught-exception handler, it captures the exception, flushes within a bounded timeout, and exits with status 1. Explicit error capture records the error without swallowing the application's exception. See the [package source and README](https://github.com/Prilog-ai/prilog-monitoring) for implementation details.