每个请求在Node.js中logging

我是一位经验丰富的Java开发人员,他挑选了Node.js,并将其转换为asynchronous模型。 除了日志以外,大多数情况都很好。 在使用express的Node.js中进行开发时,我无法在Java中find类似于log4j和NDC的任何内容。

我的目标是让每个日志语句自动添加以下信息:

[2013-11-07 11:17:04.615 serverScript INFO 7036 192.168.7.209]

这包括时间戳,写这个语句(模块化节点应用程序)的js文件的名称,debugging级别,进程ID(正在运行的集群)以及客户端的IP地址。

我可以把它写到最初进入我的请求处理程序时,但没有传播一堆参数给每个被调用的函数,子程序内的logging器语句没有信息。 我知道我可以在每个js文件中创build一个logging器实例来初始化它的名字,但是我还没有找出客户端IP地址的解决scheme。 对于长时间运行的请求,当下一个请求进入时,我在logging器中设置的地址将被覆盖,因此logging的IP会越过。

我已经看过温斯顿,但即使是这样,也没能解决这个问题。 有没有人做到这一点? 当您可以通过IP过滤只查看一个用户的活动时,这是非常有用的跟踪字段问题。

[编辑:从parameter passing的解决scheme,直到我学习syslog的方式testing]

[2013-11-07 14:29:28.641 server INFO 7527 192.168.7.209] Got request from 192.168.7.209 for /ionmed/executeQuery? [2013-11-07 14:29:28.641 router INFO 7527 192.168.7.209] About to route a request for /ionmed/executeQuery, method=POST [2013-11-07 14:29:28.642 router INFO 7527 192.168.7.209] getting POSTed data [2013-11-07 14:29:28.642 router INFO 7527 192.168.7.209] POST params: {"sqlQuery":"select sleep(10)","sessionStart":"1383852558799","rand":"0.5510970998368581","jsessionid":"117DBAA89F599D923AF80D4AB171BDDF"} [2013-11-07 14:29:28.642 requestHandlers INFO 7527 192.168.7.209] 'query' was called. [2013-11-07 14:29:28.642 requestHandlers INFO 7527 192.168.7.209] select sleep(10) [2013-11-07 14:29:30.673 server INFO 7527 192.168.7.217] Got request from 192.168.7.217 for / [2013-11-07 14:29:30.673 router INFO 7527 192.168.7.217] About to route a request for /, method=GET [2013-11-07 14:29:30.673 router INFO 7527 192.168.7.217] No request handler found for /; serving as file [2013-11-07 14:29:30.673 router INFO 7527 192.168.7.217] Request handler 'serveFile' was called to get: /index.html [192.168.7.217 Thu, 07 Nov 2013 19:29:30 GMT] HTTP/1.1 GET "/node/" 200 "Mozilla/5.0 (iPod; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3" [2013-11-07 14:29:33.578 server INFO 7527 192.168.7.217] Got request from 192.168.7.217 for / [2013-11-07 14:29:33.578 router INFO 7527 192.168.7.217] About to route a request for /, method=GET [2013-11-07 14:29:33.578 router INFO 7527 192.168.7.217] No request handler found for /; serving as file [2013-11-07 14:29:33.579 router INFO 7527 192.168.7.217] Request handler 'serveFile' was called to get: /index.html [192.168.7.217 Thu, 07 Nov 2013 19:29:33 GMT] HTTP/1.1 GET "/node/" 200 "Mozilla/5.0 (iPod; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3" [2013-11-07 14:29:38.644 requestHandlers INFO 7527 192.168.7.209] sending response [192.168.7.209 Thu, 07 Nov 2013 19:29:38 GMT] HTTP/1.1 POST "/node/ionmed/executeQuery?" 200 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:25.0) Gecko/20100101 Firefox/25.0" [2013-11-07 14:29:41.540 server INFO 7527 192.168.7.217] Got request from 192.168.7.217 for / [2013-11-07 14:29:41.541 router INFO 7527 192.168.7.217] About to route a request for /, method=GET [2013-11-07 14:29:41.541 router INFO 7527 192.168.7.217] No request handler found for /; serving as file [2013-11-07 14:29:41.541 router INFO 7527 192.168.7.217] Request handler 'serveFile' was called to get: /index.html [192.168.7.217 Thu, 07 Nov 2013 19:29:41 GMT] HTTP/1.1 GET "/node/" 200 "Mozilla/5.0 (iPod; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3" [2013-11-07 14:29:45.146 server INFO 7527 192.168.7.209] RLz6tmJ7KTH2R16VCVTX: bye {"user":"1"} [2013-11-07 14:29:45.176 server INFO 7527 192.168.7.209] RLz6tmJ7KTH2R16VCVTX: disconnected 

现在我只需要弄清楚如何让快速请求logging器与我的内部logging器处于相同的行input格式,直到它全部移动到rsyslog。

这些说明来自我设置的Ubuntu 12.04发行版,但是它们应该非常适用于RHEL,Fedora,CentOS等。

Rsyslog是一个系统日志工具,可以用来在Linux机器上logging来自任何程序的消息。 首先你需要find你的rsylogconfiguration信息。 你可以用下面的命令来做到这一点:

 sudo find / -name rsyslog.conf 

如果找不到configuration文件,可以使用以下命令列出正在运行的服务以查看rsyslog是否在您的机器上:

 service --status-all 

现在打开find的文件并执行以下操作:

  • 注释掉行$ ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
  • 取消注释$ ModLoad imtcp
  • 取消注释$ InputTCPServerRun并指定端口号1514,将使用1514 b / c Ubuntu 12.04 rsyslog有一个问题,如果我使用端口514删除权限,其他发行没有类似的问题,你可以保持默认的端口#。 我通过使用iptables将端口514的stream量redirect到1514来解决这个问题
  • 将$ FileCreateMode 0640更改为0644

现在我创build了一个名为/etc/rsyslog.d/10.conf的文件(这是rsyslog的一个辅助configuration文件,我们可以过滤消息,名称日志文件等),并添加以下内容:

 $template DailyPerHostLogs,"/var/log/MyLogFile_%$YEAR%_%$MONTH%_%$DAY%.log" #:msg,contains,"MsgName" -?DailyPerHostLogs *.* -?DailyPerHostLogs &~ 

该文件为每一天创build一个新文件,并find任何与文本中的MsgName一起发送的消息,并将其放入日常文件中,然后将其从队列中删除,以便被任何其他日志请求logging下来,所以我们不logging它。

现在你可以重新启动你正在使用的机器,这一切都应该工作。 您可以通过在/ var / log中查找上面10.conf中定义的文件来检查。 通过发出以下命令从命令行中inputlogging器:

 logger this is from the command line echo "this is from the tcp port" > /dev/tcp/127.0.0.1/1514 

你应该看到这两行popup日志文件。 如果你明白了,那就让我们继续看看能够打日志的节点模块。

 var net = require('net'); var client = net.connect({port: this.1514}, function(){ console.log("Open"); }); client.write(' ' + "sMsgName: What"+ ' ' + "hath" + ' ' + "God wrought?" + '\n'); //Do everything else your program needs. . . 

写的'\ n'告诉rsyslog我们完成了这一行。 此外,您将需要预先过滤的空间工作: http : //www.rsyslog.com/log-normalization-and-the-leading-space/

魔鬼总是在这样的设置细节,但我认为这会让你大部分的方式,谷歌search将让你剩下的路。

回答这个问题,我刚刚写了一篇关于如何使用continuation-local-storage来保存每个日志的“事务ID”(不需要手动传播)的文章。 你可以做同样的客户端IP,进程ID等

按照这个post: https : //datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

但是,不要只保存一个事务ID,你也需要这些: request.connection.remoteAddressprocess.pid

如果您在这里或那里有任何问题,请告诉我,我会回答他们。

前一段时间我也遇到了同样的问题,最后我可以花点时间研究一下。 @ibash的方法和他的post让我率先解决了我的问题(谢谢你的帮助)。 我只多走了一些步骤,以便在日志中自动打印每个请求的唯一标识。 在您的情况下,您可以使用相同的方法添加每个请求所需的起始和目标IP以及所有信息,并在所有日志中自动打印。

我的做法: – 正如@ibash解释,我使用continuation-local-storage在每个请求的所有模块之间共享信息。 因此,我为每个请求生成一个唯一的ID并将其存储在使用此库创build的命名空间中 – 为了从命名空间共享中恢复信息并覆盖我使用的所有Winston方法,我封装了Winston库(以一种非常简单的方式)string唯一的ID。 显然在你的情况下,你应该添加所有你需要的信息,你以前已经存储在库的命名空间。

由于向人们解释这些问题有点复杂,所以我在一篇文章中写下了一个明确的例子,如果你愿意,你可以重复使用。 Winston wrap可能非常有用: Express.js:使用全局唯一请求标识logging信息 – Node.js

我希望你可以重用我的代码,也许在未来Express实现这个解决scheme。