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

@1984vc/otel-http-logger

v0.0.1

Published

A lightweight OpenTelemetry logger for Node.js, Bun, and browsers with zero dependencies

Readme

otel-http-logger

A lightweight OpenTelemetry logger for Node.js, Bun, and browsers with zero dependencies and support for async context propagation. Includes built-in support for HyperDX.

Features

  • Zero Dependencies: Works with vanilla JavaScript/Node.js/Bun
  • OpenTelemetry Compatible: Sends logs to any OTLP HTTP collector
  • Context Propagation: Uses AsyncLocalStorage for automatic logger context across async boundaries
  • TypeScript Support: Written in TypeScript with full type definitions
  • Compatible with many JS runtimes: NodeJS, Browser, Bun, Cloudflare(Miniflare), Deno

Installation

npm install @1984vc/otel-http-logger

Or with yarn:

yarn add @1984vc/otel-http-logger

Or with bun:

bun add @1984vc/otel-http-logger

Quick Start

const { initializeLogger, LogLevel } = require('otel-http-logger');

// Initialize a console-only logger (no OTLP)
const logger = initializeLogger({
  endpoint: '', // Empty endpoint means no OTLP logging
  headers: {},
  serviceName: 'my-service',
  environment: 'development'
});

// Log at different levels
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message');

// Log with additional attributes
logger.info('User logged in', {
  userId: '12345',
  loginTime: new Date().toISOString()
});

// Log errors with stack traces
try {
  throw new Error('Something went wrong');
} catch (error) {
  logger.error('An error occurred', error, {
    component: 'authentication'
  });
}

OTLP Logging

HyperDX Example

const { initializeLogger } = require('otel-http-logger');

// Get HyperDX API key from environment variable
const HYPERDX_API_KEY = process.env.HYPERDX_API_KEY;

// Initialize a logger with HyperDX configuration
const logger = initializeLogger({
  endpoint: 'https://in-otel.hyperdx.io/v1/logs',
  headers: {
    'Authorization': HYPERDX_API_KEY,
    'Content-Type': 'application/json'
  },
  serviceName: 'my-service',
  environment: 'production'
});

// Log as usual
logger.info('This will be sent to HyperDX');

// Important: Flush logs before your application exits
await logger.flush();

Context Propagation

The logger supports context propagation using AsyncLocalStorage, which allows you to create contextual loggers that are automatically available throughout your async call stack:

const { initializeLogger, createLogger } = require('otel-http-logger');

const logger = initializeLogger({
  endpoint: 'https://your-otlp-collector/v1/logs',
  headers: { 'Authorization': 'Bearer your-token' },
  serviceName: 'my-service',
  environment: 'production'
});

// Use withLogger to set the current logger in the async context
await logger.withLogger(async () => {
  // This function and all async functions called from it
  // will have access to the logger via createLogger
  
  await processRequest();
});

async function processRequest() {
  // Create a contextual logger using the current logger from async context
  const requestLogger = createLogger('request');
  
  requestLogger.info('Processing request');
  
  // Even in nested async functions, the logger is available
  await callDatabase();
}

async function callDatabase() {
  const dbLogger = createLogger('database');
  dbLogger.info('Executing query');
}

API Reference

initializeLogger(config)

Initializes a new logger with the provided configuration.

interface LoggerConfig {
  endpoint: string;        // OTLP HTTP collector endpoint URL
  headers: Record<string, string>; // Headers for OTLP HTTP collector
  serviceName: string;     // Service name for OTLP resource
  environment: string;     // Environment name (e.g., 'production', 'staging')
}

createLogger(context)

Creates a contextual logger using the current logger from the async context.

function createLogger(context: string): ContextLogger;

getCurrentLogger()

Gets the current logger from the async context.

function getCurrentLogger(): Logger;

Logger

The main logger class.

class Logger implements ContextLogger {
  constructor(config?: LoggerConfig, contextPrefix?: string);
  
  debug(message: string, attributes?: Record<string, any>): void;
  info(message: string, attributes?: Record<string, any>): void;
  warn(message: string, attributes?: Record<string, any>): void;
  error(message: string, error?: Error, attributes?: Record<string, any>): void;
  
  newContext(context: string): ContextLogger;
  
  async withLogger<T>(fn: () => T | Promise<T>): Promise<T>;
  
  async flush(): Promise<void>;
}

LogLevel

Enum for log levels.

enum LogLevel {
  DEBUG = 'DEBUG',
  INFO = 'INFO',
  WARN = 'WARN',
  ERROR = 'ERROR'
}

Examples

See the examples directory for more detailed examples:

To run the examples with HyperDX integration:

# Set your HyperDX API key
export HYPERDX_API_KEY=your_api_key_here

# Run the examples with Node.js
node examples/basic.js
node examples/context.js

# Or run with Bun
bun examples/basic.js
bun examples/context.js

License

MIT