Git Product home page Git Product logo

nest-winston's Introduction

Nest Logo

nest-winston

NPM version NPM downloads GitHub commit activity

GitHub last commit GitHub Workflow Status GitHub issues GitHub pull requests

A Nest module wrapper for winston logger.

Table of Contents

Installation

npm install --save nest-winston winston

Having troubles configuring nest-winston? Clone this repository and cd in a sample:

cd sample/quick-start
npm install
npm run start:dev

If you want to upgrade to a major or minor version, have a look at the upgrade section.

Quick start

Import WinstonModule into the root AppModule and use the forRoot() method to configure it. This method accepts the same options object as createLogger() function from the winston package:

import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';

@Module({
  imports: [
    WinstonModule.forRoot({
      // options
    }),
  ],
})
export class AppModule {}

Afterward, the winston instance will be available to inject across entire project (and in your feature modules, being WinstonModule a global one) using the WINSTON_MODULE_PROVIDER injection token:

import { Controller, Inject } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';

@Controller('cats')
export class CatsController {
  constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) { }
}

Async configuration

Caveats: because the way Nest works, you can't inject dependencies exported from the root module itself (using exports). If you use forRootAsync() and need to inject a service, that service must be either imported using the imports options or exported from a global module.

Maybe you need to asynchronously pass your module options, for example when you need a configuration service. In such case, use the forRootAsync() method, returning an options object from the useFactory method:

import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';

@Module({
  imports: [
    WinstonModule.forRootAsync({
      useFactory: () => ({
        // options
      }),
      inject: [],
    }),
  ],
})
export class AppModule {}

The factory might be async, can inject dependencies with inject option and import other modules using the imports option.

Alternatively, you can use the useClass syntax:

WinstonModule.forRootAsync({
  useClass: WinstonConfigService,
})

With the above code, Nest will create a new instance of WinstonConfigService and its method createWinstonModuleOptions will be called in order to provide the module options.

Replacing the Nest logger

This module also provides the WinstonLogger class (custom implementation of the LoggerService interface) to be used by Nest for system logging. This will ensure consistent behavior and formatting across both Nest system logging and your application event/message logging.

Change your main.ts as shown below:

import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
  await app.listen(3000);
}
bootstrap();

Then inject the logger using the WINSTON_MODULE_NEST_PROVIDER token and the LoggerService typing:

import { Controller, Inject, LoggerService } from '@nestjs/common';
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';

@Controller('cats')
export class CatsController {
  constructor(@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService) { }
}

Under the hood, the WinstonLogger class uses the configured winston logger instance (through forRoot or forRootAsync), forwarding all calls to it.

Replacing the Nest logger (also for bootstrapping)

Important: by doing this, you give up the dependency injection, meaning that forRoot and forRootAsync are not needed and shouldn't be used. Remove them from your main module.

Using the dependency injection has one minor drawback. Nest has to bootstrap the application first (instantiating modules and providers, injecting dependencies, etc.) and during this process the instance of WinstonLogger is not yet available, which means that Nest falls back to the internal logger.

One solution is to create the logger outside of the application lifecycle, using the createLogger function, and pass it to NestFactory.create. Nest will then wrap our winston logger (the same instance returned by the createLogger method) into the Logger class, forwarding all calls to it:

import { WinstonModule } from 'nest-winston';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: WinstonModule.createLogger({
      // options (same as WinstonModule.forRoot() options)
    })
  });
  await app.listen(3000);
}
bootstrap();

An alternative is to provide directly an instance of Winston in the options. This allows you to keep a reference to the instance and interact with it.

import { createLogger } from 'winston';
import { WinstonModule } from 'nest-winston';

async function bootstrap() {
  // createLogger of Winston
  const instance = createLogger({
    // options of Winston
  });
  const app = await NestFactory.create(AppModule, {
    logger: WinstonModule.createLogger({
      instance,
    }),
  });
  await app.listen(3000);
}
bootstrap();

The usage afterwards for both solutions is the same. First, change your main module to provide the Logger service:

import { Logger, Module } from '@nestjs/common';

@Module({
  providers: [Logger],
})
export class AppModule {}

Then inject the logger simply by type hinting it with Logger from @nestjs/common:

import { Controller, Logger } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  constructor(private readonly logger: Logger) {}
}

Alternative syntax using the LoggerService typing and the @Inject decorator:

import { Controller, Inject, Logger, LoggerService } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  constructor(@Inject(Logger) private readonly logger: LoggerService) {}
}

Injection and usage summary

Here is a summary of the three techniques explained above:

Injection token Typing Module config Usage
WINSTON_MODULE_PROVIDER Logger from winston Yes + Your application/message logging
WINSTON_MODULE_NEST_PROVIDER LoggerService from @nestjs/common Yes + Your application/message logging
+ Nest logger
none Logger from @nestjs/common No + Your application/message logging
+ Nest logger
+ Application bootstrapping

Utilities

The module also provides a custom Nest-like special formatter for console transports named nestLike. Supported options:

  • colors: enable console colors, defaults to true, unless process.env.NO_COLOR is set (same behaviour of Nest > 7.x)
  • prettyPrint: pretty format log metadata, defaults to true
import { Module } from '@nestjs/common';
import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-winston';
import * as winston from 'winston';

@Module({
  imports: [
    WinstonModule.forRoot({
      transports: [
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp(),
            winston.format.ms(),
            nestWinstonModuleUtilities.format.nestLike('MyApp', {
              colors: true,
              prettyPrint: true,
            }),
          ),
        }),
        // other transports...
      ],
      // other options
    }),
  ],
})
export class AppModule {}

Logger methods

