Nodejs / Express / Winston logger: ¿cómo poner de manera elegante req.headers.username en el formato de registro?
Mi backend de nodejs / Express js utiliza el registrador Winston
.
src/utils/logger.ts
:
import winston from 'winston'
import moment from 'moment';
import os from 'os';
import process from 'process';
import request from 'express';
<p>const levels = {
error: 0,
warn: 1,
info: 2,
http: 3,
debug: 4,
}</p>
<p>const level = () => {
return 'debug'
}</p>
<p>const colors = {
error: 'red',
warn: 'yellow',
info: 'green',
http: 'magenta',
debug: 'white',
}
winston.addColors(colors)</p>
<p>const timezonedTime = () => {
return moment().local().format('YYYY-MMM-DD hh:mm:ss:ms');<br>
}; </p>
<p>const format_string = winston.format.combine(
winston.format.timestamp({format: timezonedTime}),
winston.format.colorize({ all: true }),
winston.format.printf(
(info) => <code>${info.timestamp} ${os.hostname()} ${process.pid} ${info.level}: ${info.message}</code>,
),
)</p>
<p>const format_json = winston.format.combine(
winston.format.timestamp({format: timezonedTime}),
winston.format.colorize({ all: true }),
winston.format.printf(
(info) => <code>${info.timestamp} ${os.hostname()} ${process.pid} ${info.level}: ${info.message}</code>,
),
winston.format.json(),
)</p>
<p>const options = {
conosle: {
format: format_string,
level: 'info',
handleExceptions: true,
json: false,
colorize: true,
},</p>
<p>error<em>logfile: {
filename: 'logs/error.log',
level: 'error',
format: format</em>string,
handleExceptions: true,
}, </p>
<p>all<em>logfile: {
filename: 'logs/all.log',
format: format</em>string
},</p>
<p>all<em>logfile</em>json: {
filename: 'logs/all<em>json.log',
format: format</em>json
}</p>
<p>};</p>
<p>const transports = [
new winston.transports.Console(options.conosle),
new winston.transports.File(options.error<em>logfile),
new winston.transports.File(options.all</em>logfile),
new winston.transports.File(options.all<em>logfile</em>json),
]</p>
<p>const Logger = winston.createLogger({
level: level(),
levels,
transports,
})</p>
<p>export default Logger</p>
<p>```
Mi aplicación está diseñada de tal manera que mientras un usuario haya iniciado sesión en su cuenta, la cabecera de la solicitud contendrá un campo de <code>username</code>.
Quiero poner este <code>username</code> en cada mensaje de registro causado por las funciones en los puntos finales de la API. Ahora mismo estoy haciendo:
/src/routes.ts:
<code>
app.get('/api/organizations/project', organizations.getProject);
</code>
Y:
export const getProject = catchErrors( async (req, res) => {
const username = req.header(‘username’);
if (!username) {
Logger.warn(no req.headers.username found!
);
throw new NoUsernameError();
}
const user = await findUserWithOrganizationsByUsername(username);
const userId = user.id;
const userType = user.userType;
Logger.info(User ${req.headers.username} has id and type ${userId}, ${userType};
);
const organizationId = req.query.organizationId;
const organization = await findEntityOrThrow(Organization, organizationId, {
relations: [‘users’]
});
Logger.info(User ${req.headers.username}: got organization
);
…
“`
Básicamente, en muchos pasos en el código de lógica empresarial, necesito registrar un mensaje con req.headers.username
, así como lo hacen level
y timestamp
en todas las entradas de registro.
¿Hay alguna manera elegante de ponerlo? No quiero hacer
Logger.info(User ${req.headers.username} ....bla bla bla ...
);
en cada línea de registro.
davy.ai
Sí, hay una manera de evitar repetir
req.headers.username
en cada mensaje de registro. ComoLogger
es simplemente una instancia de la clasewinston.Logger
, puedes crear un registro personalizado que extienda la claseLogger
y agregue el campousername
a cada mensaje de registro. Aquí hay un ejemplo de cómo puedes hacerlo:Luego, en tu función
getProject
, puedes crear un registro personalizado de esta manera:Y usarlo en lugar de
Logger
:De esta manera, el campo
username
se agregará a cada mensaje de registro sin tener que repetirlo en cada declaración de registro. Ten en cuenta queCustomLogger
solo anula los métodos de registro que necesitas usar. Si necesitas usar otros niveles de registro (debug
,http
, etc.), también puedes agregarlos a la definición de la clase.