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

@chiper-inc/logging-chiper

v2.4.3

Published

just a little module to log

Readme

Logging Chiper

Table of Contents

Description

This simple module offers a way to use some functionalities from the logging-chiper.

Motivation

As company we want to standardize the way we log our application, so that's we wrote this module to make it easier to log our application.

Requirements

  1. Node.js 20.19.0 or higher.
  2. GOOGLE_APPLICATION_CREDENTIALS defined with the file path as environment variable.

Usage

Install

npm i logging-chiper -S -E

OR

yarn add logging-chiper -S -E

Initialization

To initialize the logger you need call the init function at start point of your application, using the following parameters:

// import the class from the library
import { Logger } from "logging-chiper";

Logger.init({
  projectId: "your-project-id",
  service: "your-service-name",
  version: "0.0.1",
});

Parameters

As we want to standardize the way we log our application, so we defined a base structure as input parameters to accomplish this:

// Log method
Logger.getInstance().log({
  stt: "my-stt", // name of the stt owner
  context: "my-context", // name of the class or file (optional)
  functionName: "my-function", // name of the function (optional)
  message: "my-message", // message to log
  data: {
    // data to log (optional)
    storeId: "" + 123456,
    responseCode: "" + 200,
    testField: "test",
    extraField: "extra",
  },
});

// Warn method
Logger.getInstance().warn({
  stt: "my-stt", // name of the stt owner
  context: "my-context", // name of the class or file (optional)
  functionName: "my-function", // name of the function (optional)
  message: "my-message", // message to log
  data: {
    // data to log (optional)
    storeId: "" + 123456,
    responseCode: "" + 200,
    testField: "test",
    extraField: "extra",
  },
});

// Error method
Logger.getInstance().error({
  stt: "my-stt", // name of the stt owner
  context: "my-context", // name of the class or file (optional)
  functionName: "my-function", // name of the function (optional)
  message: "my-message", // message to log
  error, // the exception to log that just occurred
  data: {
    // data to log (optional)
    storeId: "" + 123456,
    responseCode: "" + 200,
    testField: "test",
    extraField: "extra",
  },
});

As you can see, all the methods follows almost the same structure, but when you want to log an error, you need to pass the error as parameter.

Examples

Simple Log

import { Logger } from 'logging-chiper';

const bootstrap = () => {
  Logger.init({
    projectId: 'your-project-id',
    service: 'your-service-name',
    version: '0.0.1',
  });

  Logger.getInstance().log({
    stt: 'solutions',
    context: 'main.ts',
    functionName: 'bootstrap',
    message: 'this is a log message...',
  });
};
}

bootstrap();

Log Requests

With Express

import { createMiddleware } from "logging-chiper";
import express, { Request, Response } from "express";
import { AddressInfo } from "net";
import { LoggingWinston } from "@google-cloud/logging-winston";
import { transports } from "winston";

const app = express();

createMiddleware([
  // creates the middleware
  new transports.Console(), // logs to console
  new LoggingWinston({
    // logs to gpc
    projectId: "chiper-development",
    logName: "myapp",
  }),
]).then((mw) => {
  app.use(mw); // setup middler into express

  app.get("/info", (req: Request, res: Response) => {
    (req as any).log.info("get Hello World!"); // Using log from request
    res.status(200).send("Hello World!");
  });

  const server = app.listen(3000, () => {
    const address = server.address() as AddressInfo;
    mw.logger.info(`running at http://${address.address}:${address.port}`); // use the logger from mw.
  });
});

With NestJS

  • You need the create an interceptor for logging:

app.logmiddleware.ts

import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
import { createMiddleware } from "logging-chiper";
import { LoggingWinston } from "@google-cloud/logging-winston";
import { transports } from "winston";

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  async use(req: Request, res: Response, next: NextFunction) {
    const mw = await createMiddleware([
      // creates the middleware
      new transports.Console(), // logs to console
      new LoggingWinston({
        // logs to gpc
        projectId: "chiper-development",
        logName: "myapp",
      }),
    ]);
    mw(req, res, next);
  }
}
  • And then configure in the module:

app.module.ts

import { MiddlewareConsumer, Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { LoggerMiddleware } from "./app.loggermiddleware";

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes("*");
  }
}

Advance Logging Options

LoggingProvider Class

The LoggingProvider class provides a more structured and configurable way to handle logging with predefined context and logging levels. This is particularly useful when you want to create multiple logger instances for different parts of your application with specific configurations.

Motivation

The LoggingProvider class was created to:

  • Provide a more object-oriented approach to logging
  • Allow configuration of logging levels per provider instance
  • Enable automatic context and STT (service team) management
  • Reduce boilerplate code when logging from specific classes or modules

Requirements

  • Logger must be initialized using Logger.init() before using LoggingProvider
  • Same requirements as the base Logger class

Usage

Basic Setup

import { LoggingProvider, Logger } from "logging-chiper";

// Initialize the base logger first
Logger.init({
  projectId: "your-project-id",
  service: "your-service-name",
  version: "0.0.1",
});