Note: the logger instance has different logger methods, and each takes different arguments. To make sure the logger is being formatted the same way across the board take note of the following:

debug(message: any, context?: string)
log(message: any, context?: string)
error(message: any, stack?: string, context?: string)
fatal(message: any, stack?: string, context?: string)
verbose(message: any, context?: string)
warn(message: any, context?: string)

Example:

import { Controller, Get, Logger } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    private readonly logger: Logger,
  ) {}

  @Get()
  getHello(): string {
    this.logger.log('Calling getHello()', AppController.name);
    this.logger.debug('Calling getHello()', AppController.name);
    this.logger.verbose('Calling getHello()', AppController.name);
    this.logger.warn('Calling getHello()', AppController.name);

    try {
      throw new Error()
    } catch (e) {
      this.logger.error('Calling getHello()', e.stack, AppController.name);
    }

    return this.appService.getHello();
  }
}

Upgrade

Some notes about upgrading to a major or minor version.

1.6.x to 1.7

  • The exported type NestLikeConsoleFormatOptions has slightly changed: prettyPrint is now optional and colors has been added.
  • The nestLike formatter has the new colors option: if not provided, colors will be used according to Nest "approach" (disabled if env variable process.env.NO_COLOR is defined). Before output was always colorized.

Contributing

All types of contributions are encouraged and valued. See the Contributing guidelines, the community looks forward to your contributions!

Contributors list

License

This project is released under the under terms of the ISC License.

nest-winston's People

Contributors

adrianmxb avatar angeloanan avatar ankit-noba avatar cchanche avatar chrisipk avatar danijelpredojevic avatar devvspaces avatar faithfulojebiyi avatar github-actions[bot] avatar gremo avatar guillaumedeconinck avatar ibrcko avatar j3bb9z avatar jbpin avatar jdg- avatar kadrian avatar kierans avatar kiriancaumes avatar lwhiteley avatar mizozobu avatar nemanja-mudrinic avatar piranit avatar renovate-bot avatar renovate[bot] avatar sezanzeb avatar tmkx avatar trejgun avatar viceice avatar vorotech avatar yardz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nest-winston's Issues

Still unable to inject config

I am using the new imports declaration but still unable to inject Config (or environment) variables, they are undefined.

Below is my main module:

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    WinstonModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        level: 'info',
        format: winston.format.combine(
          winston.format.timestamp(),
          winston.format.splat(),
          winston.format.json()
        ),
        transports: [
          new winston.transports.Console({
            level: configService.get<string>('LOG_LEVEL'),
          }),
        ],
    }),
    inject: [ConfigService],
  }),
  FooModule
  ],
  controllers: [FooController],
  providers: [FooService],
})
export class AppModule {}

The WinstonModule declaration above is identical to my SequelizeModule below (which works):

    SequelizeModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
      dialect: 'mssql',
      dialectOptions: {
        options: {
          encrypt: true
        }
      },
      host: configService.get<string>('DATABASE_HOST'),
      port: configService.get<number>('DATABASE_PORT'),
      username: configService.get<string>('DATABASE_USER'),
      password: configService.get<string>('DATABASE_PASSWORD'),
      database: 'CatFacts',
      models: [Fact, Animal, FactAnimal],
    }),
    inject: [ConfigService]
  }),

Best approach for unit testing modules

Hi,

I have recently started using this package. As I run my unit tests all tests failed that are injecting the logger.

Nest can't resolve dependencies of the [SERVICE] (?, ANOTHER_SERVICE). Please make sure that the argument NestWinston at index [0] is available in the RootTestModule context.

I'm using the Quick start example for implementing nest-winston.
For testing I'm using the provided way by the nestjs docs.

Could anyone provide an example how to mock this package for testing?

Using the same instance for both bootstrap and whole project logging.

Maybe I didn't understand the docs fully, but it seems to me as thought we use two different logger instances for across the whole project logging, e.g.

import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';

@Module({
  imports: [
    WinstonModule.forRoot({
      // options
    }),
  ],
})
export class AppModule {}

and for logging during bootstrap, e.g.

import { WinstonModule } from 'nest-winston';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: WinstonModule.createLogger({
      // options (same as WinstonModule.forRoot() options)
    })
  });
}
bootstrap();

For across the project logging we use whatever WinstonModule.forRoot returns, and for logging during the bootstrap we use whatever WinstonModule.createLogger returns. So it's like using two different loggers, or at least two different instances.

If I, let's say, want to move the logic associated with creating a logger to another file, so then I could import it. My logger file would look like this.

export const bootstrapLogger = WinstonModule.createLogger(options);
export const projectLogger = WinstonModule.forRoot(options); 

Is there any way to "combine" bootstrapLogger and projectLogger into just one instance?

can i get a full example of how to implement and log?

I am using forRoot method and injecting using @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger. however when i do this.logger.log('some message') i get an error

TypeError: Cannot create property 'Symbol(level)'

using transaport.console and transport.file

[FeatureRequest] Child loggers creation with use of forFeature

Hello,

