winston + PM2 logging uncaughtException twice

无人久伴 提交于 2021-02-06 13:57:11

问题


I am using winston for my NodeJS apps, to have a structured logging format (JSON) that later I will process and send to Logstash via Filebeat.

As suggested by PM2 and 12factor.net I'm logging using winston.transports.Console transport and letting PM2 to handle the stdoutand stderr in my ecosystem.json.

In my logger.js module I have the following:

"use strict";
const winston = require("winston");
// Remove logging on console
winston.remove(winston.transports.Console);
// env
const env = process.env.NODE_ENV || 'development';
const isDev = env === "development";
// The default Console transport
const defaultLogLevel = isDev ? "debug" : "info";

const consoleTransport = new winston.transports.Console({
    level: defaultLogLevel,
    colorize: true,
    json: true,
    timestamp: true,
    exceptionsLevel: "error",
    prettyPrint: false,
    handleExceptions: true,
    humanReadableUnhandledException: false,
    exitOnError: true
});

const defaultOptions = {
    transports: [
    consoleTransport
    ]
};


module.exports = function(options)
{
    let initOpts = defaultOptions;
    if(options)
    {
        Object.assign(initOpts, options);
    }
    const logger = new winston.Logger(initOpts);
    // suppress any logger errors
    logger.emitErrs = false;
    winston.handleExceptions(consoleTransport);

    return logger;
};

In my main app file server.js I run this code to simulate an unhandled Exception being thrown, a fake dependency is being required and not found:

"use strict";
var log         = require('./logger')({name: "api-messages"});
log.info("some info message");
log.error("some error message");
var notFound = require("someInexistentPackage");

Finally, in my PM2 ecosystem.json I have the following:

{
  "apps":
  [
    {
      "name"            : "my-app",
      "script"          : "server.js",
      "max_restarts"    : 1,
      "error_file"      : "~/.pm2/logs/my-app.log",
      "out_file"        : "~/.pm2/logs/my-app.log",
      "merge_logs"      : true

    }
  ]
}

When I run pm2 start ecosystem.json the contents of the log files are the following:

{
  "level": "info",
  "message": "some info message",
  "timestamp": "2017-06-08T16:10:05.967Z"
}
{
  "level": "error",
  "message": "some error message",
  "timestamp": "2017-06-08T16:10:05.968Z"
}
Error: Cannot find module 'someInexistentPackage'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/mps/Sites/my-app/server.js:10:20)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
{
  "date": "Thu Jun 08 2017 13:10:05 GMT-0300 (-03)",
  "process": {
    "pid": 50862,
    "uid": 501,
    "gid": 20,
    "cwd": "/Users/mps/Sites/my-app",
    "execPath": "/Users/mps/.nvm/versions/node/v7.10.0/bin/node",
    "version": "v7.10.0",
    "argv": [
      "/Users/mps/.nvm/versions/node/v7.10.0/bin/node",
      "/Users/mps/.nvm/versions/node/v7.10.0/lib/node_modules/pm2/lib/ProcessContainerFork.js"
    ],
    "memoryUsage": {
      "rss": 36724736,
      "heapTotal": 9879552,
      "heapUsed": 6309680,
      "external": 63983
    }
  },
  "os": {
    "loadavg": [
      2.49560546875,
      2.228515625,
      2.0205078125
    ],
    "uptime": 329559
  },
  "trace": [
    {
      "column": 15,
      "file": "module.js",
      "function": "Module._resolveFilename",
      "line": 470,
      "method": "_resolveFilename",
      "native": false
    },
    {
      "column": 25,
      "file": "module.js",
      "function": "Module._load",
      "line": 418,
      "method": "_load",
      "native": false
    },
    {
      "column": 17,
      "file": "module.js",
      "function": "Module.require",
      "line": 498,
      "method": "require",
      "native": false
    },
    {
      "column": 19,
      "file": "internal/module.js",
      "function": "require",
      "line": 20,
      "method": null,
      "native": false
    },
    {
      "column": 20,
      "file": "/Users/mps/Sites/my-app/server.js",
      "function": null,
      "line": 10,
      "method": null,
      "native": false
    },
    {
      "column": 32,
      "file": "module.js",
      "function": "Module._compile",
      "line": 571,
      "method": "_compile",
      "native": false
    },
    {
      "column": 10,
      "file": "module.js",
      "function": "Module._extensions..js",
      "line": 580,
      "method": ".js",
      "native": false
    },
    {
      "column": 32,
      "file": "module.js",
      "function": "Module.load",
      "line": 488,
      "method": "load",
      "native": false
    },
    {
      "column": 12,
      "file": "module.js",
      "function": "tryModuleLoad",
      "line": 447,
      "method": null,
      "native": false
    },
    {
      "column": 3,
      "file": "module.js",
      "function": "Module._load",
      "line": 439,
      "method": "_load",
      "native": false
    }
  ],
  "stack": [
    "Error: Cannot find module 'someInexistentPackage'",
    "    at Function.Module._resolveFilename (module.js:470:15)",
    "    at Function.Module._load (module.js:418:25)",
    "    at Module.require (module.js:498:17)",
    "    at require (internal/module.js:20:19)",
    "    at Object.<anonymous> (/Users/mps/Sites/my-app/server.js:10:20)",
    "    at Module._compile (module.js:571:32)",
    "    at Object.Module._extensions..js (module.js:580:10)",
    "    at Module.load (module.js:488:32)",
    "    at tryModuleLoad (module.js:447:12)",
    "    at Function.Module._load (module.js:439:3)"
  ],
  "level": "error",
  "message": "uncaughtException: Cannot find module 'someInexistentPackage'",
  "timestamp": "2017-06-08T16:10:05.972Z"
}

As you can see, PM2 is adding the uncaught Exception to the log file, i.e. this code:

Error: Cannot find module 'someInexistentPackage'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/mps/Sites/my-app/server.js:10:20)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)

This breaks the format/structure of my logs, since it's plain text instead of the formatted JSON I receive from winston.

I'm confident this is a PM2 issue/misconfiguration, because if I run node server.js the console output are just the JSON objects.

Do I have to setup a specific property in PM2 ecosystem.json file?

How can I tell PM2 to ignore Node's uncaughtException?

The only alternative I have come up with (which I haven't tried yet), is to change my winston transport to winston.transports.File, redirect ALL logs to stdoutand tell PM2 to save stderr in a different file, but I'd rather stick with the console aproach.


回答1:


One way to prevent PM2 from logging the uncaughtException is to pass --no-pmx as a flag, i.e. pm2 start --no-pmx myapp.js or to add pmx: false to the ecosystem.json file.

This disables PMX injection into PM2, which is the responsible for logging this uncaughtException.



来源:https://stackoverflow.com/questions/44441017/winston-pm2-logging-uncaughtexception-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!