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

@fortify-ts/logging

v0.2.0

Published

Structured logging utilities for fortify-ts resilience patterns

Readme

@fortify-ts/logging

Structured logging utilities for the Fortify-TS resilience library.

Installation

npm install @fortify-ts/logging
# or
pnpm add @fortify-ts/logging

Features

  • Console Logger: Browser-friendly logger with timestamps and JSON output
  • Pino Adapter: Integrate with pino for production logging
  • Resilience Logger: Pre-built methods for resilience pattern events
  • Log Redaction: Automatic redaction of sensitive data
  • Child Loggers: Create contextual loggers with bound metadata

Usage

Console Logger

import { createConsoleLogger } from '@fortify-ts/logging';

const logger = createConsoleLogger({
  level: 'info',      // Minimum log level
  timestamps: true,   // Include ISO timestamps
  json: false,        // Output as JSON
  prefix: 'myapp',    // Custom prefix
});

logger.info('User logged in', { userId: '123' });
// [2024-01-15T10:30:00.000Z] [myapp] [INFO] User logged in {"userId":"123"}

Pino Integration

import pino from 'pino';
import { createPinoLogger } from '@fortify-ts/logging';

const logger = createPinoLogger(pino());

logger.info('Hello', { key: 'value' });

Resilience Logger

import { createConsoleLogger, createResilienceLogger } from '@fortify-ts/logging';

const baseLogger = createConsoleLogger({ level: 'info' });
const logger = createResilienceLogger(baseLogger);

// Pre-built methods for resilience events
logger.circuitBreakerStateChange('api-breaker', 'closed', 'open');
logger.retryAttempt('fetch-data', 2, 5, new Error('Connection failed'));
logger.rateLimitExceeded('api-limiter', 'user-123');
logger.timeoutExceeded('fetch-data', 5000);
logger.bulkheadRejection('api-bulkhead', 10, 50);
logger.fallbackActivated('get-user', new Error('Primary failed'));

Log Redaction

Automatically redact sensitive data from logs:

import { createConsoleLogger, withDefaultRedaction } from '@fortify-ts/logging';

const baseLogger = createConsoleLogger({ level: 'info' });
const logger = withDefaultRedaction(baseLogger);

// Sensitive keys are automatically redacted
logger.info('User authenticated', {
  username: 'john',
  password: 'secret123',    // Will be '[REDACTED]'
  token: 'jwt-token',       // Will be '[REDACTED]'
  apiKey: 'key-123',        // Will be '[REDACTED]'
});

Custom Redaction

import {
  createConsoleLogger,
  withRedaction,
  createRedactor,
} from '@fortify-ts/logging';

// Create custom redactor
const redactor = createRedactor({
  keys: ['customSecret', 'internalId'],
  patterns: [/^x-internal-/i],
  replacement: '****',
  deep: true,  // Redact nested objects
});

const baseLogger = createConsoleLogger({ level: 'info' });
const logger = withRedaction(baseLogger, redactor);

logger.info('Request', {
  customSecret: 'hidden',      // '****'
  'x-internal-token': 'xyz',   // '****'
  publicData: 'visible',       // Unchanged
});

Extending Default Redaction

import { createConsoleLogger, withDefaultRedaction } from '@fortify-ts/logging';

const baseLogger = createConsoleLogger({ level: 'info' });

// Add custom keys/patterns to default redaction
const logger = withDefaultRedaction(
  baseLogger,
  ['myCustomSecret'],           // Additional keys
  [/^x-my-app-/i]              // Additional patterns
);

Manual Context Redaction

import { redactContext, createDefaultRedactor } from '@fortify-ts/logging';

// One-time redaction
const sanitized = redactContext(
  { password: 'secret', name: 'john' },
  { keys: ['password'] }
);

// Reusable redactor
const redact = createDefaultRedactor();
const safe = redact({ apiKey: 'key123', data: 'public' });

Child Loggers

const logger = createConsoleLogger({ level: 'info' });

// Create child with bound context
const requestLogger = logger.child({ requestId: 'abc-123' });

requestLogger.info('Processing request');
// All logs include requestId automatically

Noop Logger

import { noopLogger } from '@fortify-ts/logging';

// Disable logging (useful for tests)
const circuitBreaker = new CircuitBreaker({
  logger: noopLogger,
});

Configuration Reference

Console Logger

| Option | Type | Default | Description | |--------|------|---------|-------------| | level | string | 'info' | Minimum log level | | timestamps | boolean | true | Include timestamps | | json | boolean | false | Output as JSON | | prefix | string | '' | Log message prefix |

Redaction Config

| Option | Type | Default | Description | |--------|------|---------|-------------| | keys | string[] | required | Keys to redact | | patterns | RegExp[] | [] | Patterns to match | | replacement | string | '[REDACTED]' | Replacement value | | deep | boolean | true | Redact nested objects |

Default Sensitive Keys

The following keys are redacted by default:

  • password, secret, token
  • apiKey, api_key, apikey
  • authorization, auth
  • credential, credentials
  • privateKey, private_key
  • accessToken, access_token
  • refreshToken, refresh_token
  • sessionId, session_id
  • cookie, ssn, cvv, pin
  • Credit card related fields

API Reference

Logger Factories

| Function | Description | |----------|-------------| | createConsoleLogger(config?) | Create console logger | | createPinoLogger(pino) | Wrap pino instance | | createResilienceLogger(logger) | Add resilience methods | | createNoopLogger() | Create silent logger |

Redaction Functions

| Function | Description | |----------|-------------| | withRedaction(logger, redactor) | Wrap logger with redaction | | withDefaultRedaction(logger, keys?, patterns?) | Wrap with default redaction | | redactContext(context, config) | Redact a single context object | | createRedactor(config) | Create reusable redactor | | createDefaultRedactor(keys?, patterns?) | Create default redactor |

License

MIT