I wanted to be able to use "filename/moduleName" in my logging. To do this it would be nice to use child logger functionality of winston. Currently I use it as follows:
export` class Features { constructor( @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger ) { this.logger = logger.child({ module: 'Features'}); } }

This way all logs in this "provider" will be marked with moduleName without need to pass it in each query. Much nicer way would be to use forFeature method on Dynamic Module which would create a child instance for each module.

Using as Main logger: fails for unit tests: RootTestModule

I followed the directions to use this as the main logger, and I am importing the Logger and LoggerService per the readme in a class that a unit test utilizes. Just running the app, things work fine, however with I npm run test I get this

   Nest can't resolve dependencies of the ApiTokenService (ConfigService, HttpService, ?). Please make sure that the argument Logger at index [2] is available in the RootTestModule context.

    Potential solutions:
    - If Logger is a provider, is it part of the current RootTestModule?
    - If Logger is exported from a separate @Module, is that module imported within RootTestModule?
      @Module({
        imports: [ /* the Module containing Logger */ ]
      })

There is no info function in WinstonLogger class

I'm surprised that nest-winton doesn't provide info function, which is used in winston document frequently. Furthermore, log function sticks with info level. It's very confused and wastes a lot of time when moving from winston to nest-winston. Why don't we implement info and log function like the original library? Can I work on PR to implement it?

[Release Request]

Iโ€™ve been waiting for WinstonLogger to be exported. Looks like itโ€™s been done already. Can we get a new version released?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/contributors.yaml
  • wow-actions/contributors-list v1
.github/workflows/slate.yaml
  • actions/stale v8
.github/workflows/test.yaml
  • actions/checkout v4
  • actions/setup-node v4
.github/workflows/toc.yaml
  • technote-space/toc-generator v4
npm
package.json
  • fast-safe-stringify ^2.1.1
  • @nestjs/common 10.3.8
  • @nestjs/core 10.3.8
  • @nestjs/platform-express 10.3.8
  • @nestjs/testing 10.3.8
  • @types/jest 29.5.12
  • @typescript-eslint/eslint-plugin 6.21.0
  • @typescript-eslint/parser 6.21.0
  • eslint 8.57.0
  • jest 29.7.0
  • reflect-metadata 0.2.2
  • rimraf 4.4.1
  • rxjs 7.8.1
  • source-map-support 0.5.21
  • ts-jest 29.1.2
  • ts-node 10.9.2
  • typescript 4.9.5
  • winston 3.13.0
  • @nestjs/common ^5.0.0 || ^6.6.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
  • winston ^3.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

Can not record trace message when use as the main Nest logger

As the document states, we can replace the system logger with Winston logger like this:

import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
}
bootstrap();

However, when Nest catches an exception, the trace message is missing in log file. I think it's because Winston logger instance doesn't conform Nest LoggerService.

As a workaround, we should use logger instance return from WinstonModule.createLogger.

Nest can't resolve dependencies 'Logger' provider

Many thanks for module, I have added to my personal project, following readme, everything is fine for me until apply NestWinston as default (also for bootstrapping) I cannot start project.

Please help me to point out my mistake, may I misunderstanding for

This works because Nest Logger wraps our winston logger (the same instance returned by the createLogger method) and will forward all calls to it.

Details of log is showing like this:

Nest can't resolve dependencies of the UserService (?, HashService, UserRepository). Please make sure that the argument Logger at index [0] is available in the Us
erModule context.

Potential solutions:
- If Logger is a provider, is it part of the current UserModule?
- If Logger is exported from a separate @Module, is that module imported within UserModule?

Here is my main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: WinstonModule.createLogger({
      format: winston.format.json(),
      defaultMeta: { service: 'bootstrap' },
      transports: [
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp(),
            utilities.format.nestLike(),
          ),
        }),
        new winston.transports.File({
          filename: __dirname + '/log/error.log',
          level: 'error',
        }), // - Write all logs with level `error` and below to `error.log`
        new winston.transports.File({
          filename: __dirname + '/log/combined.log',
        }),
        // - Write all logs with level `info` and below to `combined.log`
      ],
    }),
    cors: true,
  });

  const configService = app.get(ConfigService);

  await app.listen(configService.get<number>('port'));
}
bootstrap();

My app.module.ts file

@Module({
  providers: [Logger],
})
export class AppModule {}

My user.service.ts file:

@Injectable()
export class UserService {
  constructor(
    @Inject(Logger)
    private readonly logger: LoggerService,
    private readonly hashService: HashService,
    private readonly userRepo: UserRepository,
  ) {}
}

Using nestLike formatter throws error when tries to log a circular object structure

I use nest-winston for l logging in my NestJS application. I am using a third-party lib to handle some business logic and in some cases, it throws a circular object structure error.

When this happens, I get the following error:

2020-04-20 09:31:20 [ExceptionsHandler] [error] Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    --- property 'someProperty' closes the circle
    TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    --- property 'someProperty' closes the circle
    at JSON.stringify (<anonymous>)
    at Printf.template (/my_project/node_modules/nest-winston/dist/winston.utilities.js:23:17)

After some research, I have found that the winston package uses fast-safe-stringify in order to avoid these kinds of errors. See here

The error comes from the winston.utilities.ts file when it tries to JSON.stringify the meta property.

Expected behaviour:

  • the nestLike formatter handles circular JSON structures using fast-safe-stringify

getTimestamp exception thrown when creating Application logger

Creating an application level Logger (via the bootstrap) now appears to cause the following exception:

[ExceptionHandler] instance.getTimestamp is not a function - {"stack":["TypeError: instance.getTimestamp is not a function\n

I created a vanilla application with the following main.ts file:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { utilities as nestWinstonModuleUtilities, WINSTON_MODULE_NEST_PROVIDER, WinstonModule } from 'nest-winston';
import * as winston from 'winston';

const winstonTransports: winston.transport[] = [
  new winston.transports.Console({
    format: winston.format.combine(winston.format.timestamp(), nestWinstonModuleUtilities.format.nestLike()),
  }),
];

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: WinstonModule.createLogger({
      transports: winstonTransports,
    })})
  await app.listen(3000);
}
bootstrap();

Then adding a simple log to the app.controller.ts file

import { Controller, Get, Logger } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {
    Logger.log('Try it then')
  }

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

This should cause the issue as described. If you need any more information just let me know.

Thanks

setContext method implementation and injection scope

Hello,

I have noticed that you haven't implemented "setContext()" method in a similar fashion as it is implemented in @nestjs/logger-service.

Since this is a cool feature, what do you think about adding it to this library?

The implementation itself would look something like this:

class WinstonLogger implements LoggerService {
  private context?: string;

  constructor(private readonly logger: Logger) {
  }

  public log(message: any, context?: string) {
    return this.logger.info(message, {context: context || this.context});
  }

  public error(message: any, trace?: string, context?: string): any {
    return this.logger.error(message, {trace, context: context || this.context});
  }

  public warn(message: any, context?: string): any {
    return this.logger.warn(message, {context: context || this.context});
  }

  public debug(message: any, context?: string): any {
    return this.logger.debug(message, {context: context || this.context});
  }

  public verbose(message: any, context?: string): any {
    return this.logger.verbose(message, {context: context || this.context});
  }

  public setContext(context: string) {
    this.context = context;
  }
}

The use case for this feature would be to set logging context per incoming request, so we don't have to pass "context" as a parameter every time we are logging something.

Furthermore, it would be nice to have an option to set an injection scope for "WinstonLogger" instance i.e. per request.
Since "WinstonLogger" isn't exported from the module, the solution would be either to actually export it, or to add an option "injectionScope" to "WinstonModuleOptions".

What do you think about this?
Thanks.

How to pass in dynamic label?

I have used Nest-Winston for main logging including bootstrap.

This is my configuration

{
    transports: [new transports.Console({
        level: 'debug'
    })],
    format: f.combine(
        format.colorize({ all: true }),
        format.splat(),
        format.simple(),
        format.timestamp(),
        nestWinstonModuleUtilities.format.nestLike()
    ),
    exitOnError: false
}

And this is what it logs now [NestWinston] debug 9/30/2020, 12:56:51 PM debug - {"abc": "xyz"}

How do I print the class name where the error occurred in the place of NestWinston ?

I tried with label but it wasn't dynamic.

Export WinstonLogger from npm module

Firstly great job on this (npm) module!! It's saved me some hassle so thanks ๐Ÿ‘

However using the WinstonLogger as a @Module means that you have to wait for the logger to be instantiated before it will kick in which means you get the default Nest Logger's output for a bit eg:

[Nest] 13486   - 09/28/2019, 5:16:50 PM   [InstanceLoader] TypeOrmCoreModule dependencies initialized +1314ms
info: 9/28/2019, 5:16:50 PM	 [RoutesResolver] AppController {/}:

However in the Nestjs Logger Docs it suggests passing the logger to app at app creation time eg:

const app = await NestFactory.create(AppModule, {
  logger: createWinstonLogger({
    level: "info"
  })
});

function createWinstonLogger(opts: LoggerOptions): LoggerService {
  const logger: winston.Logger = winston.createLogger(opts);

  return new WinstonLogger(logger);
}

This leads to uniform log output ie:

info: 9/28/2019, 5:24:14 PM	 [InstanceLoader] TypeOrmCoreModule dependencies initialized
info: 9/28/2019, 5:24:14 PM	 [RoutesResolver] AppController {/}:

However because the WinstonLogger class is not exported, the only way to make this work for me to copy/paste it into my codebase.

winston exceptionHandlers is not printing logs to file

Env:

  1. Node: v10.19.0
  2. Nest: v7.3.2
  3. Nest Winston: ^1.3.6
  4. winston: ^3.3.3
  5. OS: Mac

Issue:

When i configure exceptionHandlers, the file got created but no log saving in the file.

Configure

import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
const path = require("path");
require('winston-daily-rotate-file');
const myFormat = winston.format.printf(info => {
  return `${info.timestamp} ${info.level} [${info.label}]: ${info.message}`;
});
@Module({
  imports: [ConfigModule.forRoot({
    isGlobal: true,
    load: [configuration]
  }),
  WinstonModule.forRoot({
    exitOnError: false,
    format: winston.format.combine(winston.format.timestamp()
    , winston.format.label({ label: path.basename(process.mainModule.filename) })
    ,myFormat),  // winston.format.json(),
    transports: [
        new (<any>(winston.transports)).DailyRotateFile({
            filename: '/Desktop/logs/daily-%DATE%.log',
            datePattern: 'YYYY-MM-DD',
            maxFiles: '14d'
        }),
        new winston.transports.Console({
          format: winston.format.combine(winston.format.timestamp(), myFormat),
          handleExceptions: true
        })
    ],
    exceptionHandlers: [
        new winston.transports.File({ filename: '/Desktop/logs/exception.log' }),
    ]
  }),],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

The console directly print below but there is no content in the file /Desktop/logs/exception.log

[Nest] 66966   - 07/16/2020, 8:21:33 PM   [ExceptionsHandler] ER_NO_SUCH_TABLE: Table 'test.aaaaa11111' doesn't exist +4038ms
Error: ER_NO_SUCH_TABLE: Table 'test.aaaaa11111' doesn't exist
    at Query.Sequence._packetToError (/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)
    at Query.ErrorPacket (/node_modules/mysql/lib/protocol/sequences/Query.js:79:18)
    at Protocol._parsePacket (/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/node_modules/mysql/lib/protocol/Parser.js:433:10)
    at Parser.write (/node_modules/mysql/lib/protocol/Parser.js:43:10)
    at Protocol.write (/node_modules/mysql/lib/protocol/Protocol.js:38:16)
    at Socket.<anonymous> (/node_modules/mysql/lib/Connection.js:88:28)
    at Socket.<anonymous> (/node_modules/mysql/lib/Connection.js:526:10)
    at Socket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    --------------------
    at Protocol._enqueue (/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at PoolConnection.query (/node_modules/mysql/lib/Connection.js:198:25)
    at /dist/src/common/MySqlService.js:63:28
    at Handshake.onConnect (/node_modules/mysql/lib/Pool.js:64:7)
    at Handshake.<anonymous> (/node_modules/mysql/lib/Connection.js:526:10)
    at Handshake._callback (/node_modules/mysql/lib/Connection.js:488:16)
    at Handshake.Sequence.end (/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Handshake.Sequence.OkPacket (/node_modules/mysql/lib/protocol/sequences/Sequence.js:92:8)
    at Protocol._parsePacket (/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/node_modules/mysql/lib/protocol/Parser.js:433:10)

Unable to inject Logger in Repository and logrotate function

Hello,
thanks for your great work here.
I do have a question:

I was unable after following your tutorial using nest-winston as nestjs logger to use it inside a repository class:

Here some code:

import { ConflictException, Inject, InternalServerErrorException, LoggerService } from "@nestjs/common";
import { WINSTON_MODULE_NEST_PROVIDER } from "nest-winston";
import { EntityRepository, Repository } from "typeorm";
import { AuthCredentialsDto } from "./dto/auth-credentials.dto";
import { User } from "./user.entity";

@EntityRepository(User)
export class UserRepository extends Repository<User> {
    constructor(@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService) {        
        super()
    }

    async signUp(authCredentialsDto: AuthCredentialsDto): Promise<void> {

        const { username, password, primaryEmailAddress } = authCredentialsDto

        const user = new User();
        user.username = username;
        user.password = password;
        user.primaryEmailAddress = primaryEmailAddress;
        
        try {
            await user.save()
        } catch(error) {
            // Catches duplicated Entry Error
            if (error.code === 'ER_DUP_ENTRY') {
                this.logger.error(`User with name ${user.username} tried to be registered a second time.`)
                throw new ConflictException('Username already exists')
            } else {
                throw new InternalServerErrorException();
            }
        }
    }
}

When the user is already in the database the line this.logger ... is called, but ending up in this error message:
TypeError: this.logger.error is not a function . This message is also logged to the error.log. But the expected value should be User with name ${user.username} tried to be registered a second time.

I straight followed your documentation by creating the logger in this way:

app.module.ts

@Module({
  imports: [
  TypeOrmModule.forRoot(configService.getTypeOrmConfig()),
  WinstonModule.forRoot({
    transports: [
      new winston.transports.Console({
        format: winston.format.combine(
          winston.format.timestamp(),
          nestWinstonModuleUtilities.format.nestLike(),
        )
      },
    ),
    new winston.transports.File({
      format: winston.format.json(),
      filename: errorLogPath, level: 'error',
      zippedArchive: true,
      tailable: true,      
    }),
    new winston.transports.File({
      format: winston.format.json(),
      filename: infoLogPath, level: 'info',
      zippedArchive: true,
      tailable: true,      
    })
    ],

  }),
  AuthModule
],
  controllers: [],
  providers: []
})
export class AppModule {}

Here my second question arises: How can I use logrotate? It wants a function, can you provide me an example? I want to daily rotate my logs.

Thanks in advance!!

Best regards
Meywether

structured logging (info objects)

First things first, thanks for putting together this NestJS module.

We want to be able to use structured logging in our, not only json formatted output but also the ability to include application specific key-value pairs. This is something that Winston already supports, known as info objects.

I could not find a way of achieving this in the current implementation of nest-winston. The limitation stems from the definition of nestjs's LoggerService interface.

export interface LoggerService {
    log(message: any, context?: string): any;
    error(message: any, trace?: string, context?: string): any;
    warn(message: any, context?: string): any;
    debug?(message: any, context?: string): any;
    verbose?(message: any, context?: string): any;
}

I would like to know if there is appetite for a contribution to extend the interface to allow for structured logging. The interface could look like:

export interface StructuredLoggerService extends LoggerService {
  log(message: any, meta?: any): void;
  error(message: any, trace?: string, meta?: any): any;
  warn(message: any, meta?: any): any;
  debug?(message: any, meta?: any): any;
  verbose?(message: any, meta?: any): any;
}

the signature of the methods is compatible with the base interface. The implementation, WinstonLogger, could apply some logic to determine if the argument is a context string or a meta object and based on that delegate the logging to the underlaying winston logger instance.

Something on the lines of:

  public log(message: any, meta?: any) {
    return this.logger.info(message, packFields(this.context, undefined, meta));
  }

function packFields(context?: string, trace?: string, meta?: any): any {
  let fields: any = {}
  if (typeof meta === 'string') {
    fields.context = meta;
  } else {
    fields.context = meta?.context || context
    fields = {...fields, ...meta, trace}
  }
  return fields
}

The app would use the logger like this:

this.logger('this is a simple message`)
this.logger('this is a message that sets the context', 'context foo')
this.logger('this message attaches some key/value pairs', {foo: 'bar'})

