0

我正在使用node-bunyan-syslog为我的节点应用程序的 Bunyan 记录器提供 syslog 流,这似乎是节点应用程序中 syslog 日志记录的常用库。这是我的基本记录器实现:

var bunyan = require('bunyan');
var syslog = require('bunyan-syslog');

var syslogStream = syslog.createBunyanStream({
    host: 'my.remote.host',
    port: 514,
    type: 'udp'
});

module.exports = bunyan.createLogger({
    name: 'alert-creator-logger',
    streams: [
        {
            level: 'debug',
            type: 'raw',
            stream: syslogStream
        }
    ]
}); 

每隔一段时间,这个日志语句:

logger.debug('Processing message: ' + JSON.stringify(data));

引发以下错误:

events.js:85
  throw er; // Unhandled 'error' event
        ^
Error: send EMSGSIZE
    at exports._errnoException (util.js:746:11)
    at SendWrap.afterSend [as oncomplete] (dgram.js:348:23)

因为我的流配置为使用 UDP,所以我阅读了UDP(7) 规范,这表明当正在传输的数据包的大小超过为正在传输的网络接口设置的 MTU(最大传输单元)时,会引发 EMSGSIZE 错误用过的。

我的第一个想法是data传递给日志语句的内容太大(实际上,如果我只记录小消息,错误就会停止抛出),因为它有时可能是多个 KB 大小。但是,日志消息的大小不应该与我实例化的 node-bunyan-syslog 流传输的数据包大小无关吗?

我查看了 node-bunyan-syslog 源代码,试图确定它是否将自己的消息分解为数据包,但我找不到任何这样的逻辑。

一种解决方案是首先检查建议的日志消息的大小,并且仅在小于一定大小时才记录,但这似乎没有必要的限制。我希望 node-bunyan-syslog 或其底层套接字库能够处理诸如 MTU 之类的基本协议限制,而不会将相关错误传播给用户。

我对原因的评估是否准确?此上下文中的 EMSGSIZE 错误是否是由超过 MTU 引起的?如何通过 Bunyan 和 node-bunyan-syslog 成功记录大消息?

4

2 回答 2

1

这是syslog 协议本身的一个基本限制。单个消息必须能够适合单个 UDP 数据包。是的,EMSGSIZE 意味着您超过了 MTU(数据 + 协议开销)。Bunyan 无法真正弥补这一点,因为它必须向 syslog 服务器发送 syslog。

如果您的远程系统日志服务器可以配置为接受它,则一种选择是切换到 tcp 。

于 2015-05-22T18:17:54.640 回答
-1

var bunyan = require('bunyan'); var bsyslog = require('bunyan-syslog');

var log = bunyan.createLogger({ name: 'foo', streams: [ { level: 'debug', type: 'raw', stream: bsyslog.createBunyanStream({ type: 'sys', facility: bsyslog.local0, host : '192.168.0.1', 端口: 514 }) }] });

log.debug({foo: 'bar'}, 'hello %s', 'world');

差不多就是这样。您创建一个 syslog 流,并将其指向 syslog 服务器(默认为 UDP;您可以通过在构造函数中设置 type: tcp 来强制 TCP);默认是在 127.0.0.1:514 上使用设施用户和系统日志服务器。请注意,您必须在顶级流对象中将 type: 'raw' 传递给 bunyan,否则这将不起作用。

如果您希望日志采用正常的 bunyan 格式,rsyslog 允许您设置模板以将其格式化为 JSON 对象:

模板(name="bunyan" type="string" string="%msg:R,ERE,1,FIELD:(\{.*\})--end%\n")

local0.* /var/log/application.log;bunyan

你也可以使用旧的 $template 语法来写这个:

$template bunyan,"%msg:R,ERE,1,FIELD:({.*})--end%\n"

local0.* /var/log/application.log;bunyan

于 2019-01-08T10:45:07.013 回答