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

@plyaz/logger

v1.4.1

Published

Standardized logging infrastructure for Plyaz platform. Supports structured JSON logging, multiple transports, correlation IDs, and sensitive data redaction across all services.

Readme

@plyaz/logger

Standardized logging infrastructure for the Plyaz platform. Provides structured JSON logging, multiple transports, correlation IDs, and sensitive data redaction across all services - supporting frontend, backend, and blockchain environments.

Overview

The @plyaz/logger package provides standardized logging capabilities across all services within the Plyaz platform. It ensures consistent log formatting, severity levels, and transport mechanisms, facilitating easier log aggregation, analysis, and troubleshooting across our microservices backend architecture and modular frontend applications.

Note: This package is designed as a shared package that works across frontend and backend contexts, with platform-specific implementations where necessary. It integrates seamlessly with the @plyaz/* ecosystem of shared packages.

Features

  • Structured JSON Logging: Machine-readable log formats for easy parsing and analysis
  • Multiple Transports: Console, file, cloud, localStorage, and remote logging support
  • Cross-Platform Support: Works in Node.js, browsers, and blockchain environments
  • Correlation IDs: Automatic tracking of requests across service boundaries
  • Sensitive Data Redaction: Built-in PII and sensitive information masking
  • Framework Integration: Ready-to-use integrations for NestJS, React, and Next.js
  • Performance Optimized: Async logging, batching, and sampling capabilities
  • TypeScript Support: Full type safety and IntelliSense

Installation

pnpm add @plyaz/logger

Development

Prerequisites

  • Node.js >= 22.4.0
  • pnpm >= 8.0.0

Setup

# Clone the repository
git clone https://github.com/Plyaz-Official/logger.git
cd logger

# Install dependencies
pnpm install

# Start development (watch mode)
pnpm dev

Available Scripts

# Development
pnpm dev                # Start development with watch mode (alias: pnpm build:watch)
pnpm build:watch        # Watch files and rebuild on changes

# Building
pnpm build              # Full build (clean + JS + TypeScript declarations)
pnpm build:js           # Build JavaScript bundles with tsup
pnpm build:types        # Generate TypeScript declaration files
pnpm clean              # Remove dist directory

# Testing
pnpm test               # Run all tests once
pnpm test:watch         # Run tests in watch mode
pnpm test:coverage      # Run tests with coverage report
pnpm test:ui            # Open Vitest UI for interactive testing
pnpm test:ci            # Run tests in CI environment

# Code Quality
pnpm lint               # Check code with ESLint
pnpm lint:fix           # Auto-fix ESLint issues
pnpm format             # Format code with Prettier
pnpm format:check       # Check if code is formatted correctly
pnpm type:check         # Type check with TypeScript (no emit)

# Security & Auditing
pnpm audit              # Basic security audit
pnpm audit:moderate     # Check for moderate+ vulnerabilities
pnpm audit:high         # Check for high+ vulnerabilities
pnpm audit:critical     # Check only critical vulnerabilities
pnpm audit:fix          # Auto-fix vulnerabilities where possible
pnpm audit:enhanced     # Enhanced audit with audit-ci
pnpm security:check     # Full security check (moderate + audit-ci)

# Publishing
pnpm prepublishOnly     # Runs build, test, and lint before publishing

Package Structure

@plyaz/logger/
├── src/
│   ├── core/               # Platform-agnostic core
│   │   ├── logger.ts       # Core logger implementation
│   │   ├── levels.ts       # Log levels
│   │   └── types.ts        # Shared types
│   ├── browser/            # Browser-specific code
│   │   ├── transports/     # Browser transports
│   │   └── react/          # React integration
│   ├── node/               # Node.js specific code
│   │   ├── transports/     # Node transports
│   │   └── nestjs/         # NestJS integration
│   ├── blockchain/         # Blockchain specific code
│   ├── formatters/         # Log formatters
│   ├── utils/              # Helper utilities
│   └── index.ts            # Main entry with environment detection

Quick Start

Backend (NestJS)

Module Setup

import { Module } from '@nestjs/common';
import { LoggerModule } from '@plyaz/logger/node/nestjs';

@Module({
  imports: [
    LoggerModule.forRoot({
      service: 'user-service',
      version: '1.0.0',
      environment: process.env.NODE_ENV,
      level: process.env.LOG_LEVEL || 'info',
      transports: ['console', 'file'],
      redactFields: ['password', 'token', 'creditCard'],
      isGlobal: true
    })
  ]
})
export class AppModule {}

Using in a Service

import { Injectable } from '@nestjs/common';
import { Logger } from '@plyaz/logger';

@Injectable()
export class UserService {
  private readonly logger: Logger;

  constructor(logger: Logger) {
    this.logger = logger.createChild({ component: UserService.name });
  }

  async createUser(userData: CreateUserDto): Promise<User> {
    this.logger.debug('Creating new user', { email: userData.email });
    
    try {
      const user = await this.userRepository.create(userData);
      this.logger.info('User created successfully', {
        userId: user.id,
        verification: user.isVerified ? 'verified' : 'pending'
      });
      return user;
    } catch (error) {
      this.logger.error('Failed to create user', {
        error: error.message,
        stack: error.stack,
        email: userData.email
      });
      throw error;
    }
  }
}

With Request Interceptor

import { Controller, Get, Param, UseInterceptors } from '@nestjs/common';
import { Logger, LoggingInterceptor } from '@plyaz/logger/node/nestjs';

@Controller('users')
@UseInterceptors(LoggingInterceptor)  // Adds request logging with correlation IDs
export class UsersController {
  private readonly logger: Logger;

  constructor(logger: Logger, private readonly userService: UserService) {
    this.logger = logger.createChild({ component: UsersController.name });
  }

  @Get(':id')
  async getUserById(@Param('id') id: string) {
    return this.userService.getUserById(id);
  }
}

Frontend (React/Next.js)

App Router Setup

'use client';

import { LoggerProvider } from '@plyaz/logger/browser/react';
import { setupErrorLogging } from '@plyaz/logger/browser/react/nextjs';
import { ReactNode, useEffect } from 'react';

export function Providers({ children }: { children: ReactNode }) {
  useEffect(() => {
    setupErrorLogging();
  }, []);

  return (
    <LoggerProvider options={{
      service: 'web-client',
      environment: process.env.NODE_ENV,
      level: process.env.NODE_ENV === 'development' ? 'debug' : 'info',
      redactFields: ['password', 'token']
    }}>
      {children}
    </LoggerProvider>
  );
}

Using in Components

'use client';

import { useLogger } from '@plyaz/logger/browser/react';
import { useState } from 'react';

export function ProfileForm({ userId }: { userId: string }) {
  const logger = useLogger('ProfileForm');
  const [formData, setFormData] = useState({});

  const handleSubmit = async (e) => {
    e.preventDefault();
    logger.info('Submitting profile update', { userId });
    
    try {
      await updateProfile(userId, formData);
      logger.info('Profile updated successfully');
    } catch (error) {
      logger.error('Failed to update profile', { 
        error: error.message,
        userId
      });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
      <button type="submit">Save</button>
    </form>
  );
}

Next.js Middleware

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { withLogging } from '@plyaz/logger/browser/react/nextjs';

export function middleware(request: NextRequest) {
  const response = NextResponse.next();
  return response;
}

export default withLogging(middleware);

Blockchain Integration

import { Injectable } from '@nestjs/common';
import { BlockchainLogger } from '@plyaz/logger/blockchain';

@Injectable()
export class Web3Service {
  private readonly logger: BlockchainLogger;

  constructor() {
    this.logger = new BlockchainLogger({
      service: 'web3-service',
      environment: process.env.NODE_ENV
    });
  }

  async sendTransaction(to: string, amount: string) {
    try {
      const tx = await contract.methods.transfer(to, amount).send();
      
      this.logger.logTransaction(tx.hash, {
        from: tx.from,
        to,
        amount,
        contract: contractAddress
      });
      
      this.logger.logGasUsage(tx.hash, tx.gasUsed, tx.effectiveGasPrice);
      
      return tx.hash;
    } catch (error) {
      this.logger.error('Transaction failed', { error: error.message });
      throw error;
    }
  }
}

Log Structure

All logs follow a standardized JSON structure:

{
  "timestamp": "2025-03-25T10:23:42.315Z",
  "level": "info",
  "message": "User registration successful",
  "service": "user-service",
  "environment": "production",
  "correlationId": "c7d2fbe3-3a3a-4e1e-8e4d-12c98765d234",
  "requestId": "req-5c91e0b2-a6dc-487c-b5ec-2f79c4204def",
  "context": {
    "userId": "usr-123456",
    "action": "registration",
    "duration": 235
  },
  "labels": {
    "version": "1.0.0",
    "instance": "user-service-prod-7f84d9b68b-z92vn"
  }
}

Configuration

Full Configuration Options

{
  // Basic identification
  service: 'user-service',          // Service name
  version: '1.0.0',                 // Service version
  environment: 'production',        // Environment

  // Log level configuration
  level: 'info',                    // Default level
  levels: {                         // Environment-specific levels
    development: 'debug',
    test: 'debug',
    production: 'info'
  },

  // Transports configuration
  transports: ['console', 'file'],  // Enabled transports
  console: {                        // Console transport config
    pretty: true,                   // Pretty print in dev
    colors: true                    // Colorized output
  },
  file: {                           // File transport config
    path: 'logs/',
    filename: 'app-%DATE%.log',
    datePattern: 'YYYY-MM-DD',
    maxFiles: '14d'
  },

  // Browser-specific options
  browser: {
    remoteLogging: {                // Send logs to backend
      endpoint: '/api/logs',
      batchSize: 10,
      flushInterval: 5000           // ms
    },
    localStorage: {                 // Store logs in localStorage
      enabled: true,
      key: 'app_logs',
      maxEntries: 100
    }
  },

  // Security and redaction
  redactFields: ['password', 'token', 'creditCard'],
  redactionText: '[REDACTED]',

  // Correlation
  enableCorrelationId: true,
  correlationIdHeader: 'x-correlation-id',

  // Performance
  asyncLogging: true,
  logSampling: {
    debug: 0.1,                    // Sample 10% of debug logs
    info: 1.0                      // Log all info and above
  }
}

Transport Options

Node.js Transports

  • Console: Colored, formatted output for development
  • File: Rotating file logs with configurable retention
  • Cloud: AWS CloudWatch, Google Cloud Logging integration

Browser Transports

  • Console: Pretty-printed logs with formatting
  • Remote: Send logs to backend API endpoint
  • LocalStorage: Offline log storage for debugging

Security Features

Automatic Redaction

logger.info('User authentication', {
  email: '[email protected]',
  password: 'secret123',      // Automatically redacted
  token: 'Bearer abc123',     // Automatically redacted
  creditCard: '4111111111111111'  // Automatically redacted
});

Configurable Redaction Patterns

{
  redactFields: ['password', 'token', 'apiKey', 'secret'],
  redactionText: '[REDACTED]',
  customPatterns: [
    /Bearer\s+[^\s]+/gi,
    /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g  // Credit cards
  ]
}

Performance Features

Log Sampling

{
  logSampling: {
    debug: 0.1,    // Log only 10% of debug messages
    info: 1.0,     // Log all info messages
    warn: 1.0,
    error: 1.0
  }
}

Batching (Browser)

{
  browser: {
    remoteLogging: {
      batchSize: 10,        // Batch 10 logs together
      flushInterval: 5000,  // Send every 5 seconds
      maxRetries: 3
    }
  }
}

Best Practices

Log Levels

  • debug: Detailed information for debugging
  • info: General operational information
  • warn: Potential issues that don't cause failure
  • error: Errors that prevent operations from completing
  • fatal: Critical errors requiring immediate attention

Message Guidelines

// Good: Specific and actionable
logger.info('User registration completed', { userId, email, duration });

// Bad: Vague and unhelpful
logger.info('Something happened');

// Good: Includes context
logger.error('Database connection failed', { 
  host: dbHost, 
  error: error.message,
  retryCount 
});

// Bad: Missing context
logger.error('Error');

Performance Considerations

  1. Use appropriate log levels
  2. Avoid logging in tight loops
  3. Use sampling for high-volume debug logs
  4. Batch logs when possible (browser)
  5. Use child loggers for component context

Platform Architecture Context

The logger is a critical component of the Plyaz platform's shared package ecosystem:

Backend Architecture

  • Microservices: Each NestJS microservice uses the logger for service-specific logging contexts
  • API Gateway: Centralized logging point with correlation ID propagation
  • Event-Driven: Event correlation tracking across asynchronous service communication
  • Distributed Tracing: Correlation IDs enable request tracking across service boundaries

Frontend Architecture

  • Multiple Apps: Supports web app, admin panel, landing pages, and micro apps
  • React/Next.js: Deep integration with React Context and Next.js middleware
  • State Management: Logs state changes in Zustand stores
  • API Client: Tracks all API calls with React Query integration

Integration with Other Plyaz Packages

| Package | Integration | Purpose | |---------|------------|---------| | @plyaz/config | Configuration source | Reads LOG_LEVEL, SERVICE_NAME, environment settings | | @plyaz/monitoring | Data consumer | Logs feed into monitoring metrics and alerts | | @plyaz/events | Correlation | Event publishing includes logger correlation IDs | | @plyaz/errors | Error formatting | Structured error logging with stack traces | | @plyaz/auth | Context enrichment | Adds user/session context to logs | | @plyaz/api | Request tracking | Logs API calls, responses, and errors | | @plyaz/web3 | Transaction logging | Specialized blockchain transaction logging | | @plyaz/common | NestJS utilities | Provides logging interceptors and filters | | @plyaz/types | Type definitions | Shared LogEntry, LogLevel interfaces |

API Reference

Core Methods

  • createLogger(options): Create a new logger instance
  • logger.debug(message, context?): Log debug message
  • logger.info(message, context?): Log info message
  • logger.warn(message, context?): Log warning
  • logger.error(message, context?): Log error
  • logger.fatal(message, context?): Log fatal error
  • logger.createChild(context): Create child logger with context

React Hooks

  • useLogger(component): Get logger instance in React component
  • LoggerProvider: React context provider for logger

NestJS

  • LoggerModule.forRoot(options): Configure logger module
  • LoggingInterceptor: Request logging interceptor
  • @InjectLogger(): Inject logger into services

Blockchain

  • BlockchainLogger: Specialized blockchain logger
  • logTransaction(hash, details): Log transaction details
  • logGasUsage(hash, used, price): Log gas consumption

Migration Guide

From console.log

// Before
console.log('User logged in:', userId);
console.error('Error:', error);

// After
logger.info('User logged in', { userId });
logger.error('Operation failed', { error });

From Winston/Bunyan

// Before (Winston)
winston.log('info', 'User action', { user: userId });

// After
logger.info('User action', { userId });

Contributing

This package is part of the Plyaz platform. Please follow the contribution guidelines in the main repository.

Resources

License

ISC © Plyaz