If you think this is useful and the right approach I can submit a PR.

Thanks!

Export nest like log format

I actually got this idea from https://github.com/pay-k/nestjs-winston (as an aside I don't know why this module/repo exists as it's not a fork of this repo and according the npm this module was published first, so it looks like the author just took a dump of this repo)

It's a Winston formatter that mimics the output format of the default Nest Logger.

const nestLikeFormat = winston.format.printf(({ context, level, timestamp, message }) => {
  return `${level}: ${new Date(timestamp).toLocaleString()}\t [${colors.yellow(context)}] ${message}`;
});

const nestFormat = winston.format.combine(
  winston.format.timestamp(),
  winston.format.colorize({ all: true }),
  nestLikeFormat
);

error stack trace is not printed

Hi there! I'm not sure if this is feature request of bug repport.

what I do is configure winson in bootstrap function

  app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));

and app module

    WinstonModule.forRootAsync({
      useFactory: () => ({
        transports: [
          new transports.Console({
            format: format.combine(
              format.timestamp(),
              utilities.format.nestLike(),
            ),
          }),
        ],
      }),
    }),

and then use

  constructor(@Inject("winston") private readonly logger: Logger) {}

  public method(): void {
    const error = new Error("On no!");
    this.logger.error(error.message, error.stack, this.constructor.name);
  }

