LogTide

Fastify SDK

@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,
});

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
onRequestCreates request scope, extracts traceparent, starts span
onResponseLogs request completion with duration and status code
onErrorCaptures errors with full request context
onCloseFlushes 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
logtideFastify plugin — register with fastify.register(logtide, options)
request.logtideScopePer-request scope for setting tags, user, extras
request.logtideTraceIdCurrent trace ID for the request

See the JavaScript SDK core docs for the full @logtide/core API.