Fastify Integration
Instrument Fastify applications with one npm install. Schema-based route monitoring, plugin lifecycle tracing, hook timing, and Node.js runtime metrics — zero configuration.
How It Works
Install the npm Package
Run npm install @tigerops/fastify or yarn add @tigerops/fastify. The package bundles @opentelemetry/instrumentation-fastify with TigerOps OTLP exporters and a Node.js runtime metrics collector for CPU, heap, and event loop lag.
Register the Plugin
Import and register the TigerOps Fastify plugin before any other plugins. Call fastify.register(tigerops, { apiKey, serviceName }) or let the plugin read TIGEROPS_API_KEY and TIGEROPS_SERVICE_NAME from process.env automatically.
Set Environment Variables
Set TIGEROPS_API_KEY, TIGEROPS_SERVICE_NAME, and TIGEROPS_ENVIRONMENT in your shell or .env file. The plugin respects dotenv if loaded before Fastify starts. Works with @fastify/env schema validation for type-safe config.
Traces, Schema Metrics & Hook Timing
Within seconds TigerOps receives Fastify route spans with schema validation time, hook execution durations, plugin initialization timing, and Node.js runtime metrics from your high-throughput Fastify service.
What You Get Out of the Box
Schema-Based Route Monitoring
Fastify JSON Schema validation time is measured per route and recorded as a child span. Routes with slow schema validation are flagged. The schema identifier and validation error count are attached as span attributes.
Plugin Lifecycle Tracing
Each @fastify/plugin registration and initialization time is measured. Plugin dependency resolution order, encapsulation scope, and decoration count are recorded so slow plugin initialization is immediately visible in traces.
Hook Execution Timing
onRequest, preHandler, onSend, and onResponse hook execution times are measured individually. Hooks that exceed the configured threshold are flagged with their hook name, route pattern, and execution duration.
Node.js Runtime Metrics
Event loop lag, heap used, heap total, external memory, GC pause duration, and active handles count are collected every 15 seconds. Alerts fire when event loop lag exceeds 100ms or heap utilization exceeds 85%.
TypeBox & Zod Schema Awareness
Routes using TypeBox or @sinclair/typebox schemas have their schema ID and property count recorded. Zod schemas wrapped with fastify-zod are instrumented via the Zod parse function for per-field validation timing.
Undici & HTTP Client Tracing
Outgoing HTTP requests made via undici, got, or axios inside Fastify handlers are auto-traced as child spans. W3C traceparent headers are injected automatically for end-to-end distributed tracing across services.
Install & Initialize
One npm install. One plugin register. Full Fastify observability.
# Install the TigerOps Fastify package
npm install @tigerops/fastify
# Set environment variables
export TIGEROPS_API_KEY="your-api-key"
export TIGEROPS_SERVICE_NAME="my-fastify-app"
export TIGEROPS_ENVIRONMENT="production"
// server.ts
import Fastify from 'fastify'
import tigerops from '@tigerops/fastify'
import { getActiveSpan } from '@tigerops/fastify'
const fastify = Fastify({ logger: true })
// Register TigerOps FIRST — before any other plugins
await fastify.register(tigerops, {
apiKey: process.env.TIGEROPS_API_KEY,
serviceName: process.env.TIGEROPS_SERVICE_NAME,
environment: process.env.TIGEROPS_ENVIRONMENT,
captureHeaders: ['x-request-id', 'x-correlation-id'],
slowRouteThresholdMs: 200,
})
// Schema-validated route — validation time is traced
fastify.post('/orders', {
schema: {
body: {
type: 'object',
required: ['items'],
properties: {
items: { type: 'array', minItems: 1 },
},
},
},
handler: async (request, reply) => {
// Add custom span attributes
getActiveSpan()?.setAttribute('order.items', request.body.items.length)
const order = await createOrder(request.body)
return reply.code(201).send(order)
},
})
await fastify.listen({ port: 3000 })Common Questions
Which Fastify versions are supported?
Fastify 4.x and 5.x are fully supported. Node.js 18, 20, and 22 are supported. The plugin uses the Fastify plugin system (fastify-plugin) so it is compatible with all encapsulation-scoped sub-applications.
Does TigerOps work with @fastify/swagger and OpenAPI route definitions?
Yes. When @fastify/swagger is registered, TigerOps reads the operationId from each route and uses it as the span name. This ensures traces group by logical operation name rather than raw URL path.
Can I instrument Fastify workers running behind a reverse proxy like nginx?
Yes. Set the trustProxy option in Fastify and TigerOps will read the real client IP and protocol from X-Forwarded-For and X-Forwarded-Proto headers and attach them to spans correctly.
How does TigerOps handle multipart file uploads?
TigerOps does not buffer or inspect multipart bodies. For routes using @fastify/multipart, the span records the content-type and estimated content-length from the request headers only. File contents are never captured.
Can I add custom attributes to route spans from inside a handler?
Yes. Import { getActiveSpan } from "@tigerops/fastify" and call getActiveSpan()?.setAttribute("key", "value") anywhere inside your handler or hook. The span is associated with the current async context automatically.
Full Fastify Observability in One npm Install
Route traces, schema validation timing, plugin lifecycle, and Node.js runtime metrics — no code changes required.