which print just

[NestWinston] Error     11/30/2019, 9:47:02 PM On no! - {}

according to docs it should print [context] and trace property in the meta data

ok lets do this ather way around

  constructor(@Inject("winston") private readonly logger: Logger) {}

  public method(): void {
    const error = new Error("On no!");
    this.logger.error(error);
  }

prints

[NestWinston] Error     11/30/2019, 9:51:27 PM undefined - {}

which is even worth

I was managed to make it work somehow

    WinstonModule.forRootAsync({
      useFactory: () => ({
        format: format.combine(
          format.errors({stack: true}), 
          format.timestamp()
        ),
        transports: [
          new transports.Console({
            format: format.printf(({level, context, timestamp, message, stack, trace}) => {
              let color, text;
              if (level === "error") {
                color = red;
                const lines = (stack || trace).split("\n");
                lines[0] = color(lines[0]);
                text = lines.join("\n");
              } else {
                color = green;
                text = color(message);
              }
              return `${color(`[Nest] ${process.pid}   -`)} ${new Date(timestamp).toLocaleString()}   ${context ? yellow("[" + context + "]") : ""} ${text}`;
            }),
          }),
        ],
      }),
    }),

now it prints Error object

[Nest] 20905   - 11/30/2019, 9:53:37 PM    Error: On no!
    at AuthController.biometric (~/path/to/file.ts:59:19)
    at ~/node_modules/@nestjs/core/router/router-execution-context.js:37:29
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at ~/node_modules/@nestjs/core/router/router-execution-context.js:45:28
    at ~/node_modules/@nestjs/core/router/router-proxy.js:8:17

