I am creating a nodejs app and using Winston 3.0 for logging. The requirement is logs should be json format in Kibana like so
{"message":"the_log_message","level":"info","log_timestamp":"2019-12-14T21:28:44+05:30","service_name":"foo","service_id":"1.0.0"}
Following are the things I am able to achieve
JSON.stringify
also does not help'use strict';
const {createLogger, format, transports} = require('winston');
const moment = require('moment-timezone');
const env = process.env.NODE_ENV || 'development';
const serviceId = process.env.npm_package_name;
const serviceVersion = process.env.npm_package_version;
const appendTimestamp = format((info, opts) => {
if (opts.tz)
info.log_timestamp = moment().tz(opts.tz).format();
return info;
});
const addAppNameFormat = format(info => {
info.service_name = serviceId;
return info;
});
const addAppVersionFormat = format(info => {
info.service_id = serviceVersion;
return info;
});
const logger = createLogger({
// change level if in dev environment versus production
level: env === 'prd' ? 'info' : 'debug',
format: format.combine(
appendTimestamp({tz: Intl.DateTimeFormat().resolvedOptions().timeZone}),
addAppNameFormat(),
addAppVersionFormat(),
format.json()
),
transports: [
new transports.Console()
]
});
module.exports = logger;
Additionally adding the logger file which works fine but does not print Json format logs
const { createLogger, format, transports } = require('winston');
const moment = require('moment-timezone');
const appendTimestamp = format((info, opts) => {
if(opts.tz)
info.timestamp = moment().tz(opts.tz).format();
return info;
});
const logger = createLogger({
// change level if in dev environment versus production
level: env === 'prd' ? 'info' : 'debug',
format: format.combine(
appendTimestamp({ tz: Intl.DateTimeFormat().resolvedOptions().timeZone }),
format.json()
),
transports: [
new transports.Console({
format: format.combine(
format.colorize(),
format.printf(
info =>
`${info.timestamp} ${process.env.npm_package_name} [${process.env.npm_package_version}] ${info.level} [${info.label}]: ${JSON.stringify(info.message)}`
)
)
})
]
});
module.exports = logger;
EDIT1:
Made following changes in the code. Adding a space before my logs are generating the logs in Kibana but we are not able to parse it. If we are not using the space in return statement, logs do not generate
return ` ${value}`;
I am suspecting my Winston configuration is not supporting JSON format. Reiterating that on local machine logs are generating fine.
const logger = createLogger({
// change level if in dev environment versus production
level: env === 'prd' ? 'info' : 'debug',
format: format.combine(
appendTimestamp({tz: Intl.DateTimeFormat().resolvedOptions().timeZone}),
format.json()
),
transports: [
new transports.Console({
format: format.combine(
format.printf(
(info) => {
const value = JSON.stringify({
'log-timestamp': info.timestamp,
'service-id': process.env.NOMAD_TASK_NAME,
'service-version': process.env.npm_package_version,
'level': info.level.toUpperCase(),
'env': process.env.ENV,
'message': info.message,
'logger': process.env.npm_package_name,
'thread': 'main'
});
return ` ${value}`;
}
)
)
})
]
});
Turns out the way the Kibana was configured was incorrect. The code itself was working fine