Skip to content

stainless-api/xray-emitter-js

Repository files navigation

X-ray emitter

Node and Typescript SDKs to emit request logs to Stainless X-ray.

Getting started

npm add @stainlessdev/xray-emitter

Then using it in Express, for example:

import express from 'express';
import { createEmitter } from '@stainlessdev/xray-emitter/express';
import { getXrayContext } from '@stainlessdev/xray-emitter/node';

const app = express();

const xray = createEmitter({ serviceName: 'my-service' });

app.use(xray);

app.use((req, _res, next) => {
  const ctx = getXrayContext(req);
  ctx?.setActor('tenant-123', 'user-123');
  next();
});

app.get('/', (_req, res) => {
  res.send('ok');
});

Supported frameworks

Framework Import Docs Example
Express @stainlessdev/xray-emitter/express README example
Fastify @stainlessdev/xray-emitter/fastify README example
Hono @stainlessdev/xray-emitter/hono README example
Next.js @stainlessdev/xray-emitter/next README example
Remix @stainlessdev/xray-emitter/remix README example
Effect @stainlessdev/xray-emitter/effect README example

Lower-level adapters:

Adapter Import Docs Example
Node.js (node:http) @stainlessdev/xray-emitter/node README example
Fetch / Edge @stainlessdev/xray-emitter/fetch README example
Core @stainlessdev/xray-emitter README

Configuration

X-ray does not read standard OTEL environment variables. Configure an endpoint by passing endpointUrl or setting STAINLESS_XRAY_ENDPOINT_URL. If both are set, endpointUrl wins. An error is thrown if no endpoint is configured.

The core module (@stainlessdev/xray-emitter) is runtime-agnostic; use it only if you supply a custom exporter instance to createEmitter.

Request IDs

X-ray resolves request IDs from response headers when the span is closed. Configure the header name with requestId.header (default: request-id, emitted as Request-Id). Resolution order is: explicit requestId on the normalized request → response header lookup → UUIDv7 when missing.

If the configured response header is missing when the response is finalized, X-ray will set it (using the explicit ID when provided, otherwise a generated UUIDv7). Existing response headers are not overwritten.

Fetch wrappers

wrapFetch may replace the request/response objects while capturing bodies. wrapFetchPreserve keeps the original request/response whenever possible, but it may replace the response if it needs to inject a missing Request-Id header.

Development

pnpm install
pnpm build
pnpm test

About

X-ray emitter for Node/Typescript

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •