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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@henry781/ts-logger

v0.1.1

Published

Simple Typescript logger, usefull for all typescript/javascript projects.

Downloads

2

Readme

ts-logger

Simple Typescript logger, usefull for all typescript/javascript projects.

Usage

Basic Example

Create your logger and use it (one logger with their own options).

import {LoggerLevel, LoggerOptions} from '@kirakishin/ts-logger';

const myloggerOptions:LoggerOptions = new LoggerOptions({
  level:LoggerLevel.DEBUG
});

export class FooClass {
  private logger: Logger;

  constructor() {
    this.logger = loggerService.getLogger(this, myloggerOptions);
    this.logger.debug('my debug');
  }
}

will produces :

[DEBUG] LOGGER{FooClass:4} my debug

Multiple logger Example

Create your loggers and use it with shared options. If you change an option as level, all classes that uses this shared options will have the same log level. Its useful if you want to manage log level per application module for example.

import {LoggerLevel, LoggerSharedOptions} from '@kirakishin/ts-logger';

const SharedLoggerOptions:LoggerSharedOptions = new LoggerSharedOptions({
  key: 'FooBarModule',
  level:LoggerLevel.DEBUG
});

export class FooClass {
  private logger: Logger;

  constructor() {
    this.logger = loggerService.getLogger(this, SharedLoggerOptions);
    this.logger.debug('my debug Foo');
  }
}

export class BarClass {
  private logger: Logger;

  constructor() {
    this.logger = loggerService.getLogger(this, SharedLoggerOptions);
    this.logger.debug('my debug Bar');
  }
}

will produces :

[DEBUG] LOGGER{FooBarModule.FooClass:4} my debug Foo
[DEBUG] LOGGER{FooBarModule.BarClass:4} my debug Bar

The two loggers has the same log level.

Logger and subLogger Example

Create your logger and a subLogger.

import {LoggerLevel, LoggerOptions} from "@kirakishin/ts-logger";

const LoggerOptions:LoggerOptions = new LoggerOptions({
  level:LoggerLevel.DEBUG
});

export class FooClass {
  private logger: Logger;

  constructor() {
    this.logger = loggerService.getLogger(this, LoggerOptions);
    this.logger.debug('my debug');
    let myFunc1 = () => {
      let logger = this.logger.subLogger('myFunc1');
      logger.debug('i am now in myFunc1');
    }

    let fooName = this.getFooName();
    let barName = this.getBarName();
  }

  getFooName() {
    let logger = this.logger.subLogger('getFooName');
    logger.debug('i am getFooName method');
    logger.debug('now i let it go away');
    return 'FooName';
  }
  
  getBarName() {
    let logger = this.logger.subLogger('getBarName');
    logger.debug('i am getBarName method');
    let myFunc2 = () => {
      let logger = logger.subLogger('myFunc2');
      logger.debug('i am now in myFunc2');
    }
    logger.debug('now i let it go away');
    return myFunc2();
  }
}

will produces :

[DEBUG] LOGGER{FooClass:4} my debug
[DEBUG] LOGGER{FooClass:4} [myFunc1] i am now in myFunc1
[DEBUG] LOGGER{FooClass:4} [getFooName] i am getFooName method
[DEBUG] LOGGER{FooClass:4} [getFooName] now i let it go away
[DEBUG] LOGGER{FooClass:4} [getBarName] i am getBarName method
[DEBUG] LOGGER{FooClass:4} [getBarName] now i let it go away
[DEBUG] LOGGER{FooClass:4} [getBarName.myFunc2] i am now in myFunc2

Options

Available Options of the LoggerService :

  • level : see {@link LoggerLevel}
  • tokens : some context data for each log (by default, this is the datetime, the level, and the caller: [datetimeToken, levelToken, callerToken])
  • global : export the LoggerService instance into globalObject[globalKey].
    • If enabled, it permit to access to loggers via globalObject[globalKey].loggers()
  • globalKey : key used to store the LoggerService into globalObject[globalKey]
  • globalObject : global object in which we store the loggerService (can be window on front side, or another custom object)
  • store : store options of LoggerService into LocalStorage. only level, localLogging, remoteLogging are loaded from LocalStorage
  • storeKey : key used to store the LoggerService options into LocalStorage
  • localLogging : log into client console ?
  • remoteLogging : cache log and send it to the server [TODO]
  • cacheLineNumber : number of cached line before send it to the server
  • loggerInfo : display logger info used for the log line
  • loggerInfoMode : logger info is displayed as a string (same as sent to server) or displayed as object on which you can click to see corresponding logger
  • logger : object with log methods definition (abstract layer to use winston or another layer)

Log customization

Use case

We have logs like :

[DEBUG] LOGGER{DesignService:4} [get] getting object code <DEMO>
[DEBUG] LOGGER{RightsService:4} [preCheckSuperAdmin] checking user rights...
[DEBUG] LOGGER{RightsService:4} [preCheckSuperAdmin] bypass rights is enabled for user

To fully track user actions, we need something like :

[DEBUG] [user1] [request0001] {DesignService:4} [get] getting object code <DEMO>
[DEBUG] [user1] [request0001] [preCheckSuperAdmin] checking user rights...
[DEBUG] [user1] [request0001] [preCheckSuperAdmin] bypass rights is enabled for user

Implementation

You can use the token concept, each part of a log message is a token. The tokens are configurable in the loggerServiceOptions.

By default, tokens datetime, level, caller and subLogger are enabled.

We provide a list of tokens, there are default tokens :

  • datetime
  • caller
  • subLogger
  • level

User can create his own tokens, for example :

  • requestId
  • user ...
export const LoggerServiceOptions: LoggerServiceOptions = {
  level: LoggerLevel.ERROR,
  tokens: [
    levelToken,
    {
      name:'login',
      value: () => this.logContext.get('login'),
      format: 'brackets'
    },
    {
      name:'requestId',
      value: () => this.logContext.get('requestId'),
      format: 'brackets'
    },
    callerToken
  ],
  global: true,
  globalKey: 'logger',
  store: false,
...

Log in JSON

Use case

For analysis we want to send logs to an elastic search instance. Logs should be in JSON.

Implementation

To enable json logging, just set json to true in options :

export const LoggerServiceOptions: LoggerServiceOptions = {
  ...
  json: true
...

Example of json log entry :

{
	level : 'info',
	login : 'login001', # custom token
	caller : 'access',
	content : {
		url : '/api/favicon-16x16.png',
		method : 'GET',
		login : undefined,
		ip : '::ffff:127.0.0.1',
		status : '304',
		responseTime : '1'
	}
}