按请求登录Node.js

时间:2013-11-07 16:33:48

标签: node.js logging ip

我是一位经验丰富的Java开发人员,他们选择Node.js并转向异步模型。除了伐木以外,大多数事情都很顺利。在使用express。

在Node.js中开发时,我在Java中找不到类似于log4j和NDC的任何内容

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

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

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

我可以在最初进入我的请求处理程序时编写它们,但是如果没有将一堆参数传播到每个被调用的函数,则子例程内的记录器语句没有信息。我知道我可以在每个初始化其名称的js文件中创建我的记录器实例,但我还没有找到客户端IP地址的解决方案。对于运行时间较长的请求,我在记录器中设置的地址会在下一个请求进入时被覆盖,因此记录的IP会被越过。

我看过温斯顿,但即使用它也无法解决这个问题。有没有人完成这个?当您可以按IP过滤以仅查看一个用户的活动时,跟踪字段问题非常有用。

[编辑:从参数传递解决方案测试,直到我学习syslog方式]

[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

现在我只需要弄清楚如何让快速请求记录器与我的内部记录器采用相同的行条目格式,直到它全部转移到rsyslog。

3 个答案:

答案 0 :(得分:2)

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

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

由于问题对于不熟悉所有这些事情的人来说有点复杂,我在一篇文章中写下了一个明确的例子,如果你愿意,你可以重复使用。 Winston wrap非常有用: Express.js: Logging info with global unique request ID – Node.js

我希望您可以重用我的代码,也许将来Express会为此实现解决方案。

答案 1 :(得分:1)

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

Rsyslog是一个系统日志记录实用程序,可用于记录Linux计算机上任何程序的消息。首先,您需要找到您的rsylog配置信息。您可以使用以下命令执行此操作:

sudo find / -name rsyslog.conf

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

service --status-all

现在打开它找到的文件并执行以下操作:

  • 注释掉$ ActionFileDefaultTemplate一行RSYSLOG_TraditionalFileFormat
  • 取消注释$ ModLoad imtcp
  • 取消注释$ InputTCPServerRun并指定端口号1514,将使用1514 b / c Ubuntu 12.04如果我使用端口514,则rsyslog在删除权限时出现问题,其他发行版没有类似问题,您可以保留默认端口#。我通过使用iptables将端口514流量重新路由到1514
  • 来解决这个问题
  • 将$ FileCreateMode 0640更改为0644

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

$template DailyPerHostLogs,"/var/log/MyLogFile_%$YEAR%_%$MONTH%_%$DAY%.log"

#:msg,contains,"MsgName" -?DailyPerHostLogs
*.* -?DailyPerHostLogs
&~

此文件为每天创建一个新文件,并在文本中查找与MsgName一起发送的任何消息,并将其放入每日文件中,然后将其从队列中删除,以便由任何其他日志请求记录,这样我们就不会加倍记录下来。

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

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

您应该会在日志文件中看到这两行。如果你得到了,那么让我们转到能够点击日志的节点模块。

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/

魔鬼总是在细节中使用这样的设置,但我认为这会让你大部分都在那里,谷歌搜索会让你完成其余的工作。

答案 2 :(得分:1)

回答这个,因为我刚写了一篇关于如何使用continuation-local-storage来保存每个日志的“事务ID”(不用手动传播)的帖子。您可以对客户端ip,进程ID等执行相同的操作。

关注此帖:https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

但不仅仅是保存交易ID,您还需要这些: request.connection.remoteAddressprocess.pid

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