express-winston icon indicating copy to clipboard operation
express-winston copied to clipboard

errorLogger when metaField=nulll

Open jehanzebqayyum opened this issue 5 years ago • 12 comments

The errorLogger does not log anything when metaField is set to null.

app.use( expressWinston.errorLogger({ winstonInstance: logger, metaField: null }) );

jehanzebqayyum avatar Feb 25 '20 08:02 jehanzebqayyum

That causes the log metadata to be placed at the root of the log entry (see the read me) but depending on the transports you're using, this might not be what you want. What is the rest of your configuration?

yinzara avatar Feb 25 '20 15:02 yinzara

hi,

The rest of configuration, json format, console and kafka transports.

jehanzebqayyum avatar Mar 01 '20 15:03 jehanzebqayyum

The kafka transport expects log messages to have the metadata of the log messages at the "meta" property of the log entry (the default behavior of express-winston when you don't set the metaField). By setting the "metaField" to null you put it at the root of the log entry (see the readme of express-winston for the use of this field) and would be ignored by kafka. This is used for other transports like the Stackdriver transport which expect additional metadata to be at the root of the log entry. Why are you setting it to null?

yinzara avatar Mar 01 '20 18:03 yinzara

Strange! the kafka transport does pick up the messages cleanly without meta (i.e. from root message) in case of req/resp logger. Whereas the error logger does not log full details/meta fields when metaField=null.

I just wanted to have things less nested when received in ELK to match the pattern with other winston logs which are without meta

Best Regards, Jehanzeb Qayyum +971 52 898 2285

On Sun, 1 Mar 2020 at 22:01, Matthew Morrissette [email protected] wrote:

The kafka transport expects log messages to have the metadata of the log messages at the "meta" property of the log entry (the default behavior of express-winston when you don't set the metaField). By setting the "metaField" to null you put it at the root of the log entry (see the readme of express-winston for the use of this field) and would be ignored by kafka. Why are you setting it to null?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bithavoc/express-winston/issues/236?email_source=notifications&email_token=ABJV6SWONMWHRKRUPNGMYJDRFKPHDA5CNFSM4K3BPMXKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENNGDIA#issuecomment-593125792, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJV6SSQBMQRTZOY7JDZR6TRFKPHDANCNFSM4K3BPMXA .

jehanzebqayyum avatar Mar 01 '20 18:03 jehanzebqayyum

Hmmm well I might be wrong then. That seems very odd behavior to me, but I can't see any difference in the coding of the metadata mapping for errors vs normal request logging. Without more detailed information about your configuration and examples of how it's logging, I don't know how I can help you anymore.

yinzara avatar Mar 01 '20 18:03 yinzara

export const logTransports = [
  new transports.Console(),
  new transports.WinstonKafkaTransport({
    kafkaClient: {
      kafkaHost: process.env.ELK_KAFKA_HOSTS,
      clientId: 'winston-kafka-logger'
    },
    topic: process.env.ELK_KAFKA_TOPIC
  })
];

export const logFormat = format.combine(format.timestamp(), format.json(), format.prettyPrint());

export const logger = createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: logFormat,
  transports: logTransports
});


app.use(
  expressWinston.logger({
    winstonInstance: logger,
    msg: 'service',
    responseWhitelist: ['body', 'statusCode', 'statusMessage', 'headers'],
    requestWhitelist: [
      'hostname',
      'ip',
      'method',
      'secure',
      'protocol',
      'path',
      'url',
      'query',
      'headers'
    ],
    metaField: null

    /* skip: (req, res) => {
      return res.statusCode === 200;
    } */
  })
);

//express routes

//error logger
app.use(
  expressWinston.errorLogger({
    winstonInstance: logger
    //metaField: null //does not log anything
  })
);

// Global express error handler

jehanzebqayyum avatar Mar 02 '20 11:03 jehanzebqayyum

If you remove the metaField from the errorLogger (like you have it), do you start to get metadata under the "meta" field? Do you have an example? I'm reading through the code and I can't find anything that varies between the two.

yinzara avatar Mar 02 '20 17:03 yinzara

as of now i commented metaField: null, and its logging the error stats/details under meta. If i un-comment it will not log an error entry . I will post the 2 example logs (with/without metaField=null).

jehanzebqayyum avatar Mar 02 '20 17:03 jehanzebqayyum

