@logtide/fastify is a Fastify plugin that provides
automatic request logging, per-request scoping, lifecycle hooks, and W3C Trace Context propagation.
Installation
npm install @logtide/fastify Quick Start
import Fastify from 'fastify';
import { hub } from '@logtide/core';
import { logtide } from '@logtide/fastify';
const fastify = Fastify();
// Register the plugin (initializes LogTide automatically)
await fastify.register(logtide, {
dsn: 'https://[email protected]',
service: 'api-server',
environment: 'production',
});
fastify.get('/users/:id', async (request, reply) => {
// Access request-scoped context
request.logtideScope.setTag('userId', request.params.id);
hub.captureLog('info', 'Fetching user', {
userId: request.params.id,
});
return { id: request.params.id, name: 'Alice' };
});
await fastify.listen({ port: 3000 }); Plugin Options
The plugin accepts all ClientOptions from @logtide/core:
await fastify.register(logtide, {
dsn: 'https://[email protected]',
service: 'api-server',
environment: 'production',
release: '1.0.0',
tracesSampleRate: 1.0,
debug: false,
});
Plus three Fastify-specific capture options. They are all opt-in and attach their
data to the request span (http.request_body,
http.response_body,
http.request_headers). Bodies are captured raw
(no redaction) and truncated to 4096 characters — gate them to non-sensitive routes if needed.
await fastify.register(logtide, {
dsn: 'https://[email protected]',
service: 'api-server',
// Capture options (all default to false)
includeRequestBody: true, // → span attribute http.request_body
includeResponseBody: true, // → span attribute http.response_body (v0.9.0+)
includeRequestHeaders: true, // → span attribute http.request_headers
// or capture only specific headers:
// includeRequestHeaders: ['x-request-id', 'x-tenant-id'],
});
Sensitive headers (authorization,
cookie,
set-cookie,
x-api-key …) are always stripped from
includeRequestHeaders.
Request Scoping
Each request gets an isolated scope. Tags, user data, and extras set on the scope are included in all events captured during that request lifecycle.
import { hub } from '@logtide/core';
fastify.addHook('onRequest', async (request) => {
request.logtideScope.setExtra('userId', request.user?.id);
request.logtideScope.setTag('tenant', request.headers['x-tenant-id']);
});
fastify.get('/orders', async (request) => {
// Logs include user + tenant automatically
hub.captureLog('info', 'Listing orders');
return { orders: [] };
}); Lifecycle Hooks
The plugin hooks into Fastify's request lifecycle to provide automatic instrumentation:
| Hook | Behavior |
|---|---|
onRequest | Creates request scope, extracts traceparent, starts span |
onResponse | Logs request completion with duration and status code |
onError | Captures errors with full request context |
onClose | Flushes pending events on server shutdown |
Error Handling
// Errors thrown in route handlers are automatically captured
fastify.get('/users/:id', async (request) => {
const user = await getUser(request.params.id);
if (!user) {
// This error is captured with the request scope context
throw fastify.httpErrors.notFound('User not found');
}
return user;
});
// Custom error handler still works
fastify.setErrorHandler((error, request, reply) => {
// Error was already captured by LogTide
reply.status(error.statusCode || 500).send({
error: error.message,
traceId: request.logtideTraceId,
});
}); API Reference
| Export | Description |
|---|---|
logtide | Fastify plugin — register with fastify.register(logtide, options) |
request.logtideScope | Per-request scope for setting tags, user, extras |
request.logtideTraceId | Current trace ID for the request |
See the JavaScript SDK core docs for the full @logtide/core API.