@redhare/logger
v0.0.2
Published
`@infra-node-kit/logger` provides common abilities for all Node.js application to log with some pre-defined rules (format, properties .etc).
Downloads
2
Keywords
Readme
@infra-node-kit/logger
provides common abilities for all Node.js application to log with some pre-defined rules (format, properties .etc).
Install
yarn add @infra-node-kit/logger
Get Start
import { logger, createLogger, LOG_LEVEL, createLoggerService } from '@infra-node-kit/logger'
// use predefined logger
logger.debug('my debug message')
// create logger with options
const myLogger = createLogger({
level: LOG_LEVEL.WARN,
})
try {
// throw error
} catch (e) {
// log error stack
myLogger.stack(e)
}
// log normal message with stack
myLogger.stack('normal message')
const newLogger = myLogger.extends({
host: 'localhost:3000'
})
// { message: 'extended', host: 'localhost:3000' }
newLogger.info('extended')
const loggerSerivce = createLoggerService({
// ...
})
app.useLogger(loggerService)
User Stories
Story 1: print messages both in console and files under ./logs
, with default format
import { logger } from '@infra-node-kit/logger'
logger.info('messsage')
logger.info({
message: 'message',
customField: 'this is a custom field in log'
})
logger.error('critical error', { customField: 'this is a custom field in log' })
Story 2: print errors or messages with call stack
import { logger } from '@infra-node-kit/logger'
try {
doSomeDangerousOperations()
} catch (e) {
logger.stack(e)
}
function foo() {
// ...
// want to print call stack here
logger.stack('I\'m in foo function')
// ...
}
Story 3: replace logger in nestjs
import { NestFactory } from '@nestjs/core'
import { createLoggerService } from '@infra-node-kit/logger'
import MainModule from './main.module'
const app = await NestFactory.create(MainModule)
const loggerService = createLoggerService()
app.useLogger(loggerService)
Story 4: print messages with custom format
import { createLogger, LOG_FORMAT } from '@infra-node-kit/logger'
const logger = createLogger({
format: LOG_FORMAT.CUSTOM,
renderLog: (params: IGeneralLogParams) => {
return Object.entries(params).map(([key, value]) => `${key}=${value}`).join(' ')
},
})
logger.info('my message') // level=info message=my message
Story 5: use nestjs logger
import { NestFactory } from '@nestjs/core'
import { Injectable } from '@nestjs/common'
import { createLoggerService, LoggerService } from '@infra-node-kit/logger'
import { MainModule } from './main.module'
const app = await NestFactory.create(MainModule);
app.useLogger(createLoggerService())
@Injectable()
export class FooService {
constructor(private logger: LoggerService) {}
bar() {
this.logger.info('log with x-request-id')
}
}
Story 6: use decorator
The parameter of @Logger()
can be a string as service
or an object as extends
fields.
Notice: DO NOT use
@Logger()
in constructor, it's not a nestjs injection.
import { Logger } from '@infra-node-kit/logger'
@Injectable()
export class FooService {
@Logger('biz') private logger: LoggerService
bar() {
this.logger.info('log with x-request-id')
}
}
API References
type ILogger = {
error(message: string | IGeneralLogParams, fields?: IGeneralLogParams): ILogger;
warn(message: string | IGeneralLogParams, fields?: IGeneralLogParams): ILogger;
info(message: string | IGeneralLogParams, fields?: IGeneralLogParams): ILogger;
debug(message: string | IGeneralLogParams, fields?: IGeneralLogParams): ILogger;
trace(message: string | IGeneralLogParams, fields?: IGeneralLogParams): ILogger;
stack(error?: Error | any): ILogger;
extends(fields: IGeneralLogParams): ILogger;
}
function createLogger(options?: ICreateLoggerOptions): ILogger;
interface ICreateLoggerOptions {
/** Print log above this level only */
level?: LogLevel
/** Select format of log */
format?:
| LOG_FORMAT
| {
console?: LOG_FORMAT
file?: LOG_FORMAT
}
/** Render custom format log */
renderLog?: (params: IGeneralLogParams) => string
/** Fields appended to every log */
extends?: IGeneralLogParams
/** Don't print warning messages of this package */
silent?: boolean
/** Disable printing log to console */
disableConsole?: boolean
/** Disable printing log to file */
disableFile?: boolean
/**
* Options in `winston-daily-rotate-file`
* `dirname` is default to './logs'
*/
rotateFileOptions?: GeneralDailyRotateFileTransportOptions
}
extends action
field
declare module '@infra-node-kit/logger' {
interface ILogActions {
'fetch': 'for fetch'
'access': 'access log'
}
}
fetch
and access
will be valid values in field action