How can I change the log level for requests in Fastify? - fastify

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.

Related

Express logs resource usage after everything happened for that operation

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.

Can't send log from Hapi-Pino to Elasticsearch

I'm building server for a website use hapi and hapi-pino for logging.
I want to analyze log (about status code, route, timestamp) for some business purpose. I use elasticsearch and kibana to do it
Between hapi-pino and Elasticsearch, I try to use pino-elasticsearch to send log. However, it didn't work, elasticsearch didn't get anything
This is my code for registering hapi-pino:
const streamToElastic = PinoElasticsearch({
index: 'api',
type: 'log',
consistency: 'one',
node: 'http://elastic:changeme#localhost:9200',
'es-version': 6,
'bulk-size': 200,
ecs: true
});
await server.register({
plugin: HapiPino,
options: {
logPayload: true,
prettyPrint: process.env.NODE_ENV !== 'production',
redact: {
paths: ['req.headers', 'payload.user.password', 'payload.file'],
remove: true
},
stream: streamToElastic
}
});
Thanks for any helps and sorry about my poor English!

ExpressWinston does not log on 200 HTTP response code

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.

How to catch errors on Winston Http Transport

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... :)

Multiple file transports in using Winston

I am attempting to use multiple transports in Winston. This is working...sorta. I have a transport set up for the app's audit log, with a custom level of 'audit', and a transport for 'info'.
var winston_mongo_options = {
level: 'audit', // level that should be logged
safe: true, //makes sure writes happen before firing log event
db: config.db.db, // db in which to write logs
host: config.db.host,
port: config.db.port,
collection: config.db.audit_collection // collection we want logging to occur
};
if (config.db.user) {
winston_mongo_options.username = config.db.user;
winston_mongo_options.password = config.db.pass;
}
var custom_levels = winston.config.syslog.levels;
custom_levels.audit = 8;
var logger = new (winston.Logger)({
levels: custom_levels,
transports : [
new (winston.transports.MongoDB)(winston_mongo_options),
new (winston.transports.File)({
level: 'info',
silent: false,
colorize: true,
timestamp: true,
filename: config.logs.debug,
maxsize: 500000,
maxFiles: 5,
json: true
})
],
exceptionHandlers: [
new (winston.transports.File)({
silent: false,
colorize: false,
timestamp: true,
filename: config.logs.exception,
maxsize: 500000,
maxFiles: 5,
json: true
})
]
});
module.exports.logger = logger;
Obviously, I'm requiring this file where/when I want to do any logging. The problem comes in when wanting to send certain information separately to the logs.
logger.audit('Server Started - to DB');
logger.info('Server Started - to info');
These two lines should write to separate logs. The first line gets properly written to the database AND to the info log file. What am I doing wrong?
SOLVED: The problem was how I am defining the levels. I didn't realize that the way Winston logging works, is a log will receive everything >= the level defined. So my 'info' transport being a level 0 was receiving messages sent to the 'audit' transport, which was a level 8. I set 'audit' to level 0, and it stopped showing up in the 'info' log. I then found a better solution by creation a whole new logger just for the audit database log.

Resources