but i still want to pass context and signature with 3 params just does not work. Please gimme some directions

logs are not logged

After setting as default logger with app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));, logs are not logged
I am doing logging as:
constructor(@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService) { }

and

this.logger.log('some log')

Constant for inject token

Hi, in the README, there is this example:

@Inject('winston') private readonly logger: Logger

I do not want to type the token 'winston' all the time to avoid typo, also it can change in the future. Best to have a constant for it. I can see this one from type definition:

export declare const WINSTON_MODULE_PROVIDER = "winston"

Is it supposed to be the inject token? If so, the README should mention about it.

how to use inside a filter

I want to use this inside a filter where i am catching all 500 exceptions. can anyone provide me with some snippet to get going

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

WinstonOptionFactory

please add WinstonOptionFactory so users can create WinstonConfigService to pass in useClass property for forRootAsync

Issue with date formatting?

Hello,

I'm not sure if it's a bug or not, but if I want to format my date thanks to "winston.format.timestamp", an error "Invalid Date" is displayed in the console.

[test] Info     Invalid Date [RoutesResolver] TestController {/api/tests}: - {}
[test] Info     Invalid Date [RouterExplorer] Mapped {/api/tests, POST} route - {}
[test] Info     Invalid Date [RouterExplorer] Mapped {/api/tests, DELETE} route - {}
[test] Info     Invalid Date [NestApplication] Nest application successfully started - {}

Code example:

async function bootstrap() {
    const app = await NestFactory.create(AppModule, {
        logger: WinstonModule.createLogger({
            transports: [
                new winston.transports.Console({
                    format: winston.format.combine(
                        winston.format.timestamp({ format: "DD:MM:YYYY HH:mm:ss" }), //Date format
                        nestWinstonModuleUtilities.format.nestLike("Test"),
                    ),
                })
            ]
        })
    });
    await app.listen(5000)
}
bootstrap()

So my question is : why the function "nestLikeConsoleFormat" at line 21, does not look like this, to allow custom format to displayed?

('undefined' !== typeof timestamp ? `${timestamp} ` : `${new Date().toLocaleString()} `) +

Thank you very much for your answer!

How would I use this module with Google's logging-winston middleware?

Thanks for the really cool module. I added it into our Nest project using the bootstrap method and everything worked out of the box! ๐Ÿ‘

However, we use Google App Engine in production, and we would like our log output to be grouped by request. Normally, we use @google-cloud/logging-winston to create an express middleware which automagically picks up GAE correlationIds etc. This is explained in their documentation. Basically, you call the provided makeMiddleware function, passing it your initialised logger. The logger is then attached to your request object.

Unfortunately, WinstonModule.createLogger returns a LoggerService, which doesn't expose an interface compatible with the standard Winston logger.

How can I use your module and take advantage of the request-bundling offered by the logging-winston middleware?

Adding transports based on environment

Since the config options are placed inside the module import in the AppModule, I can't get transports to be added based on which environment the app is running in. Normally using winston, the logger is instantiated in a variable which can be accessed later to add a transport like this:

if (process.env.NODE_ENV !== 'production') {
  logger.add(new transports.Console({
    format: format.combine(
      format.colorize(),
      format.simple()
    )
  }));
}

