npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@thinkeloquent/core-route-logger

v1.1.4

Published

Fastify plugin for logging all registered routes to console, file, and/or structured JSON

Readme

@thinkeloquent/core-route-logger

A Fastify plugin that automatically logs all registered routes to console and/or file when the server is ready.

Features

  • 🚀 Automatic Logging - Logs routes when server is ready using onReady hook
  • 📝 Console & File Output - Output to console, file, or both
  • 🎨 Pretty Formatting - Optional formatted table output
  • ⏱️ Timestamps - Optional timestamp in output
  • 🔧 Configurable - Flexible options for different use cases
  • Type-Safe - Full TypeScript support with Zod validation
  • 🧪 Well Tested - Comprehensive unit tests
  • 🚫 Non-Breaking - Won't prevent server startup on errors

Installation

pnpm install @thinkeloquent/core-route-logger

Usage

Basic Usage

import Fastify from 'fastify';
import routeLogger from '@thinkeloquent/core-route-logger';

const server = Fastify();

// Register the plugin with default options
await server.register(routeLogger);

// Register your routes
server.get('/api/users', async () => ({ users: [] }));
server.post('/api/users', async () => ({ created: true }));
server.get('/api/posts/:id', async () => ({ post: {} }));

// Start server - routes will be logged when ready
await server.listen({ port: 3000 });

Output (console):

================================================================================
Fastify Routes
================================================================================
Generated at: 2025-01-21T10:30:00.000Z

└── / (HEAD, GET)
    ├── api/
    │   ├── users (GET)
    │   │   └── / (POST)
    │   └── posts/
    │       └── :id (GET)
================================================================================

Output (routes.log file):

Routes are also written to ./routes.log by default.

Configuration Options

await server.register(routeLogger, {
  enabled: true,                    // Enable/disable plugin (default: true)
  outputPath: './logs/routes.log',  // Path for log file (default: './routes.log')
  consoleOutput: true,              // Log to console (default: true)
  fileOutput: true,                 // Write to file (default: true)
  includeTimestamp: true,           // Include timestamp (default: true)
  prettyPrint: true,                // Pretty formatting (default: true)
  outputMode: 'pretty',             // Output mode: 'pretty', 'json', or 'both' (default: 'pretty')
  loggerOutput: false,              // Deprecated: Use outputMode instead (default: false)
});

Output Modes

The plugin supports three output modes via the outputMode option:

'pretty' (Default)

Human-readable formatted output to console and/or file.

await server.register(routeLogger, {
  outputMode: 'pretty',
  consoleOutput: true,
  fileOutput: true,
});

'json'

Structured JSON output to Fastify logger only. Perfect for log aggregation systems.

await server.register(routeLogger, {
  outputMode: 'json',
});

JSON Output Format:

{
  "event": "routes_registered",
  "timestamp": "2025-10-22T06:41:12.244Z",
  "count": 3,
  "routes": [
    "└── / (GET, HEAD)",
    "    ├── api/",
    "    │   └── users (GET)"
  ]
}

'both'

Combines pretty console/file output AND JSON logging. Best for development + monitoring.

await server.register(routeLogger, {
  outputMode: 'both',
  consoleOutput: true,
  fileOutput: true,
  outputPath: './logs/routes.log',
});

Examples

Console Only (No File)

await server.register(routeLogger, {
  consoleOutput: true,
  fileOutput: false,
});

File Only (No Console)

await server.register(routeLogger, {
  consoleOutput: false,
  fileOutput: true,
  outputPath: './logs/my-routes.log',
});

Minimal Output (No Formatting or Timestamp)

await server.register(routeLogger, {
  prettyPrint: false,
  includeTimestamp: false,
});

Disable in Production

await server.register(routeLogger, {
  enabled: process.env.NODE_ENV !== 'production',
});

API

Plugin Options

type RouteOutputMode = 'pretty' | 'json' | 'both';

