Как заставить svlogd отправлять логи через UDP

В настоящее время я использую runit + svlogd для наблюдения за некоторыми приложениями, но при развертывании на нескольких машинах мне нужно централизовать / унифицировать журналы в одном месте, чтобы упростить вещи, в противном случае вход на каждую машину усложняет задачу.

Вместо отправки всех журналов хоста через системный журнал что-то вроде:

*.* 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 }

Есть идеи?

1 ответ

Решение

Добавление 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

Patch:

--- 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/

Другие вопросы по тегам