// Create a LoggingProvider instance
const provider = new LoggingProvider(
  {
    stt: "my-service-team", // Required: service team name
    levels: LoggingProvider.FULL, // Optional: logging levels (defaults to NONE)
  },
  {
    context: "MyClass", // Optional: context name (defaults to 'LoggingProvider')
    levels: LoggingProvider.LOG | LoggingProvider.ERROR, // Optional: override levels
  }
);

Logging Levels

The LoggingProvider supports different logging levels that can be combined:

// Available logging levels
LoggingProvider.NONE; // 0 - No logging
LoggingProvider.LOG; // 4 - Info level logging
LoggingProvider.WARN; // 2 - Warning level logging
LoggingProvider.ERROR; // 1 - Error level logging
LoggingProvider.FULL; // 7 - All levels (LOG | WARN | ERROR)

Logging Methods

// Log info messages
provider.log({
  functionName: "processData",
  message: "Processing user data",
  data: { userId: 123, action: "update" },
});

// Log warnings
provider.warn({
  functionName: "validateInput",
  message: "Invalid input received",
  data: { input: "invalid-value" },
});

// Log errors
provider.error({
  functionName: "saveData",
  message: "Failed to save data to database",
  error: new Error("Connection timeout"),
  data: { recordId: 456 },
});

Examples

Example 1: Service Class with LoggingProvider

import { LoggingProvider, Logger } from "logging-chiper";

class UserService {
  private logger: LoggingProvider;

  constructor() {
    // Create a LoggingProvider for this service
    this.logger = new LoggingProvider(
      {
        stt: "user-management",
        levels: LoggingProvider.FULL,
      },
      {
        context: "UserService",
      }
    );
  }

  async createUser(userData: any) {
    const functionName = this.createUser.name;

    this.logger.log({
      functionName,
      message: "Starting user creation process",
      data: { email: userData.email },
    });

    try {
      // User creation logic here
      const user = await this.saveUser(userData);

      this.logger.log({
        functionName,
        message: "User created successfully",
        data: { userId: user.id },
      });

      return user;
    } catch (error) {
      this.logger.error({
        functionName,
        message: "Failed to create user",
        error,
        data: { email: userData.email },
      });
      throw error;
    }
  }

  private async saveUser(userData: any) {
    // Implementation here
  }
}

Example 2: Multiple Providers with Different Levels

import { LoggingProvider, Logger } from "logging-chiper";

// Initialize base logger
Logger.init({
  projectId: "my-project",
  service: "api-gateway",
  version: "1.0.0",
});

// Create providers for different components
const apiLogger = new LoggingProvider(
  { stt: "api-team", levels: LoggingProvider.FULL },
  { context: "ApiController" }
);

const dbLogger = new LoggingProvider(
  {
    stt: "database-team",
    levels: LoggingProvider.ERROR | LoggingProvider.WARN,
  },
  { context: "DatabaseService" }
);

const cacheLogger = new LoggingProvider(
  { stt: "infrastructure-team", levels: LoggingProvider.LOG },
  { context: "CacheService" }
);

// Usage in different parts of your application
apiLogger.log({
  functionName: "handleRequest",
  message: "Processing API request",
  data: { endpoint: "/users", method: "GET" },
});

dbLogger.warn({
  functionName: "connect",
  message: "Database connection slow",
  data: { responseTime: 5000 },
});

cacheLogger.log({
  functionName: "get",
  message: "Cache hit",
  data: { key: "user:123" },
});

Example 3: Conditional Logging

import { LoggingProvider, Logger } from "logging-chiper";

class PaymentProcessor {
  private logger: LoggingProvider;

  constructor(enableDebugLogging: boolean = false) {
    // Enable different logging levels based on configuration
    const levels = enableDebugLogging
      ? LoggingProvider.FULL
      : LoggingProvider.ERROR | LoggingProvider.WARN;

    this.logger = new LoggingProvider(
      { stt: "payments", levels },
      { context: "PaymentProcessor" }
    );
  }

  async processPayment(paymentData: any) {
    const functionName = this.processPayment.name;
    // This will only log if LOG level is enabled
    this.logger.log({
      functionName,
      message: "Payment processing started",
      data: { amount: paymentData.amount, currency: paymentData.currency },
    });

    try {
      // Payment processing logic
      const result = await this.chargeCard(paymentData);

      // This will only log if LOG level is enabled
      this.logger.log({
        functionName,
        message: "Payment processed successfully",
        data: { transactionId: result.id },
      });

      return result;
    } catch (error) {
      // This will always log if ERROR level is enabled
      this.logger.error({
        functionName,
        message: "Payment processing failed",
        error,
        data: { amount: paymentData.amount },
      });
      throw error;
    }
  }

  private async chargeCard(paymentData: any) {
    // Implementation here
  }
}

Benefits of Using LoggingProvider

  1. Automatic Context Management: The provider automatically includes the STT and context in all log entries
  2. Configurable Logging Levels: Control what gets logged per provider instance
  3. Reduced Boilerplate: No need to repeat STT and context in every log call
  4. Better Organization: Different parts of your application can have their own logging configuration
  5. Performance: Logging levels allow you to disable certain log types in production
  6. Consistency: Ensures all logs from a provider follow the same structure