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

logctx

v0.0.5

Published

A Pino-based logger with context-aware logging using async_hooks

Readme

📦 logctx

A lightweight, context-aware logger built on top of Pino, using async_hooks and supporting decorators, DI, and easy context propagation across HTTP or Kafka requests.


🚀 Features

  • ✅ Automatically injects context like userId, traceId, etc., into logs
  • ✅ Built with async_hooks for request-safe storage
  • ✅ Compatible with any Node.js framework (Express, Kafka, etc.)
  • ✅ Optional class decorator @WithLogger() for automatic logger injection
  • ✅ Customizable context shape with zero config by default
  • ✅ Built-in support for Pino transports like pino-pretty
  • ✅ Supports JSON or human-readable log formats via env
  • ✅ Optional log-to-file support with file rotation capability
  • ✅ Supports a generic logging middleware compatible with any framework

📦 Installation

npm install logctx

Or with Yarn:

yarn add logctx

🛠️ Basic Usage

1. Import and use logger

import { runWithContext, ContextualLogger } from 'logctx';

const logger = new ContextualLogger();

runWithContext({ userId: '123', traceId: 'xyz' }, () => {
  logger.log.info('This will include userId and traceId');
});

2. Use @WithLogger() Decorator

import { WithLogger } from 'logctx';

@WithLogger()
class UserService {
  private log: any;
  doWork() {
    this.log.info('Logged with contextual metadata');
  }
}

⚠️ Make sure you use a DI container (like typedi) or Container.get(UserService) so decorators are respected.


3. Configure Custom Context Getter (Optional)

By default, the logger uses whatever was passed via runWithContext. But you can override this globally:

import { configureLoggerContext } from 'logctx';

configureLoggerContext(() => ({
  userId: 'fallback-user',
  tenantId: 'default-tenant'
}));

⚙️ Environment Variables

| Variable | Description | Default | | --------------- | ------------------------------------------------ | ---------------- | | APP_NAME | Name to appear in logs | logctx | | LOG_LEVEL | Logging level (debug, info, warn, error) | info | | LOG_FORMAT | Log output format: json or pretty | json | | LOG_TO_FILE | Enable file logging: true or false | false | | LOG_FILE_PATH | File path to store logs (if LOG_TO_FILE=true) | ./logs/app.log |


🧠 API Reference

runWithContext(context, callback)

Wraps a function with the provided context for async propagation.

runWithContext({ userId: 'abc' }, () => {
  logger.log.info('userId will be injected');
});

configureLoggerContext(getterFn)

Globally defines a fallback context getter if none is set.

configureLoggerContext(() => ({ tenant: 'main', traceId: 'auto' }));

ContextualLogger

Provides a .log object with info, error, warn, and debug.

const logger = new ContextualLogger();
logger.log.info('message');

@WithLogger()

Injects this.log into any class. Works well with service or controller patterns.

@WithLogger()
class MyService {
  private log: LoggerType; // optional for type hint
  doSomething() {
    this.log.info('Message with context');
  }
}

With middleware

Here's how you can integrate logctx into an Express application to enable contextual logging based on headers, query parameters, cookies, and route parameters.

import { createContextLogger, ContextualLogger } from "logctx";
import express from "express";

const logger = new ContextualLogger();

// Middleware to initialize context logger
function middleware(
    req: express.Request,
    res: express.Response,
    next: express.NextFunction
) {
    createContextLogger(req, next, {
        headers: ['x-request-id', 'user-agent'],
        queries: ['queryParam'],
        cookies: ['sessionId'],
        params: ['param1', 'param2'],
    });
    next(); // Important: call next middleware after context setup
}

const app = express();
app.use(middleware);

// Sample route using contextual logger
app.get('/', (req, res) => {
    logger.log.info('Request received');
    res.send('Hello from Express with Contextual Logger!');
});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

💡 Use Cases

  • Log userId, tenantId, traceId across microservices
  • Contextual logging for HTTP, WebSocket, Kafka
  • Decorator-based logging without boilerplate
  • Enforce consistent metadata across logs
  • Switch easily between JSON and pretty logs using environment
  • Persist logs to disk for production systems
  • Use middleware with any NodeJS frameworks.

🧪 Example

import { runWithContext, ContextualLogger } from 'logctx';

const logger = new ContextualLogger();

runWithContext({ userId: 'U001' }, () => {
  logger.log.info('User event started'); // includes userId automatically
});

👨‍💻 Contributing

Pull requests, issues, and suggestions welcome!

git clone https://github.com/AjayKrP/logctx.git
npm install
npm run build