问题描述
我正在为NodeJS应用程序使用 winston ,以具有结构化的日志记录格式(JSON)稍后我将处理并通过Filebeat发送到Logstash.
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.
根据PM2和 12factor.net 的建议,我正在使用 winston.transports.Console进行日志记录
传输并让PM2处理我的 ecosystem.json
中的 stdout
和 stderr
.
As suggested by PM2 and 12factor.net I'm logging using winston.transports.Console
transport and letting PM2 to handle the stdout
and stderr
in my ecosystem.json
.
在我的 logger.js
模块中,我具有以下内容:
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;
};
在我的主应用程序文件 server.js
中,我运行以下代码来模拟引发未处理的异常,需要并没有找到虚假的依赖项:
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");
最后,在我的PM2 ecosystem.json
中,我具有以下内容:
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
}
]
}
当我运行 pm2时,启动生态系统.json
的日志文件内容如下:
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"
}
如您所见,PM2正在将未捕获的异常添加到日志文件,即此代码:
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)
这破坏了日志的格式/结构,因为它是纯文本而不是我从 winston
收到的格式化JSON.
This breaks the format/structure of my logs, since it's plain text instead of the formatted JSON I receive from winston
.
我确信这是PM2问题/配置错误,因为如果我运行 node server.js
,则控制台输出只是JSON对象.
I'm confident this is a PM2 issue/misconfiguration, because if I run node server.js
the console output are just the JSON objects.
我是否必须在PM2 ecosystem.json
文件中设置特定属性?
Do I have to setup a specific property in PM2 ecosystem.json
file?
如何告诉PM2忽略Node的 uncaughtException
?
How can I tell PM2 to ignore Node's uncaughtException
?
我想出的唯一选择(我还没有尝试过)是将我的winston传输更改为 winston.transports.File
,重定向 ALL 登录到 stdout
并告诉PM2将 stderr
保存在另一个文件中,但我宁愿坚持使用控制台方法.
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 stdout
and tell PM2 to save stderr
in a different file, but I'd rather stick with the console aproach.
推荐答案
防止PM2记录 uncaughtException
的一种方法是将-no-pmx
传递为标志,即 pm2 start --no-pmx myapp.js
或将 pmx:false
添加到 ecosystem.json
文件中.
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.
这将禁用PMX注入PM2,PM2负责记录此 uncaughtException
.
This disables PMX injection into PM2, which is the responsible for logging this uncaughtException
.
这篇关于Winston + PM2两次记录uncaughtException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!