Without metaField=null { meta: { error: Error: baddddd at index.js:126:9 ..., level: 'error', message: 'uncaughtException: baddddd\n' + 'Error: baddddd\n' + ' at index.js:126:9\n' + ' ...', exception: true, date: 'Tue Mar 03 2020 12:27:20 GMT+0400 (Gulf Standard Time)', process: { pid: 12812, uid: null, gid: null, cwd: 'backend', execPath: 'c:\\nvm\\root\\node.exe', version: 'v12.14.0', argv: [ 'node', 'index.js' ], memoryUsage: { rss: 111165440, heapTotal: 83271680, heapUsed: 39301544, external: 1949438 } }, os: { loadavg: [ 0, 0, 0 ], uptime: 3029658 }, trace: [ { column: 9, file: 'index.js', function: null, line: 126, method: null, native: false }, { column: 5, file: 'layer.js', function: 'Layer.handle [as handle_request]', line: 95, method: 'handle [as handle_request]', native: false }, { column: 13, file: 'route.js', function: 'next', line: 137, method: null, native: false }, { column: 3, file: 'route.js', function: 'Route.dispatch', line: 112, method: 'dispatch', native: false }, { column: 5, file: 'layer.js', function: 'Layer.handle [as handle_request]', line: 95, method: 'handle [as handle_request]', native: false }, { column: 22, file: 'index.js', function: null, line: 281, method: null, native: false }, ], req: { url: '/health', headers: { host: 'localhost:4000', connection: 'keep-alive', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', 'sec-fetch-user': '?1', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'sec-fetch-site': 'none', 'sec-fetch-mode': 'navigate', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'if-none-match': 'W/"f-RQ8OySFd+KR+AvtJ7qImjtT0D/0"' }, method: 'GET', httpVersion: '1.1', originalUrl: '/health', query: {} } }, level: 'error', message: 'middlewareError', timestamp: '2020-03-03T08:27:20.375Z' } { req: { hostname: 'localhost', ip: '::1', method: 'GET', secure: false, protocol: 'http', path: '/health', url: '/health', query: {}, headers: { host: 'localhost:4000', connection: 'keep-alive', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', 'sec-fetch-user': '?1', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'sec-fetch-site': 'none', 'sec-fetch-mode': 'navigate', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'if-none-match': 'W/"f-RQ8OySFd+KR+AvtJ7qImjtT0D/0"' } }, res: { body: '<!DOCTYPE html>\n' + '<html lang="en">\n' + '<head>\n' + '<meta charset="utf-8">\n' + '<title>Error</title>\n' + '</head>\n' + '<body>\n' + '<pre>Error: baddddd<br> &nbsp; &nbsp;at ' + '</body>\n' + '</html>\n', statusCode: 500, statusMessage: 'Internal Server Error' }, responseTime: 134, level: 'info', message: 'service', timestamp: '2020-03-03T08:27:20.436Z' }

With metaField=null

{ req: { hostname: 'localhost', ip: '::1', method: 'GET', secure: false, protocol: 'http', path: '/health', url: '/health', query: {}, headers: { host: 'localhost:4000', connection: 'keep-alive', 'cache-control': 'max-age=0', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', 'sec-fetch-user': '?1', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'sec-fetch-site': 'none', 'sec-fetch-mode': 'navigate', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8' } }, res: { body: '<!DOCTYPE html>\n' + '<html lang="en">\n' + '<head>\n' + '<meta charset="utf-8">\n' + '<title>Error</title>\n' + '</head>\n' + '<body>\n' + '<pre>Error: baddddd<br> &nbsp; &nbsp;at ' + '</body>\n' + '</html>\n', statusCode: 500, statusMessage: 'Internal Server Error' }, responseTime: 81, level: 'info', message: 'service', timestamp: '2020-03-03T08:32:35.735Z' }

As you notice the error logger did not log anything in 2nd case

jehanzebqayyum avatar Mar 03 '20 08:03 jehanzebqayyum

any update on this? Same issue

mi-mazouz avatar Jun 10 '20 11:06 mi-mazouz

same issue for me

xiaoina avatar Jun 30 '20 16:06 xiaoina

Ok I have found the issue, and a fix, but not the reason.

lets begin with the fix: add/set the following to your config:

metaField: null,
blacklistedMetaFields: ['exception'],

My investigation so far (which I am gonna drop cause this is good enough for me): Q: So what is exception? A: it's just a boolean (specifically true every time since it is an error).

Q: Is it the key or the value that is the problem? A: well.. I do not know

Let me elaborate on the last answer I have tried the following with a custom error-extractor:

  • exception: 'true' <- string, works ✅
  • exception: 'false' <- string, works ✅
  • exception: true <- boolean, broken 🛑
  • exception: false <- boolean, works ✅
  • exception2: true <- boolean, works ✅

So assuming you do not need the specific exception prop just blacklist it and get it working!

JohnLindahlTech avatar Jul 20 '20 11:07 JohnLindahlTech