/healthz, /metrics, Pino-Pretty Off in Prod
Monitoring & Health Checks
A health endpoint, JSON Pino logs, and Prometheus metrics cover most observability needs for a Fastify service.
What you'll learn
- Add a /healthz endpoint returning 200 OK
- Expose Prometheus metrics with fastify-metrics
- Pipe Pino logs to an aggregator
You don’t need a heavy observability stack to ship safely — a health endpoint, JSON logs, and a metrics scrape endpoint handle 90% of operational needs.
Health Endpoint
app.get('/healthz', async () => ({ status: 'ok' }));
app.get('/readyz', async () => {
await app.pg.query('select 1');
return { status: 'ready' };
}); /healthz is a liveness probe (process is alive). /readyz is a readiness probe (deps are
reachable). Kubernetes, Cloud Run, and most load balancers use these.
Prometheus Metrics
import metrics from 'fastify-metrics';
await app.register(metrics, {
endpoint: '/metrics',
routeMetrics: { enabled: true },
}); Scrape /metrics from Prometheus, Grafana Cloud, or Datadog Agent. You get request counts,
durations by route and status code, event-loop lag, and Node process stats — all for free.
Production Logging
Fastify’s built-in Pino logger is the right call — just turn off pino-pretty in production
so logs stay as parseable JSON.
const app = Fastify({
logger:
process.env.NODE_ENV === 'production'
? { level: 'info' }
: { level: 'debug', transport: { target: 'pino-pretty' } },
}); Ship JSON to Datadog, Loki, CloudWatch, or whatever you use. Avoid console.log — it bypasses
the request context.