Piping Morgan into Winston causes weird characters - node.js

Following this post: Node.js - logging / Use morgan and winston
I setup the logger as follows;
const winston = require('winston');
const datadogWinston = require('datadog-winston');
const os = require('os');
const logger = winston.createLogger({
level: 'info',
format: winston.format.simple(),
transports: [
new winston.transports.Console(),
new winston.transports.File({filename: 'test.log'}),
new datadogWinston({
apiKey: process.env.DATADOG_APIKEY,
hostname: os.hostname(),
service: 'korabo',
ddsource: 'nodejs',
}),
],
});
logger.stream = {
write: (message, _encoding) => {
logger.info(message);
},
};
module.exports = logger;
However, whenever winston logs an item, it ends up looking like this;
info: [0mGET /stylesheets/style.css [36m304[0m 1.550 ms - -[0m
Morgan instance;
const logger = require('./lib/logger');
const app = express();
...
app.use(morgan('dev', {stream: logger.stream}));
How can I fix those strange characters from appearing in the logs?

you can remove all ANSI colors/styles from message : Remove all ANSI colors/styles from strings
logger.stream = {
write: (message, _encoding) => {
logger.http(
message.replace(
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
""
)
);
},
};

Related

express-winston disappears in GCP Logs

Set up the use of winston and express-winston logging and stream data into GCP Logging.
Set up looks like:
import winston from 'winston';
import ExpressWinston from 'express-winston';
import { LoggingWinston } from '#google-cloud/logging-winston';
import config from '../config';
const logFormat = winston.format.printf(
(info) => `${info.timestamp} ${info.level}: ${info.message}`,
);
const transports: winston.transport[] = [
// This transport dumps into console
new winston.transports.Console({
format: winston.format.combine(winston.format.colorize(), logFormat),
}),
new LoggingWinston({
projectId: config.projectId, // its a config
});
];
const logger = winston.createLogger({
level: config.logs.level, // defaults to 'info'
transports,
format: winston.format.combine(
winston.format.colorize(),
winston.format.json(),
winston.format.prettyPrint(),
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.metadata({
fillExcept: ['message', 'level', 'timestamp'],
}),
),
});
// Whitelisting request and response bodies to be logged
ExpressWinston.requestWhitelist.push('body');
ExpressWinston.responseWhitelist.push('body');
const expressLogger = ExpressWinston.logger({
level: config.logs.level, // defaults to 'info'
format: winston.format.combine(
winston.format.colorize(),
winston.format.json(),
winston.format.prettyPrint(),
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
),
transports,
// remove the following headers from getting logged
headerBlacklist: ['authorization', 'cookie', 'set-cookie'],
colorize: true,
msg: '{{res.statusCode}} {{req.method}} {{req.url}} {{res.responseTime}}ms',
ignoreRoute: (req) =>
ignoredRoutes.indexOf(req.originalUrl || req.url) >= 0,
});
export { logger, expressLogger };
This logger is then used as follows:
import express from 'express';
import { logger, expressLogger } from './logger';
// . . .
const app = express();
app.use(expressLogger);
Importantly, all of this works great and like a charm.
e.g.
But then after a few days, the express logger stops logging -- without any error in the logs. The winston logger continues to work fine.
This forces me to restart the server to make it work again. Any suggestions on how to resolve this?
Thanks

NodeJS Winston not writing in the log file

I'm trying to use Winston to create logs, but it is not writing in the file.
I have the following file in controllers/myControler/myFile.js
const path = require('path');
const winston = require('winston');
const filename = path.join(__dirname, 'testLog.log');
const logger = winston.createLogger({
transports: [
new winston.transports.Console({ filename, level: 'error' })
]
});
exports.test = async (req, res, next) => {
logger.log({
level: 'error',
message: 'Test'
});
}
I have the file testLog.log in the root of my project.
When I run the application, I can see in the terminal:
{"level":"error","message":"Test"}
However, the testLog.log file still empty.
Thanks
new winston.transports.Console does not accept filename option.
You have to append File transport for your logger.
const logger = winston.createLogger({
transports: [
new winston.transports.Console({ level: 'error' }),
// new line
new winston.transports.File({ filename, level: 'error' }),
]
});

Update winston logger

There is an old way to use the winston logger. (version below 2.4.4)
var winston = require('winston');
//
// Configure CLI output on the default logger
//
winston.cli();
At the moment, winston version: 3.3.3.
const winston = require('winston');
const myformat = winston.format.cli({ colors: { info: 'green' }});
const logger = winston.createLogger({
transports: [
new winston.transports.Console({
format: myformat
})
]
});
winston.add(logger)
With this way, the output is
Who knows how to initialize winston to convert "% s:% s" to normal text?
const logger = winston.createLogger({
format: winston.format.splat(),
transports: [
new winston.transports.Console({
format
})
]
});
need add format

winston 3.2.1 version is not creating log file

I tried to create winston(logger file) using node js.winston 2.4.0 version its sucessfully storeing info and error in log file.but latest version its created log file but cant stored error and info messages.How to fix it
Winston.js
var winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
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' })
]
});
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
app.js
/**
* #fileoverview Root file of the application.
*/
// Import ExpressJS
const winston = require('winston');
const express = require('express');
const app = express();
// StartUp Processes
require('./startup/logging_error_startup');
require('./startup/routes_startup')(app);
require('./startup/check_security_key_startup')();
require('./startup/validation_startup')();
require('./startup/swagger_startup')(app);
require('./startup/production_startup')(app);
// Start the server
const port = process.env.PORT || 4202;
app.listen(port, () => winston.info(`Server Started and Listening on port ${port}`));
I got the output
winston] Attempt to write logs with no transports {"message":"Server Started and Listening on port 4202","level":"info"}
You need to import the logger object from Winston.js file into app.js. In your app.js code, the Winston import is for the npm package and not for the logger object created in Winston.js.
In Winston.js, export the logger object:
var winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
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' })
]
});
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
module.exports = logger;
And in app.js, use that logger object after importing.
const logger = require('./Winston'); //assuming Winston.js is in the same folder level as app.js
const express = require('express');
const app = express();
// StartUp Processes
require('./startup/logging_error_startup');
require('./startup/routes_startup')(app);
require('./startup/check_security_key_startup')();
require('./startup/validation_startup')();
require('./startup/swagger_startup')(app);
require('./startup/production_startup')(app);
// Start the server
const port = process.env.PORT || 4202;
app.listen(port, () => logger.info(`Server Started and Listening on port ${port}`));
Alternatively you can modify the default logger in your winston.js with
var winston = require('winston');
const newLogger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
transports: [.........
winston.add(newLogger);
instead of
var winston = require('winston');
const logger = winston.createLogger({....
module.exports = logger
and import the default logger in each file with
const logger = require('winston')
logger.info('log');
without dealing with relative paths each time you import the logger to different files.

Winston logging in console but not in the log files

I'm using Winston for logging in my project. I can see the logs in the console but there is no logging inside the log files.
Winston.js file
var appRoot = require('app-root-path');
var winston = require('winston');
const {transports, createLogger, format} = require('winston');
winston.addColors( winston.config.npm.colors );
const logger = winston.createLogger({
level: 'info',
format: format.combine(
format.timestamp({format:'MM-YY-DD hh:mm:ss a'}),
format.json(),
),
transports: [
new winston.transports.File({ filename: './logs/error.log', level: 'error' }),
new winston.transports.File({ handleExceptions: true,colorize:true,
json: true,filename: './logs/app.log',
})
]
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
module.exports = logger;
Server.js code
var morgan = require('morgan');
var winston = require('./server/config/winston');
Node version
8.11.3
Winston version
3.1.0
You need to make sure 'logs' folder exists. Winston doesnt take care of non-existent folder, nor giving any warning or errors.
You can put following code in your server.js
var fs = require( 'fs' );
var logDir = 'logs';
if ( !fs.existsSync( logDir ) ) {
fs.mkdirSync( logDir );
}
winston.info('Hey NODE');
Using the absolute folder path inside the winston.js solved the problem.

Resources