Where should the code above (or similar) be used to add the transport?

Adding new logger transport depending on environment

I am implementing a logger module using nest-winston but I don't know how to implement a a new logger depending on environment cleanly, here's my LoggerModule:

import { Module } from "@nestjs/common";
import { WinstonModule, utilities } from 'nest-winston';
import * as winston from 'winston';
import configuration from "../config/configuration";
// Create a method to transform stacktrace error to Object
const errorStackFormat = winston.format(info => {
  if (info instanceof Error) {
    return Object.assign({}, info, {
      stack: info.stack,
      message: info.message
    })
  }
  return info
})

@Module({
  imports: [
    WinstonModule.forRootAsync({
      useFactory: () => ({
        level: "info",
        format: winston.format.combine(errorStackFormat()),
        defaultMeta: { service: "api" },
        transports: [
            new winston.transports.File({ filename: configuration.errLogPath + "/error.log", level: "error" }),
            new winston.transports.File({ filename: configuration.appLogPath + "/combined.log", level: 'info' }),
            new winston.transports.Console({
              format: winston.format.combine(
                winston.format.timestamp(),
                utilities.format.nestLike()
              )
            }),
        ],
      }),
      inject: [],
    }),
  ],
})

export class LoggerModule {}

Question: How i can read from mongodb

Hello i use nest winston combined with winston-mongodb for transporter and for now successfully I save my data into the DB, my questions is can i use nest winston to read or i need to get it by my self?

Question: How to use it in TypeOrmModule?

Hi, my question is how to use it in TypeOrmModule ?
Currently, db query didn't saved in log.


const config: TypeOrmModuleOptions = {
  type: 'mysql',
  host: db.host,
  port: db.port,
  password: db.password,
  username: db.user,
  database: db.database,
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  logging: true,
  logger: // ?? <---- what should I inject here ?
};

@Module({
  imports: [
    TypeOrmModule.forRoot(config),
    UserModule,
    RoomModule,
    RoomHistoryModule,
    WinstonModule.forRoot({
      transports: [
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp({
              format: 'YYYY-MM-DD HH:mm:ss',
            }),
          ),
        }),
        dailyRotateFile,
        // other transports...
      ],
    }),
  ],
  controllers: [],
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthGuard,
    },
  ],
})
export class AppModule {}

Can I use this logger to see the logs of my project when it runs on a server?

Hello, I'm new with nestjs.

Description::
There is an outside of my network plugin that sends data to my nestjs that runs on a server.
And it seems my nestjs responds with:

