Logging

如何讓 svlogd 通過 UDP 發送日誌

  • April 7, 2017

我目前正在使用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的此問題的替代方案

引用自:https://serverfault.com/questions/752839