使用 node-bunyan-syslog 记录大消息
Logging large messages with node-bunyan-syslog
我正在使用 node-bunyan-syslog 为我的节点应用程序的 Bunyan 记录器提供系统日志流,这似乎是节点应用程序中系统日志记录的常用库。这是我的基本记录器实现:
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) spec,这表明当传输的数据包的大小超过设置的 MTU(最大传输单元)时会抛出 EMSGSIZE 错误对于正在使用的网络接口。
我的第一个想法是传递到日志语句中的 data
太大(事实上,如果我只记录小消息,错误就不会被抛出),因为它有时可能是多个大小为 KB。但是,日志消息的大小不应该与我实例化的 node-bunyan-syslog 流传输的数据包大小无关吗?
我查看了 node-bunyan-syslog 源代码,试图确定它是否将自己的消息分解为数据包,但我找不到任何这样的逻辑。
一个解决方案是首先检查建议的日志消息的大小,只有在一定大小以下时才记录,但这似乎是不必要的限制。我希望 node-bunyan-syslog 或其底层套接字库能够处理像 MTU 这样的基本协议限制,而不会将相关错误传播给用户。
我对原因的评估准确吗?这种情况下的 EMSGSIZE 错误是否是由于超过 MTU 而导致的?如何通过 Bunyan 和 node-bunyan-syslog 成功记录大消息?
这是syslog protocol itself中的基本限制。单个消息必须能够装入单个 UDP 数据包。是的,EMSGSIZE 意味着您超过了 MTU(数据 + 协议开销)。 Bunyan 无法真正弥补这一点,因为它必须向 syslog 服务器发送 syslog。
一个选项是 switch to tcp 如果您的远程系统日志服务器可以配置为接受它。
var bunyan = require('bunyan');
var bsyslog = require('bunyan-syslog');
var 日志 = bunyan.createLogger({
姓名:'foo',
流:[ {
等级:'debug',
类型:'raw',
流:bsyslog.createBunyanStream({
类型:'sys',
设施:bsyslog.local0,
主机:'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 对象:
模板(名称="bunyan"类型="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
我正在使用 node-bunyan-syslog 为我的节点应用程序的 Bunyan 记录器提供系统日志流,这似乎是节点应用程序中系统日志记录的常用库。这是我的基本记录器实现:
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) spec,这表明当传输的数据包的大小超过设置的 MTU(最大传输单元)时会抛出 EMSGSIZE 错误对于正在使用的网络接口。
我的第一个想法是传递到日志语句中的 data
太大(事实上,如果我只记录小消息,错误就不会被抛出),因为它有时可能是多个大小为 KB。但是,日志消息的大小不应该与我实例化的 node-bunyan-syslog 流传输的数据包大小无关吗?
我查看了 node-bunyan-syslog 源代码,试图确定它是否将自己的消息分解为数据包,但我找不到任何这样的逻辑。
一个解决方案是首先检查建议的日志消息的大小,只有在一定大小以下时才记录,但这似乎是不必要的限制。我希望 node-bunyan-syslog 或其底层套接字库能够处理像 MTU 这样的基本协议限制,而不会将相关错误传播给用户。
我对原因的评估准确吗?这种情况下的 EMSGSIZE 错误是否是由于超过 MTU 而导致的?如何通过 Bunyan 和 node-bunyan-syslog 成功记录大消息?
这是syslog protocol itself中的基本限制。单个消息必须能够装入单个 UDP 数据包。是的,EMSGSIZE 意味着您超过了 MTU(数据 + 协议开销)。 Bunyan 无法真正弥补这一点,因为它必须向 syslog 服务器发送 syslog。
一个选项是 switch to tcp 如果您的远程系统日志服务器可以配置为接受它。
var bunyan = require('bunyan'); var bsyslog = require('bunyan-syslog');
var 日志 = bunyan.createLogger({ 姓名:'foo', 流:[ { 等级:'debug', 类型:'raw', 流:bsyslog.createBunyanStream({ 类型:'sys', 设施:bsyslog.local0, 主机:'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 对象:
模板(名称="bunyan"类型="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