简体   繁体   中英

Show Correlation Id Using Winston in Feathersjs

I want to logging in FeathersJS using winston. But, I want to logging with "correlation id". I want to find how I should create the logger, I want to make just log with the message, not supply with correlation id. Here is an example.

log.info('Here is a log');

// output [Info] [correlation-id] : Here is a log

I want to know, how the best approach to make my logger injected with correlation id that different each request?

I have a solution with my question. But I'm still not sure this will effective. I use library such as

  • cls-hooked (for scoped an request)
  • uuid (for generated an id)

Here is my changes after I first time generate FeathersJS Project.

In src/logger.js , I use getNamespace and also get a variable from namespace. Here is my example:

const { createLogger, format, transports } = require('winston');
const getNamespace = require('cls-hooked').getNamespace;

const myFormat = format.printf(({level, message, timestamp}) => {
  const loggerNamespace = getNamespace('logger');
  return `[${timestamp}] [${level}] [${loggerNamespace.get('correlationId')}]: ${message}`;
});

// Configure the Winston logger. For the complete documentation see https://github.com/winstonjs/winston
const logger = createLogger({
  // To see more detailed errors, change this to 'debug'
  level: 'info',
  format: format.combine(
    format.timestamp(),
    format.splat(),
    myFormat
  ),
  transports: [
    new transports.Console()
  ],
});

module.exports = logger;

After this, I finished setup my logger to get correlationId, now to make correlation each my request, I use middleware to make this happen. I will add new middleware to control correlationId in src/middleware/correlation.js . Here is my example:

const uuidv4 = require('uuid/v4');

function correlation(namespace) {
  return (req, res, next) => {
    const correlationId = uuidv4();
    req.feathers.correlationId = correlationId;
    namespace.run(() => {
      namespace.set('correlationId', correlationId);
      next();
    });
  }
}

module.exports = correlation;

After I created my own middleware, I will register that into global middleware in src/middleware/index.js . Here is my changes,

const createNameSpace = require('cls-hooked').createNamespace;
const correlation = require('./correlation');
const logNameSpace = createNameSpace('logger');

// eslint-disable-next-line no-unused-vars
module.exports = function (app) {
  // Add your custom middleware here. Remember that
  // in Express, the order matters.
  app.use(correlation(logNameSpace));
};

Until this changes, you already setup logger to get correlationId. For example, I created an hook and will add log there. I place that in src/hooks/logsHooks Here my example:

// Use this hook to manipulate incoming or outgoing data.
// For more information on hooks see: http://docs.feathersjs.com/api/hooks.html
const logger = require('../logger');
// eslint-disable-next-line no-unused-vars
module.exports = function (options = {}) {
  return async context => {
    logger.info('Test my correlation Id');
    let i = 0;
    function recursive() {
      setTimeout(() => {
        logger.debug(`My Itteration ${i}, let it request finish than run this background`);
        i++;
        if (i < 50) {
          recursive();
        }
      }, 5000);
    }
    recursive();
    return context;
  };
};

When I setup that, I think that is already meet my requirement. But I still need to test this with another case. I just test with some simple case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM