我一直在看RFC5424来查找正式指定的标记,这将结束syslog事件。
不幸的是我找不到它。 所以,如果我想实现一些小的系统日志服务器,对某些消息作出反应什么是结束消息的标记(是的,事件通常是一条线,但我只是无法在规范中find它)
澄清 :
我把它称为事件,因为我把一条消息与一条线联系起来。 事件可能是一些事情
Type: foo Source: webservers
而给我的信息是这样的:
Type: foo Source: webservers
http://tools.ietf.org/html/rfc5424#section-6定义:
SYSLOG-MSG = HEADER SP STRUCTURED-DATA [SP MSG]
STRUCTURED-DATA和MSG都不能告诉我这些字段是如何结束的。 特别是MSG被定义为MSG-ANY / MSG-UTF8 ,它几乎扩展到任何东西。 没有什么说一个换行标志着结束(或一个8或一个这个问题)。 给出示例消息(6.5节):
这是一个有效的消息,或者2个有效的消息,取决于你说任何MSG元素中都不能出现HEADER元素:
文字空白
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - <34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 | is this an end marker?
\t代表一个标签
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\t<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 | is this an end marker?
\n代表换行符
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\n<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 | is this an end marker?
要么我误解了RFC,要么没有提到。 在RFC中指定的大小只是说我可以使用的最小长度是多less…
回答? :显然我读的是错误的RFC。 一个需要去的具体运输RFC和保持, http : //tools.ietf.org/html/rfc5426#section-3.1说这一切的UDP传输。
@joechip:由于您的意见和答案让我实际阅读更多的运输RFC中,我会很乐意接受你的答案,如果你更新一下这个方向:)
那么,“系统日志事件”是什么意思? 如果你引用系统日志消息,RFC5424明确地定义了系统日志消息的语法在其第6部分,如何从一个系统日志应用程序传输到另一个系统日志应用程序。
如果您指的是接收系统日志应用程序如何将它们存储在日志文件中,那么典型的系统日志实现只是使用换行符将一条logging与另一条logging相分离,而这通常不是可configuration的行为。 此外,系统日志logging的文本字段也可以包含换行符,这使正确parsing日志文件的任务变得复杂。 通常可以parsing它,因为每个系统日志logging都以date,时间,主机和标签的通常顺序开始,而系统日志logging中的新行通常不会跟随类似的文本。
我认为改变syslog存储logging分隔符的能力是一个很有用的function,但是在logging本身内部的这种分隔符的任何出现都应该被转义,这样做是有用的。 在纯文本文件中添加这么多的结构必然是一个妥协。 如果你关心这个问题,也许你应该支持以一些定义好的二进制格式写日志文件(例如,sqlite在这里很有用)。
编辑:对RFC5424第6节更仔细的检查表明,系统日志消息可以有两种forms:
HEADER SP STRUCTURED-DATA
要么
HEADER SP STRUCTURED-DATA SP MSG
通过扩展ABNF规范,我们可以很容易地看到第一个表单以“ – ”或“]”结尾。 在最后一个char之前可能会有其他的“ – ”和“]”字符,所以不能用syslog消息结束符。
第二种forms的结局取决于味精如何结束。 MSG可以是UTF-8string(在RFC 3629中指定,不包含string终止),也可以是以任何值结尾的任意八位字节stream。 显然,没有为这个表单指定的终止符号。
但是事实上,不需要系统日志消息终结器,无论它是以何种forms存在,因为消息长度是由传输层带外传递的。 当UDP数据包由应用程序发送时,系统日志消息必须已经按照规范准备好并存储在一个缓冲区中。 这个缓冲区被应用程序传递给一个函数或者方法来发送它,并且传送的字节量也被传递。 例如,在C中我们有:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
在这个例子中, len是应该从缓冲区buf中取出并发送到远程主机的字节数。
同样,在系统日志服务器上调用另一个函数或方法,比如这个:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
此函数返回缓冲区buf中接收到的UDP有效负载的字节长度。 如果应用程序试图读取超过这个返回的长度,它将得到垃圾(或分段错误)。 为避免超出此限制,通常在siz = recvfrom(…)调用之后立即在位置buf [siz]处放置NULL值。 这样,任何稍后使用buf作为string的函数调用都将正常工作。 这个空终止只适用于string,当然,而不是八位字节stream。 正如我所说的,这个空值通常不是通过networking传输的,而只是由接收应用程序添加的。
在系统日志服务器作为接收应用程序的情况下,大多数系统日志服务器可能会添加这个空终止符来处理接收到的string(如果他们把它当作一个string),但是在任何情况下都是空值当string被追加到日志文件中时不会中断整个日志文件的文本处理。
在6.1节中,他们定义了一个消息长度。 我会想,当你得到完整的消息,你会有头和数据,它会加起来这个长度。
除此之外,我看不到有多个消息的设施。 所以我想每个消息都是一个事件。 没有任何types的多消息跟踪,没有对开始,中间和结束消息的指定编码。 系统日志跟踪logging的消息,它并没有一个更高级别的事件概念。