Documentation Index Fetch the complete documentation index at: https://docs.tracelit.io/llms.txt
Use this file to discover all available pages before exploring further.
Requirements: Node.js ≥ 18.0.0 · TypeScript ≥ 5 (optional) · CJS and ESM both supported
Installation
npm install @tracelit/sdk
Quick start
The SDK must be initialised before any other modules that need auto-instrumentation (Express, Mongoose, Redis, etc.). Create a dedicated init file and import it as the very first line of your entry point.
Create your Tracelit initializer
import Tracelit from "@tracelit/sdk" ;
Tracelit . configure (( config ) => {
config . apiKey = process . env . TRACELIT_API_KEY ; // required
config . serviceName = "payments-api" ; // required
config . environment = process . env . NODE_ENV ?? "production" ;
config . sampleRate = 1.0 ;
});
Tracelit . start ();
Import the initializer first in your entry point
import "./tracelit" ; // ← MUST be the very first import
import express from "express" ;
const app = express ();
app . get ( "/" , ( _req , res ) => res . send ( "Hello, Tracelit!" ));
app . listen ( 3000 );
Set your environment variables
TRACELIT_API_KEY = your-api-key
TRACELIT_SERVICE_NAME = payments-api
TRACELIT_ENVIRONMENT = production
Configuration reference
All options can be set in the configure callback or via environment variables.
Option Env variable Default Description apiKeyTRACELIT_API_KEY— Required. Your Tracelit ingest API keyserviceNameTRACELIT_SERVICE_NAME— Required. Service name shown in TracelitenvironmentTRACELIT_ENVIRONMENT"production"Deployment environment tag endpointTRACELIT_ENDPOINThttps://ingest.tracelit.appOverride only when self-hosting sampleRateTRACELIT_SAMPLE_RATE1.0Sampling ratio 0.0–1.0. Errors always export. enabledTRACELIT_ENABLEDtrueSet false to disable all telemetry in tests resourceAttributes— {}Extra key/value pairs on every span, metric, and log
Custom resource attributes
Tracelit . configure (( config ) => {
config . apiKey = process . env . TRACELIT_API_KEY ;
config . serviceName = "orders-api" ;
config . resourceAttributes = {
"deployment.region" : "us-east-1" ,
"team" : "platform" ,
};
});
Tracing
Manual spans
Tracelit.tracer is a standard OpenTelemetry Tracer and supports the full OTel JS API.
import Tracelit from "@tracelit/sdk" ;
const result = await Tracelit . tracer . startActiveSpan ( "process_payment" , async ( span ) => {
span . setAttribute ( "payment.id" , payment . id );
span . setAttribute ( "payment.amount" , String ( amount ));
span . setAttribute ( "payment.currency" , currency );
try {
const result = await processPayment ( payment );
span . setAttribute ( "payment.status" , result . status );
return result ;
} catch ( err ) {
span . recordException ( err as Error );
span . setStatus ({ code: 2 /* ERROR */ , message: ( err as Error ). message });
throw err ;
} finally {
span . end ();
}
});
Automatic instrumentation
Tracelit.start() enables every auto-instrumentation package present in your node_modules via @opentelemetry/auto-instrumentations-node. No extra config needed.
Library What is captured Express / Fastify / Koa / Hapi HTTP request traces, route and method attributes http / httpsAll inbound and outbound HTTP call traces pg / mysql2 / better-sqlite3SQL query traces with sanitised statement text Mongoose / MongoDB MongoDB operation traces Redis / ioredis Cache command traces gRPC Client and server RPC traces GraphQL Resolver and query traces Kafka.js / rhea Message publish/consume traces Prisma ORM operation traces Undici / fetch Outbound HTTP call traces
Metrics
Tracelit.metrics returns null before start() is called or when the SDK is disabled — optional chaining (?.) is safe everywhere.
Counter
const ordersPlaced = Tracelit . metrics . counter ( "orders.placed" , {
description: "Total orders placed" ,
unit: "{orders}" ,
});
ordersPlaced ?. add ( 1 , { currency: "USD" , channel: "web" });
Histogram
const apiLatency = Tracelit . metrics . histogram ( "external.api.duration" , {
description: "External API call duration" ,
unit: "ms" ,
});
const start = Date . now ();
await callExternalApi ();
apiLatency ?. record ( Date . now () - start , { service: "stripe" });
Gauge
const queueDepth = Tracelit . metrics . gauge ( "job_queue.depth" , {
description: "Number of pending background jobs" ,
unit: "{jobs}" ,
});
queueDepth ?. record ( await queue . pendingCount (), { queue: "default" });
Observable gauge (callback-based)
Use when the value is expensive to compute and should only be read on the export interval:
const queueGauge = Tracelit . metrics . observableGauge ( "message.queue.size" , {
description: "Estimated message queue size" ,
unit: "{messages}" ,
});
queueGauge ?. addCallback (( result ) => {
result . observe ( getQueueSize (), { queue: "events" });
});
HTTP server metrics (Express middleware)
import express from "express" ;
import Tracelit from "@tracelit/sdk" ;
const app = express ();
app . use ( Tracelit . expressMetricsMiddleware ()); // ← add before routes
Metric Type Description http.server.request.countCounter Total HTTP requests http.server.request.durationHistogram Request duration (ms) http.server.error.countCounter 5xx responses
Attributes on all HTTP metrics: http.method, http.route, http.status_code.
Automatic process metrics
Once Tracelit.start() is called, the following are collected with no extra code:
Metric Type Description Interval process.memory.rssGauge Process RSS memory (MB) 60 s process.event_loop.lagHistogram Node.js event loop lag (ms) 30 s
Both pollers use unref()’d timers and will not prevent your process from exiting.
Logging
Console bridge (automatic)
When Tracelit.start() is called, all console.debug/log/info/warn/error calls are automatically forwarded to the OTel LoggerProvider. Original console output is preserved and logs are correlated with the active trace via trace_id and span_id.
console methodOTel SeverityNumber debug / log5 (DEBUG) info9 (INFO) warn13 (WARN) error17 (ERROR)
Winston transport
import winston from "winston" ;
import { WinstonTransport } from "@tracelit/sdk" ;
import { logs } from "@opentelemetry/api-logs" ;
const logger = winston . createLogger ({
transports: [
new winston . transports . Console (),
new WinstonTransport ( logs . getLoggerProvider ()),
],
});
logger . info ( "Order created" , { orderId: "ord_123" });
Pino destination
import pino from "pino" ;
import { createPinoDestination } from "@tracelit/sdk" ;
import { logs } from "@opentelemetry/api-logs" ;
const otelDest = createPinoDestination ( logs . getLoggerProvider ());
const logger = pino (
pino . multistream ([
{ stream: process . stdout },
{ stream: otelDest },
])
);
logger . info ({ orderId: "ord_123" }, "Order created" );
Sampling and error guarantee
Tracelit . configure (( config ) => {
config . sampleRate = 0.1 ; // keep 10% of traces
});
Error spans are always exported , even when the parent trace is outside the sample ratio. The SDK uses ErrorAlwaysOnSampler + ErrorSpanProcessor to guarantee this — no configuration required.
Disabling in tests
// tracelit.ts
Tracelit . configure (( config ) => {
config . apiKey = process . env . TRACELIT_API_KEY ;
config . serviceName = "my-service" ;
config . enabled = process . env . TRACELIT_ENABLED !== "false" ;
});
Tracelit . start ();
# Run tests with telemetry off
TRACELIT_ENABLED = false npx jest
# Or set permanently in .env.test
TRACELIT_ENABLED = false
TypeScript / JavaScript compatibility
The package ships as dual CJS + ESM bundles with full TypeScript declaration files.
ESM (TypeScript / modern Node)
CommonJS
import Tracelit from "@tracelit/sdk" ;
Tracelit . configure (( c ) => {
c . apiKey = process . env . TRACELIT_API_KEY ;
c . serviceName = "my-app" ;
});
Tracelit . start ();
Complete example
import "./tracelit" ; // initialise first!
import express from "express" ;
import Tracelit from "@tracelit/sdk" ;
const app = express ();
app . use ( Tracelit . expressMetricsMiddleware ());
app . post ( "/orders" , async ( req , res ) => {
const result = await Tracelit . tracer . startActiveSpan ( "create-order" , async ( span ) => {
span . setAttribute ( "order.channel" , req . body . channel ?? "web" );
try {
const order = await createOrder ( req . body );
span . setAttribute ( "order.id" , order . id );
return order ;
} catch ( err ) {
span . recordException ( err as Error );
span . setStatus ({ code: 2 , message: ( err as Error ). message });
throw err ;
} finally {
span . end ();
}
});
res . status ( 201 ). json ( result );
});
app . listen ( 3000 , () => console . log ( "Listening on :3000" ));
GitHub
Source code and issue tracker: github.com/Tracelit-AI/tracelit-node