@thinkeloquent/core-route-logger
v1.1.4
Published
Fastify plugin for logging all registered routes to console, file, and/or structured JSON
Maintainers
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
onReadyhook - 📝 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-loggerUsage
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.logUse 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
- The plugin registers an
onReadyhook with Fastify - When
server.ready()orserver.listen()is called, the hook executes - The plugin calls
fastify.printRoutes()to get all registered routes - Routes are formatted according to options
- 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
outputModeoption available - New
loggerOutputoption (deprecated, useoutputModeinstead) - 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:coverageBuilding
# Build TypeScript
pnpm run build
# Type check
pnpm run typecheckLicense
MIT
Contributing
Contributions are welcome! Please ensure tests pass before submitting PRs.
Part of the Fastify Multi-Tenant Framework by ThinkEloquent.
