this.logger.warn and this.logger.verbose is not a function
alko89 opened this issue · 10 comments
I'm trying to add papertrail logging to nest. I am using nest-winston module to inject the logger in bootstrap:
// logging.ts
import { hostname } from 'os';
import { format, config, transports } from 'winston';
import { utilities, WinstonModule } from 'nest-winston';
import { Syslog } from 'winston-syslog';
import { papertrailHost, papertrailPort } from './env';
const papertrail = new Syslog({
host: papertrailHost,
port: papertrailPort,
protocol: 'tls4',
localhost: hostname(),
app_name: process.env.npm_package_name,
eol: '\n',
});
const console = new transports.Console();
export const Logger = WinstonModule.createLogger({
format: format.combine(
format.timestamp(),
format.ms(),
utilities.format.nestLike(process.env.npm_package_name, {
prettyPrint: true,
}),
),
levels: config.syslog.levels,
transports: [console, papertrail],
});
// main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: Logger,
});
await app.listen(apiPort);
}
Doing so seems to work for Error
, Info
(with missing context) and Debug
but throw for Warn
and Verbose
.
I have created an endpoint to test logging:
import { Injectable, Logger } from '@nestjs/common';
import { LogDto } from './dto/log.dto';
@Injectable()
export class AppService {
private readonly logger = new Logger('App');
createLog(logDto: LogDto) {
switch (logDto.level) {
case 'log':
return this.logger.log(logDto.message, logDto.params);
case 'error':
return this.logger.error(logDto.message, logDto.params);
case 'warn':
return this.logger.warn(logDto.message, logDto.params);
case 'debug':
return this.logger.debug(logDto.message, logDto.params);
case 'verbose':
return this.logger.verbose(logDto.message, logDto.params);
}
}
}
Example console output:
[moralis-admin-api] Info 11/10/2021, 2:26:17 PM [NestApplication] Nest application successfully started - {} +1ms
[moralis-admin-api] Error 11/10/2021, 2:26:37 PM [App] test - { stack: [ null ] } +20s
[moralis-admin-api] Error 11/10/2021, 2:26:46 PM [ExceptionsHandler] this.logger.warn is not a function - {
stack: [
'TypeError: this.logger.warn is not a function\n' +
' at WinstonLogger.warn (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/nest-winston/dist/winston.classes.js:48:28)\n' +
' at Logger.warn (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/common/services/logger.service.js:48:75)\n' +
' at Logger.descriptor.value (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/common/services/logger.service.js:163:27)\n' +
' at AppService.createLog (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/src/resources/app/app.service.ts:15:28)\n' +
' at AppController.createLog (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/src/resources/app/app.controller.ts:11:21)\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-execution-context.js:38:29\n' +
' at processTicksAndRejections (node:internal/process/task_queues:96:5)\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-execution-context.js:46:28\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-proxy.js:9:17'
]
} +9s
[moralis-admin-api] Error 11/10/2021, 2:26:52 PM [ExceptionsHandler] this.logger.verbose is not a function - {
stack: [
'TypeError: this.logger.verbose is not a function\n' +
' at WinstonLogger.verbose (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/nest-winston/dist/winston.classes.js:64:28)\n' +
' at Logger.verbose (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/common/services/logger.service.js:62:130)\n' +
' at Logger.descriptor.value (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/common/services/logger.service.js:163:27)\n' +
' at AppService.createLog (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/src/resources/app/app.service.ts:19:28)\n' +
' at AppController.createLog (/home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/src/resources/app/app.controller.ts:11:21)\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-execution-context.js:38:29\n' +
' at processTicksAndRejections (node:internal/process/task_queues:96:5)\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-execution-context.js:46:28\n' +
' at /home/alko/Development/IvanOnTech/Moralis/moralis-admin-api/node_modules/@nestjs/core/router/router-proxy.js:9:17'
]
} +5s
[moralis-admin-api] Error 11/10/2021, 2:26:58 PM [App] test - { stack: [ null ] } +6s
[moralis-admin-api] Info 11/10/2021, 2:27:02 PM test - {} +5s
There are three issues I see with my approach:
- info has no context
- warn and verbose functions throw
- wrong response time - the log shows response times as if they took over a second to complete.
I had this same issue
Can you please try to inject the logger as in this app.controller.ts
?
In particular, @alko89 , why doing the following?
private readonly logger = new Logger('App');
I have the same issue with the syslog transport :
const winstonOptions: winston.LoggerOptions = {
levels: winston.config.syslog.levels,
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
customFormat,
winston.format.errors({ stack: true }),
winston.format.timestamp(),
),
}),
new winston.transports.File({
level: 'warn',
format: winston.format.combine(
winston.format.errors({ stack: true }),
winston.format.timestamp(),
winston.format.json(),
),
filename: '../logs/api.log',
}),
new Syslog(syslogOptions),
],
};
Here is the initialisation :
const app = await NestFactory.create(AppModule, {
logger: WinstonModule.createLogger(winstonOptions),
});
I think it comes from the levels: winston.config.syslog.levels
because when I set it to another thing (winston.config.npm.levels
for example)
@gremo I updated my code with what you recommended by injecting the logger, now there is no context in any of the logs and there is still issue with time measurements. Warning seems to be working now though.
Its possible to add context to logs manually by passing name to the function (this.logger.log(logDto.message, AppService.name);
). Ideally I would like to have this on by default.
@Injectable()
export class AppService {
constructor(private readonly logger: Logger) {}
createLog(logDto: LogDto) {
switch (logDto.level) {
case 'log':
return this.logger.log(logDto.message, logDto.params);
case 'error':
return this.logger.error(logDto.message, logDto.params);
case 'warn':
return this.logger.warn(logDto.message, logDto.params);
case 'debug':
return this.logger.debug(logDto.message, logDto.params);
case 'verbose':
return this.logger.verbose(logDto.message, logDto.params);
}
}
}
[moralis-admin-api] Info 11/29/2021, 3:26:06 PM [NestApplication] Nest application successfully started - {} +1ms
[moralis-admin-api] Info 11/29/2021, 3:26:21 PM test - {} +15s
[moralis-admin-api] Error 11/29/2021, 3:26:29 PM test - { stack: [ null ] } +8s
[moralis-admin-api] Warn 11/29/2021, 3:26:33 PM test - {} +4s
I'm sorry for the very late response, I'm quite busy recently with my personal and working life. I'll try to follow more this library that, honestly, went so far and has been used by many. Didn't expected that 😄
@alko89 is this still relevant? Maybe you can try the setContext
method of the logger?
hey @gremo! No worries. Unfortunately we abandoned the library in favor of using syslog driver in Docker instead. We needed winston for logging prod deployment in papertrail. This alternative solution is working great so far.
@gremo I am still getting this error today, I do not think this issue should be closed.
@gremo我今天仍然收到这个错误,我认为这个问题不应该被关闭。
+1
+1
+1