I am using ExpressWinston for logging in Node.js app. Can we log requests for each static resources which are being called ?
Logger does not log if file is found (200), but it logs when file not found (404).
For example, if request is valid like http://domain/css/existingfile.css, Logger doesnot log.
However, if request is invalid like http://domain/css/non-existingfile.css, Logger logs with proper 404 status code.
I need log when file is also found (200). How can be expressWinston configured that it logs for all the requests with whatever status code returned by server ?
Regards
The configuration I have below logs all request in a mongodb database using ExpressWinston and winston-mongodb, regardless of the status code. You can change the transport to console or file depending on what you want. You will get the relevant meta data for each request and response based on your whiteList.
expressWinston.responseWhitelist.push('body')
const requestLog = expressWinston.logger({
transports: [
new winston.transports.MongoDB({
db: db,
options: {
useNewUrlParser: true,
poolSize: 2,
autoReconnect: true
}
})
],
meta: true,
msg: (req, res) => 'HTTP {{req.method}} {{req.url}};',
requestWhitelist: [
'url',
'method',
'httpVersion',
'originalUrl',
'query',
'body'
]
});
Just replace the code in the transports array with
transports: [
new winston.transports.Console()
]
if you want to display in the console.
Related
const server = fastify({
logger: {
level: process.env.LOGLEVEL || 'debug',
prettyPrint:
process.env.ENVIRONMENT === 'local'
? {
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname',
}
: false,
},
});
LOGLEVEL is set to trace. But my requests are being logged at info level, which is higher than I want it to be:
[19:55:00] INFO: request completed
res: {
"statusCode": 200
}
responseTime: 8.38587498664856
reqId: "req-1"
I don't think metrics like that belong at info level. How can I alter the logging setup so that request logging is at the trace level? I don't see any setting for this in the docs about logging.
There is an official server option, disableRequestLogging, to fully disable it.
Then it is up to you to log with customized level in onRequest and onRequests hooks.
I'm using Express 4.17.1 — and Winston 3.3.3 / Morgan 1.10.0 for logging purposes, which I've managed to configure in this way:
import winston from "winston";
const options = {
console: {
colorize: true,
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.printf((msg) => {
return `${msg.timestamp} [${msg.level}] - ${msg.message}`;
})
),
handleExceptions: true,
json: true,
level: "debug",
},
};
const logger = winston.createLogger({
exitOnError: false,
transports: [new winston.transports.Console(options.console)], // alert > error > warning > notice > info > debug
});
logger.stream = {
write: (message) => {
logger.info(message.slice(0, -1)); // ...use lowest log level so the output will be picked up by any transports
},
};
export { logger };
I then import the Winston config inside application.js where all the Express setup is done like this:
import express from "express";
import morgan from "morgan";
import { logger } from "./config/winston.js";
const app = express();
app.use(express.json());
// ...some more settings
app.use(morgan("dev", { stream: logger.stream })); // combined, dev
// ...route Definitions
export { app };
The issue I have is with some log statements that looks like are automatically handled by Winston (I guess) based on the Express route that was processed (which I like), but they are being logged after all the usual statements for the corresponding workflow. This is an example:
2021-03-03T16:25:22.199Z [info] - Searching all customers...
{
method: 'select',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [],
__knexQueryUid: 'dFKYVOlaQyJswbxoex7Y6',
sql: 'select `customers`.* from `customers`'
}
2021-03-03T16:25:22.203Z [info] - Done with all customers workflow...
2021-03-03T16:25:22.215Z [info] - GET /api/customers 200 11.727 ms - 395
I would expect 2021-03-03T16:25:22.215Z [info] - GET /api/customers 200 11.727 ms - 395 to be the very first piece in that workflow because it's the start of it, but it's being logged at the end — which is kind of confusing.
Is there a way to fix this or is this like that by design? If it can be fixed, what should I add/remove/tweak in the Winston config or anywhere else.
According to the morgan-documentation, there's a setting which allows you to write the access-log on request instead of on response (with the latter being the default):
Write log line on request instead of response. This means that a
requests will be logged even if the server crashes, but data from the
response (like the response code, content length, etc.) cannot be
logged.
So passing { immediate: true } to morgan should make the log appear at the beginning of the workflow, but the log will obviously only contain request related data.
i was reading through the winston documentation and I came across the following statement
A transport is essentially a storage device for your logs
So I assumed if i set up a http transport i would be able to aggregate the logs somewhere else. In my case in an application running in localhost:3210
Does anybody know why I'm not receiving the log I'm trying to send ?
Here is my code:
import { createLogger, format, transports } from 'winston';
const { combine, timestamp, label, printf} = format;
const myFormat = printf(({ level, message, label, timestamp }) => {
return `${timestamp} [${label}] ${level}: ${message}`;
});
export const logger = createLogger({
format: combine(label({ label: 'Test Service' }), timestamp(), myFormat),
transports: [
new transports.Http({
host: 'localhost',
port: 3210,
path: '/'
})
]
});
logger.log({
level: 'info',
message: `Hello there`
});
Try logger.info('Hello there');. Also, no idea how your server looks like, but make sure it has a defined POST method with the required path.
I'm creating a logging framework using winston. Basically using built in winston http transport. My question is, how should I catch any http exceptions that might have occurred while making http post request due to invalid host/path/auth. Below is my code structure-
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf } = format;
const transportOptions = {
host: 'host',
port: 'port',
path: '/',
auth: '',
};
const myFormat = printf(debug => {
var msg = {
timestamp: debug.timestamp,
label: debug.label,
level: debug.level,
message: debug.message,
};
return JSON.stringify(msg);
});
const logger = createLogger({
level: 'debug',
format: combine(label({ label: 'label' }), timestamp(), myFormat),
transports: [
new transports.Console(),
new transports.Http(transportOptions),
],
json: false,
});
logger.info('Test');
If I provide wrong value in transportOptions it just does nothing. I want my framework through some sort of exception so that I would know when any error/exception occurs. Can anyone please give me any suggestion?
According to https://github.com/winstonjs/winston/blob/master/lib/winston/transports/http.js#L57 , it looks like the HTTP transport emits a 'warn' event if the HTTP response code isn't 200. So as long as your server returns non-200 when there's an error, then you could listen to the 'warn' event from your transport and process the error accordingly (throw an exception or whatever you want). Here is example code (I tested and it works):
// Declare your transport outside the logger definition
const t = new transports.Http(transportOptions);
...
t.on('warn', (e) => console.log('warning! ' + e));
logger.info('Test'); // 'warning! ...'
Note that if the server gives no response, then the transport doesn't report a warning; whether that is a bug or feature I'm not sure... :)
I have implemented Winston to log my nodejs app.
Currently I am writing the log to log files using the "DailyRotateFile" transport of Winston, and outputting the log data to the console.
I want to add an additional transport that emits the log message to a socket so that I can output it to the web interface I have created using Express, through socket.io.
This is the current way I have set up Winston:
var logger = new winston.Logger({
transports: [
new winston.transports.DailyRotateFile({
level: 'info',
filename: './Logs/server',
datePattern: '.yyyy-MM-dd.log',
handleExceptions: true,
json: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: false
}),
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
})
],
exitOnError: false
})
This is the code the I currently use to emit the log message:
var logStream = logger.stream({
start: -1
})
logStream.on('log', function(log){
console.log('LOG STREAM')
//console.log(log)
io.emit('logger', log);
})
This however continuously outputs "LOG STREAM" to the nodejs console when I start the server, and doesn't emit anything when I use the logger.info command.
EDIT
So it looks like the reason the it continues to output "LOG STREAM" is because it is sending all the messages that have been saved in the log file, even though I set "start -1"
I would really appreciate any suggestions as how to correctly achieve this. TIA!
This is how I managed to achieve sending Winston logs to the browser
I added the following transport:
new winston.transports.Webhook({
host: '192.168.51.242',
port: 8102,
}),
I then created a TCP port to receive the log messages:
http.createServer(function(req, res){
var logMsg = '';
req.on('data', function(data){
logMsg += data.toString()
})
req.on('end', function(data){
io.emit('logger', logMsg)
})
}).listen(8102)
every time I receive data to the port, I emit it using Socket.IO to my Angualr interface