runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 9f3de2602cb2c249b30b14202537cd3e1e098c78
parent 51051b9f58b535018280870121539fe390dc7207
Author: Gerrit Pape <pape@smarden.org>
Date:   Mon, 12 Jan 2004 13:22:28 +0000

  * svlogd.c: support sending log entries to remote host through udp,
    configurable through u and U lines in log dir config file; minor.
  * man/svlogd.8: adapt.

Diffstat:
Mman/svlogd.8 | 31+++++++++++++++++++++++++++++++
Mpackage/CHANGES | 4++++
Msrc/svlogd.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
3 files changed, 127 insertions(+), 18 deletions(-)

diff --git a/man/svlogd.8 b/man/svlogd.8 @@ -198,6 +198,37 @@ to feed each recent log file through .I processor (see above) on log file rotation. By default log files are not processed. +.TP +.RI u a.b.c.d[:port] +tells +.B svlogd +to transmit the first +.I len +characters of selected log messages to the IP address +.IR a.b.c.d , +port number +.IR port . +If +.I port +isn't set, the default port for syslog is used (514). +.I len +can be set through the \-l option, see below. +If +.B 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. +.TP +.RI U a.b.c.d[:port] +is the same as the +.I u +line above, but the log messages are no longer written to the log directory, +but transmitted through udp only. +Error messages from +.B svlogd +concerning sending udp packages still go to the log directory. .P If a line starts with a .IR \- , diff --git a/package/CHANGES b/package/CHANGES @@ -1,5 +1,9 @@ +runit 0.13.0 * doc/runscripts.html: use html named entities (thx Taj Khattra); add more contributed run scripts (thx Thomas Schwinge). + * svlogd.c: support sending log entries to remote host through udp, + configurable through u and U lines in log dir config file; minor. + * man/svlogd.8: adapt. runit 0.12.1 Tue, 18 Nov 2003 15:42:44 +0000 diff --git a/src/svlogd.c b/src/svlogd.c @@ -1,5 +1,8 @@ #include <sys/types.h> #include <sys/stat.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> #include <time.h> #include <sys/time.h> #include <dirent.h> @@ -28,6 +31,7 @@ #include "direntry.h" #include "taia.h" #include "fmt.h" +#include "ndelay.h" #define USAGE " [-tv] [-r c] [-R abc] [-l n ] [-b n] dir ..." #define VERSION "$Id$" @@ -58,6 +62,7 @@ buffer data; char *line; char stamp[FMT_PTIME]; unsigned int exitasap =0; +int fdudp =-1; struct logdir { int fddir; @@ -74,6 +79,8 @@ struct logdir { int fdcur; int fdlock; unsigned int match; + struct sockaddr_in udpaddr; + unsigned int udponly; } *dir; unsigned int dirn =0; @@ -88,6 +95,7 @@ void warn(char *m0) { strerr_warn3(WARNING, m0, ": ", &strerr_sys); } void warn2(char *m0, char *m1) { strerr_warn5(WARNING, m0, ": ", m1, ": ", &strerr_sys); } +void warnx(char *m0, char *m1) { strerr_warn4(WARNING, m0, ": ", m1, 0); } void pause_nomem() { strerr_warn2(PAUSE, "out of memory.", 0); sleep(3); } void pause1(char *m0) { strerr_warn3(PAUSE, m0, ": ", &strerr_sys); sleep(3); } void pause2(char *m0, char *m1) { @@ -100,7 +108,7 @@ unsigned int processorstart(struct logdir *ld) { if (! ld->processor.len) return(0); if (ld->ppid) { - warn2("processor already running", ld->name); + warnx("processor already running", ld->name); return(0); } while ((pid =fork()) == -1) @@ -167,7 +175,7 @@ unsigned int processorstop(struct logdir *ld) { while (fchdir(ld->fddir) == -1) pause2("unable to change directory, want processor", ld->name); if (wait_exitcode(wstat) != 0) { - warn2("processor crashed, restart", ld->name); + warnx("processor crashed, restart", ld->name); ld->fnsave[26] ='t'; unlink(ld->fnsave); ld->fnsave[26] ='u'; @@ -282,6 +290,24 @@ void logdir_close(struct logdir *ld) { ld->fdlock =-1; } +/* taken from libdjbdns */ +unsigned int ip4_scan(const char *s,char ip[4]) +{ + unsigned int i; + unsigned int len; + unsigned long u; + + len = 0; + i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i; + return len; +} + unsigned int logdir_open(struct logdir *ld, const char *fn) { int i; @@ -310,6 +336,8 @@ unsigned int logdir_open(struct logdir *ld, const char *fn) { ld->nmax =10; ld->name =(char*)fn; ld->match =0; + ld->udpaddr.sin_port =0; + ld->udponly =0; while (! stralloc_copys(&ld->inst, "")) pause_nomem(); while (! stralloc_copys(&ld->processor, "")) pause_nomem(); @@ -317,8 +345,9 @@ unsigned int logdir_open(struct logdir *ld, const char *fn) { if ((i =openreadclose("config", &sa, 128)) == -1) warn2("unable to read config", ld->name); if (i != 0) { - int len; - + int len, c; + unsigned long port; + if (verbose) strerr_warn4(INFO, "read: ", ld->name, "/config", 0); for (i =0; i < sa.len -1; ++i) { if ((len =byte_chr(&sa.s[i], sa.len -i, '\n')) == 1) { @@ -350,6 +379,32 @@ unsigned int logdir_open(struct logdir *ld, const char *fn) { while (! stralloc_copys(&ld->processor, &sa.s[i +1])) pause_nomem(); while (! stralloc_0(&ld->processor)) pause_nomem(); break; + case 'U': + ld->udponly =1; + case 'u': + if (! (c =ip4_scan(sa.s +i +1, (char *)&ld->udpaddr.sin_addr))) { + warnx("unable to scan ip address", sa.s +i +1); + break; + } + if (sa.s[i +1 +c] == ':') { + scan_ulong(sa.s +i +c +2, &port); + if (port == 0) { + warnx("unable to scan port number", sa.s +i +c +2); + break; + } + } + else + port =514; + ld->udpaddr.sin_port =htons(port); + if (fdudp == -1) { + fdudp =socket(AF_INET, SOCK_DGRAM, 0); + if (fdudp) + if (ndelay_on(fdudp) == -1) { + close(fdudp); + fdudp =-1; + } + } + break; } i +=len; } @@ -440,20 +495,42 @@ unsigned int linestart(struct logdir *ld, char *s, int len) { } } if (ld->match == '-') return(0); - if (timestamp) { - buffer_puts(&ld->b, stamp); - if (timestamp != 3) ld->size +=26; - else ld->size +=20; + if (! ld->udponly) { + if (timestamp) { + buffer_puts(&ld->b, stamp); + if (timestamp != 3) ld->size +=26; + else ld->size +=20; + } + buffer_put(&ld->b, s, len); + ld->size +=len; + } + if (ld->udpaddr.sin_port != 0) { + if (fdudp == -1) { + buffer_puts(&ld->b, "warning: no udp socket available: "); + buffer_put(&ld->b, s, len); + buffer_putflush(&ld->b, "\n", 1); + } + else { + if (len >= linelen -1) { + s[linelen -4] =s[linelen -3] =s[linelen -2] ='.'; + len =linelen -1; + } + if (s[len -1] != '\n') s[len++] ='\n'; + if (sendto(fdudp, s, len, 0, (struct sockaddr *)&ld->udpaddr, + sizeof(ld->udpaddr)) != len) { + buffer_puts(&ld->b, "warning: failure sending through udp: "); + buffer_put(&ld->b, s, len); + buffer_putflush(&ld->b, "\n", 1); + } + } } - buffer_put(&ld->b, s, len); - ld->size +=len; return(1); } unsigned int lineadd(struct logdir *ld, char *s, int len) { - if (ld->match != '+') return(0); + if ((ld->match != '+') || ld->udponly) return(0); buffer_put(&ld->b, s, len); ld->size +=len; - if (ld->sizemax && (ld->size >= ld->sizemax)) rotate(ld); + /* if (ld->sizemax && (ld->size >= ld->sizemax)) rotate(ld); */ return(1); } unsigned int lineflush(struct logdir *ld, char *s, int len) { @@ -465,14 +542,11 @@ unsigned int lineflush(struct logdir *ld, char *s, int len) { linestart(ld, s, len); break; case '+': + ld->match =0; + if (ld->udponly) return(0); buffer_put(&ld->b, s, len); - ld->size +=len; - break; - } - if (ld->match == '+') { buffer_putflush(&ld->b, "\n", 1); - ld->size +=1; - ld->match =0; + ld->size +=len +1; if (ld->sizemax) if ((linelen > ld->sizemax) || (ld->size >= (ld->sizemax -linelen))) rotate(ld);