responseText: "{"statusCode":500,"message":"Internal server error"}"
success: false```

Can I use this logger to see what data I'm receiving from that plugin?
When I was working locally I was able to use the default logger for that, plus a simple console.log() and I could easily see the receiving objects.

But now that I'm online and that I have to receive something outside of my network I don't know where to see what my nestjs is receiving.

So my basic question:
Can I use this logger to see what I'm receiving while being live on a server?
And if yes, how? Is there a specific file that shows me logs?
Does it have a specific name or path?

Override formating per module?

Hello,

Is there a way to override format options per module?

For instance, my app.module.ts looks like:

 imports: [
    WinstonModule.forRoot({
      transports: [...],
      format: combine(
        label({ label: 'CONTROLLER_NAME' }),
        timestamp(),
        myFormat,
      ),
    }),

And I'm calling it as such:

@Controller('SomeController')
export class SomeController {
  constructor(
    @Inject('winston')
    private readonly logger: Logger,
  ) {}

With the nest logger I would be able to add something like setContext. Is there any way to achieve this?

Thanks

Question: How can I insert the context info (module name) into logging

I wanna know if there's any way to insert (by default) the module name into logging information. I researched and found that the INQUIRER decorator seems to do what I want, however, how can I put this by default? PS.: I'm using the following configurations.

WinstonModule.forRoot({
      transports: [
        new winston.transports.File({
          format: winston.format.combine(
            winston.format.simple(),
            winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
            winston.format.printf(
              info => `[${info.timestamp}] ${info.level} ${info.message}`,
            ),
          ),
          maxsize: 10e6,
          maxFiles: 5,
          filename: `${__dirname}/../logs/log.log`,
        }),
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.simple(),
            winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
            winston.format.colorize(),
            winston.format.printf(
              info => `[${info.timestamp}] ${info.level} ${info.message}`,
            ),
          ),
          level: 'debug',
        }),
      ],
    }),
  ],

I get from logger.info method [object Object]

I made model in folder modules/logger.

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { WinstonModule } from 'nest-winston';

import { winstonConfig } from './winston.config';
import { LoggerInterceptor } from './interceptor/logger.interceptor';

@Module({
    imports: [WinstonModule.forRoot(winstonConfig)],
    controllers: [],
    providers: [
        {
            provide: APP_INTERCEPTOR,
            useClass: LoggerInterceptor,
        },
    ],
})
export class LoggerModule {}

My config file of logger in folder modules/logger.

import { utilities, WinstonModuleOptions } from 'nest-winston';
import { config, format, transports } from 'winston';

export const winstonConfig: WinstonModuleOptions = {
    levels: config.npm.levels,
    level: 'verbose',
    transports: [
        new transports.Console({
            format: format.combine(format.timestamp(), utilities.format.nestLike()),
        }),
        new transports.File({
            level: 'verbose',
            filename: 'application.log',
            dirname: 'logs',
            maxsize: 104857600, // 100MB
        }),
    ],
};

After a mode an interceptor in folder modules/logger/interceptor.

import { Injectable, Inject, NestInterceptor, CallHandler, ExecutionContext } from '@nestjs/common';
import { Logger } from 'winston';
import { Observable } from 'rxjs';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';

@Injectable()
export class LoggerInterceptor implements NestInterceptor {
    constructor(@Inject(WINSTON_MODULE_PROVIDER) private logger: Logger) {}

    public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        this.log(context.switchToHttp().getRequest());
        return next.handle();
    }

    private log(req): void {
        const body = { ...req.body };
        delete body.password;
        delete body.passwordConfirmation;
        const user = (req as any).user;
        const userEmail = user ? user.email : null;
        const data = {
            timestamp: new Date().toISOString(),
            method: req.method,
            route: req.route.path,
            data: {
                body: body,
                query: req.query,
                params: req.params,
            },
            from: req.ip,
            madeBy: userEmail,
        };
        console.log(data);

        this.logger.info(data);
    }
}

In my app.module I added my logger.module.

...
import { LoggerModule } from './modules/logger/logger.module';

@Module({
    imports: [..., LoggerModule],
    controllers: [],
    providers: [],
})
export class AppModule {}

Where I run me app I see in console [object Object].

...
backend     | [NestWinston] Info        9/15/2020, 11:10:24 AM [RouterExplorer] Mapped {/user/update-user, PATCH} route - {}
backend     | [NestWinston] Info        9/15/2020, 11:10:24 AM [RouterExplorer] Mapped {/user/delete-user/:id, DELETE} route - {}
backend     | [NestWinston] Info        9/15/2020, 11:10:24 AM [RouterExplorer] Mapped {/user/profile, GET} route - {}
backend     | [NestWinston] Info        9/15/2020, 11:10:24 AM [RouterExplorer] Mapped {/user/find-users, GET} route - {}
backend     | [NestWinston] Info        9/15/2020, 11:10:24 AM [NestApplication] Nest application successfully started - {}
backend     | {
backend     |   timestamp: '2020-09-15T11:12:01.729Z',
backend     |   method: 'POST',
backend     |   route: '/auth/sign-in',
backend     |   data: { body: { email: '[email protected]' }, query: {}, params: {} },
backend     |   from: '::ffff:172.23.0.1',
backend     |   madeBy: null
backend     | }
backend     | [NestWinston] Info        9/15/2020, 11:12:01 AM [object Object] - {}

But usual console.log is show all object.

Why is it work so? Where I make mistake?

Winston does not appear to inject properly

Hi, I'm trying to Inject Winston into a service class. I've added Winston to the main Application module:

import { Module } from '@nestjs/common';
...
import { WinstonModule } from 'nest-winston';
import * as winston from "winston";

@Module({
    imports: [
        TypeOrmModule.forRoot(),
        WinstonModule.forRoot({
            level: 'info',
            format: winston.format.json(),
            transports: [
                //
                // - Write to all logs with level `info` and below to `combined.log`
                // - Write all logs error (and below) to `error.log`.
                //
                new winston.transports.File({ filename: 'error.log', level: 'error' }),
                new winston.transports.File({ filename: 'combined.log' })
            ]
        }),
        AuthModule,
        ...
    ]
})

and in its constructor I've built it like this:

...
import {Logger} from "winston";

@Injectable()
export class FileService {
    constructor(@InjectRepository(ImageFile)
                @Inject('winston') logger: Logger,
                private readonly imageFileRepository: Repository<ImageFile>,
                config: ConfigService,
    ) { ... }

However, upon startup, NestJS presents:

[Nest] 12572   - 11/24/2018, 4:33:15 PM   [ExceptionHandler] Nest can't resolve dependencies of the FileService (ImageFileRepository, ?, ConfigService). Please make sure that the argument at index [1] is available in the current context. +16ms
Error: Nest can't resolve dependencies of the FileService (ImageFileRepository, ?, ConfigService). Please make sure that the argument at index [1] is available in the current context.

So, it looks like the Winston injection isn't there. My understanding is that because I added Winston .forRoot() it should be ready to inject anywhere... Maybe the token is wrong?

Also, it appears that Winston will not operate without a specified config, I think? Maybe it should have a sensible default?

Cannot use logger based on package documentation

I want to use Winston global when app starts

async function bootstrap() {

  const app = await NestFactory.createMicroservice(AppModule, {
    logger: WinstonModule.createLogger({
      transports: [
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp(),
            nestWinstonModuleUtilities.format.nestLike(),
          ),
        }),
        new winston.transports.File({
          filename: 'logs/app.log', format: winston.format.combine(
            winston.format.timestamp(),
            winston.format.logstash(),
          )
        })
      ],
    }),
    transport: Transport.TCP,
    options: {
      host: "127.0.0.1",
      port: 8888
    }
  });
  app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
  await app.listen(() => {app.get(WINSTON_MODULE_NEST_PROVIDER).log("STARTED")}); /**/is this ok?**
}
bootstrap();

- {"trace":"Error: Nest can't resolve dependencies of the AuthController (?, UserService, AuthService). Please make sure that the argument winston at index [0] is available in the AuthModule context.\n\nPotential solutions:\n- If winston is a provider, is it part of the current AuthModule?
This is not working anymore
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) { }

If I added to the app main.js how can I use it in controllers?

Initializing logger with setContext inside constructor

@gremo Is there an option to initialize the logger inside the class constructor with the context, so that everytime the context need not be specified in a class.

If we could do something like

_logger: any;
constructor(@Inject(WINSTON_MODULE_NEST_PROVIDER) private logger: LoggerService) {
    this._logger = logger.setContext('ClassName');
}

async test() {
    this._logger.log('Hello World');
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.