summary refs log tree commit diff
diff options
context:
space:
mode:
authorGerrit Pape <pape@smarden.org>2004-01-12 13:22:28 +0000
committerGerrit Pape <pape@smarden.org>2004-01-12 13:22:28 +0000
commite4851e06f03fdc028d3c6dba13ae27df7cfa6a4a (patch)
tree936711f36cd208712c485445ef2b8eb41da4d192
parent23d1b9a9879d57c9434efa87233ddb0b0e37dbdf (diff)
downloadrunit-e4851e06f03fdc028d3c6dba13ae27df7cfa6a4a.tar.gz
runit-e4851e06f03fdc028d3c6dba13ae27df7cfa6a4a.tar.xz
runit-e4851e06f03fdc028d3c6dba13ae27df7cfa6a4a.zip
* 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.
-rw-r--r--man/svlogd.831
-rw-r--r--package/CHANGES4
-rw-r--r--src/svlogd.c110
3 files changed, 127 insertions, 18 deletions
diff --git a/man/svlogd.8 b/man/svlogd.8
index 7448c00..b170fe5 100644
--- 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
index a6dcb35..c0ee395 100644
--- 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
index 1e9498f..6ebbe9f 100644
--- 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);