Installations
npm install nest-winston
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
22.13.0
NPM Version
11.0.0
Releases
Unable to fetch releases
Contributors
Languages
TypeScript (100%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
gremo
Download Statistics
Total Downloads
51,530,149
Last Day
79,068
Last Week
486,913
Last Month
1,985,749
Last Year
20,477,347
GitHub Statistics
670 Stars
1,169 Commits
94 Forks
7 Watching
6 Branches
35 Contributors
Bundle Size
9.45 kB
Minified
2.94 kB
Minified + Gzipped
Package Meta Information
Latest Version
1.10.2
Package Id
nest-winston@1.10.2
Unpacked Size
31.26 kB
Size
8.76 kB
File Count
17
NPM Version
11.0.0
Node Version
22.13.0
Publised On
21 Jan 2025
Total Downloads
Cumulative downloads
Total Downloads
51,530,149
Last day
8.1%
79,068
Compared to previous day
Last week
7%
486,913
Compared to previous week
Last month
30.8%
1,985,749
Compared to previous month
Last year
22%
20,477,347
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
1
Peer Dependencies
2
nest-winston
A Nest module wrapper for winston logger.
Table of Contents
- Installation
- Quick start
- Async configuration
- Replacing the Nest logger
- Replacing the Nest logger (also for bootstrapping)
- Injection and usage summary
- Utilities
- Logger methods
- Upgrade
- Contributing
- License
Installation
1npm install --save nest-winston winston
Having troubles configuring nest-winston
? Clone this repository and cd
in a sample:
1cd sample/quick-start 2npm install 3npm 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:
1import { Module } from '@nestjs/common'; 2import { WinstonModule } from 'nest-winston'; 3import * as winston from 'winston'; 4 5@Module({ 6 imports: [ 7 WinstonModule.forRoot({ 8 // options 9 }), 10 ], 11}) 12export 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:
1import { Controller, Inject } from '@nestjs/common'; 2import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; 3import { Logger } from 'winston'; 4 5@Controller('cats') 6export class CatsController { 7 constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) { } 8}
Async configuration
Caveats: because the way Nest works, you can't inject dependencies exported from the root module itself (using
exports
). If you useforRootAsync()
and need to inject a service, that service must be either imported using theimports
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:
1import { Module } from '@nestjs/common'; 2import { WinstonModule } from 'nest-winston'; 3import * as winston from 'winston'; 4 5@Module({ 6 imports: [ 7 WinstonModule.forRootAsync({ 8 useFactory: () => ({ 9 // options 10 }), 11 inject: [], 12 }), 13 ], 14}) 15export 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:
1WinstonModule.forRootAsync({ 2 useClass: WinstonConfigService, 3})
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:
1import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; 2 3async function bootstrap() { 4 const app = await NestFactory.create(AppModule); 5 app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER)); 6 await app.listen(3000); 7} 8bootstrap();
Then inject the logger using the WINSTON_MODULE_NEST_PROVIDER
token and the LoggerService
typing:
1import { Controller, Inject, LoggerService } from '@nestjs/common'; 2import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; 3 4@Controller('cats') 5export class CatsController { 6 constructor(@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService) { } 7}
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
andforRootAsync
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:
1import { WinstonModule } from 'nest-winston'; 2 3async function bootstrap() { 4 const app = await NestFactory.create(AppModule, { 5 logger: WinstonModule.createLogger({ 6 // options (same as WinstonModule.forRoot() options) 7 }) 8 }); 9 await app.listen(3000); 10} 11bootstrap();
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.
1import { createLogger } from 'winston'; 2import { WinstonModule } from 'nest-winston'; 3 4async function bootstrap() { 5 // createLogger of Winston 6 const instance = createLogger({ 7 // options of Winston 8 }); 9 const app = await NestFactory.create(AppModule, { 10 logger: WinstonModule.createLogger({ 11 instance, 12 }), 13 }); 14 await app.listen(3000); 15} 16bootstrap();
The usage afterwards for both solutions is the same. First, change your main module to provide the Logger
service:
1import { Logger, Module } from '@nestjs/common'; 2 3@Module({ 4 providers: [Logger], 5}) 6export class AppModule {}
Then inject the logger simply by type hinting it with Logger
from @nestjs/common
:
1import { Controller, Logger } from '@nestjs/common'; 2 3@Controller('cats') 4export class CatsController { 5 constructor(private readonly logger: Logger) {} 6}
Alternative syntax using the LoggerService
typing and the @Inject
decorator:
1import { Controller, Inject, Logger, LoggerService } from '@nestjs/common'; 2 3@Controller('cats') 4export class CatsController { 5 constructor(@Inject(Logger) private readonly logger: LoggerService) {} 6}
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 totrue
, unlessprocess.env.NO_COLOR
is set (same behaviour of Nest > 7.x)prettyPrint
: pretty format log metadata, defaults totrue
processId
: includes the Node Process ID (process.pid
) in the output, defaults totrue
appName
: includes the provided application name in the output, defaults totrue
Note: When providing partial options, unspecified options will retain their default values.
1import { Module } from '@nestjs/common'; 2import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-winston'; 3import * as winston from 'winston'; 4 5@Module({ 6 imports: [ 7 WinstonModule.forRoot({ 8 transports: [ 9 new winston.transports.Console({ 10 format: winston.format.combine( 11 winston.format.timestamp(), 12 winston.format.ms(), 13 nestWinstonModuleUtilities.format.nestLike('MyApp', { 14 colors: true, 15 prettyPrint: true, 16 processId: true, 17 appName: true, 18 }), 19 ), 20 }), 21 // other transports... 22 ], 23 // other options 24 }), 25 ], 26}) 27export 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:
1debug(message: any, context?: string) 2log(message: any, context?: string) 3error(message: any, stack?: string, context?: string) 4fatal(message: any, stack?: string, context?: string) 5verbose(message: any, context?: string) 6warn(message: any, context?: string)
Example:
1import { Controller, Get, Logger } from '@nestjs/common'; 2import { AppService } from './app.service'; 3 4@Controller() 5export class AppController { 6 constructor( 7 private readonly appService: AppService, 8 private readonly logger: Logger, 9 ) {} 10 11 @Get() 12 getHello(): string { 13 this.logger.log('Calling getHello()', AppController.name); 14 this.logger.debug('Calling getHello()', AppController.name); 15 this.logger.verbose('Calling getHello()', AppController.name); 16 this.logger.warn('Calling getHello()', AppController.name); 17 18 try { 19 throw new Error() 20 } catch (e) { 21 this.logger.error('Calling getHello()', e.stack, AppController.name); 22 } 23 24 return this.appService.getHello(); 25 } 26}
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 andcolors
has been added. - The
nestLike
formatter has the newcolors
option: if not provided, colors will be used according to Nest "approach" (disabled if env variableprocess.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!
License
This project is released under the under terms of the ISC License.
![Empty State](/_next/static/media/empty.e5fae2e5.png)
No vulnerabilities found.
Reason
security policy file detected
Details
- Info: security policy file detected: .github/SECURITY.md:1
- Info: Found linked content: .github/SECURITY.md:1
- Info: Found disclosure, vulnerability, and/or timelines in security policy: .github/SECURITY.md:1
- Info: Found text in security policy: .github/SECURITY.md:1
Reason
no dangerous workflow patterns detected
Reason
30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/ci.yaml:1
- Warn: no topLevel permission defined: .github/workflows/contributors.yaml:1
- Warn: no topLevel permission defined: .github/workflows/slate.yaml:1
- Warn: no topLevel permission defined: .github/workflows/toc.yaml:1
- Info: no jobLevel write permissions found
Reason
Found 1/28 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/gremo/nest-winston/ci.yaml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/gremo/nest-winston/ci.yaml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/contributors.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/gremo/nest-winston/contributors.yaml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/slate.yaml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/gremo/nest-winston/slate.yaml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/toc.yaml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/gremo/nest-winston/toc.yaml/main?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:49
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:54
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:62
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:70
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:75
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:80
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:88
- Info: 0 out of 3 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 2 third-party GitHubAction dependencies pinned
- Info: 0 out of 7 npmCommand dependencies pinned
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 9 are checked with a SAST tool
Reason
49 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-4jpv-8r57-pv7j
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25
- Warn: Project is vulnerable to: GHSA-cph5-m8f7-6c5x
- Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-h452-7996-h45h
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-wm7h-9275-46v2
- Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h
- Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc
- Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx
- Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q
- Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c
- Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc
- Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq
- Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488
- Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6
- Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-hc6q-2mpp-qw7j
- Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
Score
4.5
/10
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More