如何讓 svlogd 通過 UDP 發送日誌
我目前正在使用runit + svlogd來監督一些應用程序,但是當部署到多台機器時,我需要將日誌集中/統一在一個地方以簡化事情,否則登錄到每台機器會使事情變得非常複雜。
而不是通過 syslog 發送所有主機日誌,例如:
*.* remote.log.host
我只想發送與應用程序相關的日誌,理論上 svlogd 能夠做到這一點,來自文件:
ua.b.c.d[:port] tells svlogd to transmit the first len characters of selected log messages to the IP address a.b.c.d, port number port. If port isn’t set, the default port for syslog is used (514). len can be set through the -l option, see below. If svlogd has trouble sending udp packets, it writes error messages to the log directory. Attention: logging through udp is unreliable, and should be used in private networks only. Ua.b.c.d[:port] is the same as the u line above, but the log messages are no longer written to the log directory, but transmitted through udp only. Error messages from svlogd concerning sending udp packages still go to the log directory.
我的配置文件的內容
/service/my-service/log/main/config
:u127.0.0.1:5514
或者
U127.0.0.1:5514
為了測試,我創建了一個非常基本的UDP 伺服器/客戶端,但由於未知原因
svlogd
沒有發送日誌,我也嘗試netcat
使用它:nc -ul 5514
我為此使用的日誌執行腳本
/service/my-service/log/run
:#!/bin/sh exec svlogd -tt ./main
我得到的唯一錯誤消息是:
warning: failure sending through udp:
我一直在使用的解決方法是
logger
在日誌執行腳本中呼叫,例如:#!/bin/sh exec chpst -u nobody logger -i -h remote.host.tld -P 42060 -t my-app
但是通過這種方法,我失去了 svlogd 的所有優勢,除了
sv status .
總是開/關(1,0),因為記錄器不像守護程序那樣執行。最後,我想繼續獲得來自 svlogd 的日誌,但可以讓工作成為
ua.b.c.d[:port]
選項。更新:做一個 ktrace 這就是我得到的:
4909 svlogd CALL socket(PF_INET,SOCK_DGRAM,IPPROTO_IP) 4909 svlogd RET socket 7 4909 svlogd CALL fcntl(0x7,F_GETFL,0) 4909 svlogd RET fcntl 2 4909 svlogd CALL fcntl(0x7,F_SETFL,0x6<O_RDWR|O_NONBLOCK>) 4909 svlogd RET fcntl 0 4909 svlogd CALL sendto(0x7,0x609580,0x3c,0,0x609c3c,0x10) 4909 svlogd STRU struct sockaddr { AF_UNSPEC, unknown address family } 4909 svlogd RET sendto -1 errno 47 Address family not supported by protocol family 4909 svlogd CALL write(0x6,0x609760,0x62) 4909 svlogd GIO fd 6 wrote 98 bytes "warning: failure sending through udp:
STRU struct sockaddr { AF_UNSPEC, unknown address family }
有任何想法嗎 ?
添加
ld->udpaddr.sin_family =AF_INET;
到svlogd.c
http://skarnet.org/cgi-bin/archive.cgi?2:mss:1163:201602:gpiglpbjdemlioaeabbn
FreeBSD 更新檔: https ://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207747
修補:
--- src/svlogd.c.orig 2016-03-06 13:48:35 UTC +++ src/svlogd.c @@ -430,6 +430,7 @@ unsigned int logdir_open(struct logdir * ld->name =(char*)fn; ld->ppid =0; ld->match ='+'; + ld->udpaddr.sin_family =AF_INET; ld->udpaddr.sin_port =0; ld->udponly =0; while (! stralloc_copys(&ld->prefix, "")) pause_nomem();
更新:作為目前使用https://immortal.run的此問題的替代方案