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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nextrush/logger

v3.0.5

Published

Request logging middleware for NextRush - wraps @nextrush/log

Downloads

450

Readme

@nextrush/logger

Request logging middleware for NextRush. This package wraps @nextrush/log and provides:

  • Re-exports of all @nextrush/log functionality
  • Request logging middleware for NextRush applications
  • Automatic correlation ID handling
  • Context-attached logger (ctx.log) for request handlers

Installation

pnpm add @nextrush/logger

Quick Start

import { createApp } from '@nextrush/core';
import { logger, createLogger } from '@nextrush/logger';

const app = createApp();

// Add request logging middleware
app.use(logger());

// Direct logging for application code
const log = createLogger('MyService');
log.info('Server starting');

// Access logger in handlers via context
app.use(async (ctx) => {
  ctx.log.info('Fetching users');
  ctx.json({ users: [] });
});

Output (development):

2025-01-15 10:30:00.123 🐛 [DEBUG] [nextrush] (abc12345-...) Request started
  method: "GET"
  path: "/users"
  ip: "127.0.0.1"
2025-01-15 10:30:00.125 ℹ️  [INFO ] [nextrush] (abc12345-...) Fetching users
2025-01-15 10:30:00.130 ℹ️  [INFO ] [nextrush] (abc12345-...) GET /users
  method: "GET"
  path: "/users"
  status: 200
  duration: 7

API

logger(options?)

Request logging middleware that:

  • Logs request start (development only by default)
  • Logs request completion with duration
  • Attaches ctx.log for use in handlers
  • Extracts/generates correlation IDs
app.use(logger({
  // Log level configuration
  minLevel: 'info',              // Minimum log level
  successLevel: 'info',          // Level for 2xx/3xx responses (default: 'info')
  clientErrorLevel: 'warn',      // Level for 4xx responses (default: 'warn')
  serverErrorLevel: 'error',     // Level for 5xx responses (default: 'error')

  // Request logging
  logRequestStart: true,         // Log when request starts (default: true in dev)

  // Correlation ID
  correlationIdHeader: 'x-request-id',  // Header name (default: 'x-request-id')
  generateCorrelationId: true,          // Generate if not in headers (default: true)

  // Customization
  context: 'api',                // Logger context name (default: 'nextrush')
  skip: (ctx) => ctx.path === '/health', // Skip logging for paths
  formatMessage: (ctx, duration) => \`\${ctx.method} \${ctx.path} - \${duration}ms\`,

  // Silent mode (no console output, transports still called)
  silent: false,
}));

attachLogger(options?)

Lightweight middleware that only attaches ctx.log without request logging.

app.use(
  attachLogger({
    correlationIdHeader: 'x-request-id',
    generateCorrelationId: true,
    context: 'api',
  })
);

app.use(async (ctx) => {
  ctx.log.info('Handler called');
  ctx.json({ ok: true });
});

hasLogger(ctx)

Type guard to check if context has logger attached.

app.use(async (ctx) => {
  if (hasLogger(ctx)) {
    ctx.log.info('Logger is available');
  }
});

getLogger(ctx, fallbackContext?)

Get logger from context, or create a fallback.

app.use(async (ctx) => {
  const log = getLogger(ctx, 'fallback');
  log.info('Always works');
});

Using ctx.log

When using logger() or attachLogger() middleware, a request-scoped logger is attached to ctx.log:

app.use(logger());

app.use(async (ctx) => {
  // All log levels
  ctx.log.trace('Trace message');
  ctx.log.debug('Debug message');
  ctx.log.info('Processing request', { path: ctx.path });
  ctx.log.warn('Rate limit approaching', { remaining: 5 });
  ctx.log.error('Failed to process', new Error('Database error'));
  ctx.log.fatal('Critical failure');

  // Performance timing
  const timer = ctx.log.time('database-query');
  // ... perform work ...
  timer.end('Query completed', { rows: 1 });

  // Child loggers
  const dbLog = ctx.log.child('database');
  dbLog.info('Connection established');

  // With additional metadata
  const enrichedLog = ctx.log.withMetadata({ service: 'user-api' });
  enrichedLog.info('Request processed');

  ctx.json({ ok: true });
});

TypeScript Type Safety

import type { LoggerContext } from '@nextrush/logger';

app.use(async (ctx) => {
  // Option 1: Type cast
  (ctx as LoggerContext).log.info('Typed access');

  // Option 2: Type guard
  if (hasLogger(ctx)) {
    ctx.log.info('Now typed correctly');
  }

  // Option 3: Helper function
  const log = getLogger(ctx);
  log.info('Always safe');
});

Re-exports from @nextrush/log

This package re-exports everything from @nextrush/log:

Core

import {
  createLogger, // Create a new logger instance
  defaultLogger, // Default logger instance (re-exported from @nextrush/log)
  log, // Quick-access log function
  Logger, // Logger class
  configure, // Configure global settings
  setGlobalLevel, // Set global minimum level
} from '@nextrush/logger';

// Note: `logger` (without "default") is the middleware function:
import { logger } from '@nextrush/logger'; // middleware factory

Transports

import {
  createConsoleTransport,
  createBatchTransport,
  createFilteredTransport,
  createRateLimitedTransport,
  addGlobalTransport,
} from '@nextrush/logger';

Serializers & Formatters

import {
  safeSerialize,
  serializeError,
  redactSensitiveValues,
  formatJSON,
  formatPrettyTerminal,
} from '@nextrush/logger';

Runtime Detection

import { detectRuntime, getRuntime, isProductionBuild } from '@nextrush/logger';

Async Context

import { runWithContext, getAsyncContext, isAsyncContextAvailable } from '@nextrush/logger';

Runtime Compatibility

| Runtime | Support | Notes | | ------------------------ | ---------- | -------------------------------------- | | Node.js 20+ | ✅ Full | AsyncLocalStorage for context | | Bun | ✅ Full | AsyncLocalStorage for context | | Deno | ✅ Full | AsyncLocalStorage for context | | Edge (Vercel/Cloudflare) | ⚠️ Partial | Fallback context | | Browsers | ⚠️ Partial | Fallback context, different formatting |

Configuration Examples

Production

app.use(
  logger({
    minLevel: 'info',
    redact: true,
    logRequestStart: false,
    skip: (ctx) => ctx.path === '/health',
  })
);

Development

app.use(
  logger({
    minLevel: 'trace',
    pretty: true,
    colors: true,
    logRequestStart: true,
  })
);

Best Practices

  1. Use ctx.log in handlers - Includes correlation ID automatically
  2. Skip health check paths - Reduce log noise
  3. Use child loggers - ctx.log.child('db') for clear context
  4. Enable redaction in production - Sensitive data is masked
  5. Use timing for performance - ctx.log.time() for measurements

License

MIT