interface RouteLoggerOptions {
  enabled?: boolean;           // Default: true
  outputPath?: string;         // Default: './routes.log'
  consoleOutput?: boolean;     // Default: true
  fileOutput?: boolean;        // Default: true
  includeTimestamp?: boolean;  // Default: true
  prettyPrint?: boolean;       // Default: true
  outputMode?: RouteOutputMode; // Default: 'pretty'
  loggerOutput?: boolean;      // Default: false (deprecated, use outputMode)
}

Route Log Result

After the server is ready, the plugin decorates the Fastify instance with routeLogResult:

interface RouteLogResult {
  success: boolean;
  routeCount: number;
  consoleLogged: boolean;
  fileLogged: boolean;
  loggerLogged: boolean;
  outputPath?: string;
  error?: string;
}

// Access the result
server.routeLogResult?.routeCount;    // Number of routes
server.routeLogResult?.success;       // Whether logging succeeded
server.routeLogResult?.loggerLogged;  // Whether JSON was logged to fastify.log

Use Cases

Development Debugging

Quickly see all registered routes during development:

await server.register(routeLogger, {
  enabled: process.env.NODE_ENV === 'development',
  consoleOutput: true,
  fileOutput: false,
});

Documentation Generation

Generate a routes file for documentation:

await server.register(routeLogger, {
  outputPath: './docs/routes.txt',
  consoleOutput: false,
  fileOutput: true,
});

CI/CD Validation

Log routes during CI/CD to verify route registration:

await server.register(routeLogger, {
  outputPath: './artifacts/routes.log',
  prettyPrint: true,
});

Multi-Tenant Applications

Perfect for debugging route registration in multi-tenant applications with dynamic routing.

Log Aggregation & Monitoring

Send structured JSON route data to log aggregation systems (ELK, Datadog, CloudWatch, etc.):

await server.register(routeLogger, {
  outputMode: 'json',  // JSON only to fastify.log
});

Or combine both for local debugging + remote monitoring:

await server.register(routeLogger, {
  outputMode: 'both',
  consoleOutput: true,
  fileOutput: true,
  outputPath: './logs/routes.log',
});

How It Works

  1. The plugin registers an onReady hook with Fastify
  2. When server.ready() or server.listen() is called, the hook executes
  3. The plugin calls fastify.printRoutes() to get all registered routes
  4. Routes are formatted according to options
  5. Output is written to console and/or file as configured

Error Handling

The plugin is designed to never prevent server startup:

  • If file writing fails, the error is logged but the server continues
  • Invalid paths are caught and logged
  • All errors are decorated on the server instance for inspection
if (!server.routeLogResult?.success) {
  console.error('Route logging failed:', server.routeLogResult?.error);
}

Migration Guide

From custom-route-logger

If you're using a custom route logger that logs structured JSON to fastify.log, you can replace it with:

Before:

// custom-route-logger.ts
fastify.log.info({
  event: 'routes_registered',
  timestamp: new Date().toISOString(),
  count: routeCount,
  routes: routesArray,
}, `Registered ${routeCount} routes`);

After:

import routeLogger from '@thinkeloquent/core-route-logger';

await server.register(routeLogger, {
  outputMode: 'json',  // For JSON-only logging
  // OR
  outputMode: 'both',  // For pretty console/file + JSON
});

Upgrading from v1.0.x

Version 1.1.0 adds new options but maintains full backwards compatibility:

  • Existing configurations work unchanged
  • New outputMode option available
  • New loggerOutput option (deprecated, use outputMode instead)
  • No breaking changes

TypeScript Support

Full TypeScript support with exported types:

import type {
  RouteLoggerOptions,
  RouteLogResult,
  RouteOutputMode
} from '@thinkeloquent/core-route-logger';

Testing

# Run tests
pnpm test

# Run tests in watch mode
pnpm run test:watch

# Run tests with coverage
pnpm run test:coverage

Building

# Build TypeScript
pnpm run build

# Type check
pnpm run typecheck

License

MIT

Contributing

Contributions are welcome! Please ensure tests pass before submitting PRs.


Part of the Fastify Multi-Tenant Framework by ThinkEloquent.