bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-inetutils] patch circular log feature for syslogd


From: Daniel Lehne
Subject: [bug-inetutils] patch circular log feature for syslogd
Date: Wed, 21 Nov 2012 14:29:53 +0200
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20121026 Thunderbird/16.0.2

Hello,

in relation to [Re: [bug-inetutils] [SCM] GNU Inetutils  branch, master,
updated. inetutils-1_9_1-204-g3299ba8] her the post of the feature
circular log for syslogd.

Syntax in syslog.conf for a circular log:
<facility>.<priority/level>{SPACES}%<file>{SPACE}<maximum
size>{SPACE}<offset>
<>  must replaced by the user for his needs, all fields must filled
{} essential syntax characters must used by the user

 >Since I suspect that this is a non-trivial change, we would need an
 >copyright assignment from you (and employeer?).  Would you like to
 >sign such an agreement?
The copyright is GPL according the head of the file syslogd.c and no
additional rights are claimed on my (our) side. In detail:
/*
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
   Inc.

   This file is part of GNU Inetutils.

   GNU Inetutils is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or (at
   your option) any later version.

   GNU Inetutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see `http://www.gnu.org/licenses/'. */

/*
  * Copyright (c) 1983, 1988, 1993, 1994
  *      The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */

I want to mention, that the base idea was by Jeff Weelhouse with his clog
program for BSD syslog [http://software.wwwi.com/syslogd/].
I've hardly changed the concept and implementation, mainly the defines could be 
the same.
You could check it, if this should be a problem for you.


0001-added-circular-log-feature.patch:
-----------------------------------------------------------------
From 894e9a448eceae3bf68aa3e71b2e032b5994eb11 Mon Sep 17 00:00:00 2001
From: Daniel Lehne <address@hidden>
Date: Wed, 21 Nov 2012 14:59:41 +0200
Subject: added circular log feature

---
 src/syslogd.c |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/src/syslogd.c b/src/syslogd.c
index 4fa459a..1ad2cf5 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -67,6 +67,7 @@
  * Author: Eric Allman
  * extensive changes by Ralph Campbell
  * more extensive changes by Eric Allman (again)
+ * added circular log by Daniel Lehne
  */
#include <config.h>
@@ -133,6 +134,7 @@
  * not logged to a file.
  */
 int facilities_seen;
+const char clog_wrap[] = "\n\n";        /* empty line, indicates wrap of 
ringbuffer */
const char *ConfFile = PATH_LOGCONF; /* Default Configuration file. */
 const char *PidFile = PATH_LOGPID;     /* Default path to tuck pid.  */
@@ -182,6 +184,12 @@ struct filed
       struct sockaddr_storage f_addr;
       socklen_t f_addrlen;
     } f_forw;                  /* Forwarding address.  */
+    struct {
+      char *f_fname;
+      long int  cf_offset;
+      long int  cf_next;
+      long int  cf_max;
+    } f_clog;                   /* circular log file */
     char *f_fname;             /* Name use for Files|Pipes|TTYs.  */
   } f_un;
   char f_prevline[MAXSVLINE];  /* Last message logged.  */
@@ -208,6 +216,7 @@ struct filed consfile;              /* Console `file'.  */
 #define F_FORW_SUSP    7       /* Suspended host forwarding.  */
 #define F_FORW_UNKN    8       /* Unknown host forwarding.  */
 #define F_PIPE         9       /* Named pipe.  */
+#define F_CLOG          10      /* Circular log) */
const char *TypeNames[] = {
   "UNUSED",
@@ -219,7 +228,8 @@ const char *TypeNames[] = {
   "WALL",
   "FORW(SUSPENDED)",
   "FORW(UNKNOWN)",
-  "PIPE"
+  "PIPE",
+  "CLOG"
 };
/* Flags in filed.f_flags. */
@@ -244,6 +254,10 @@ int repeatinterval[] = { 30, 60 }; /* Number of seconds 
before flush.  */
 /* Delimiter in arguments to command line options `-s' and `-l'.  */
 #define LIST_DELIMITER ':'
+/* Constants for the F_CLOG footer and wrap */
+#define WRAP_CHARS_SIZE sizeof(clog_wrap) /* size of space print on wraping 
the log */
+#define IOV_OFFSET      2                 /* ignore n first elements of iov - 
DATE, SPACE */
+
 extern int waitdaemon (int nochdir, int noclose, int maxwait);
void cfline (const char *, struct filed *);
@@ -269,6 +283,7 @@ void trigger_restart (int);
 static void add_funix (const char *path);
 static int create_unix_socket (const char *path);
 static void create_inet_socket (int af, int fd46[2]);
+ssize_t clogwritev (struct filed *, struct iovec *, int);
char *LocalHostName; /* Our hostname. */
 char *LocalDomain;             /* Our local domain name.  */
@@ -573,7 +588,8 @@ main (int argc, char *argv[])
   /* Initialize kernel logging and add to the list.  */
   if (!NoKLog)
     {
-      fklog = open (PATH_KLOG, O_RDONLY, 0);
+      /* klog could block system startup, so O_NONBLOCK */
+      fklog = open (PATH_KLOG, O_RDONLY | O_NONBLOCK, 0);
       if (fklog >= 0)
        {
          fdarray[nfds].fd = fklog;
@@ -679,6 +695,7 @@ main (int argc, char *argv[])
       /*dbg_printf ("got a message (%d)\n", nready); */
for (i = 0; i < nfds; i++)
+      {
        if (fdarray[i].revents & (POLLIN | POLLPRI))
          {
            int result;
@@ -694,10 +711,18 @@ main (int argc, char *argv[])
                  {
                    kline_len += result;
                  }
-               else if (result < 0 && errno != EINTR)
+                  else
                  {
-                   logerror ("klog");
-                   fdarray[i].fd = fklog = -1;
+                    /* catch and tollerate */
+                    if (errno == EAGAIN){
+                      logerror ("klog EAGAIN");
+                    } else if (errno == EINTR){
+                      logerror ("klog EINTR");
+                    } else {
+                     /* stop klog */
+                     logerror ("klog");
+                     fdarray[i].fd = fklog = -1;
+                    }
                  }
while (1)
@@ -805,6 +830,7 @@ main (int argc, char *argv[])
          logerror ("poll err\n");
        else if (fdarray[i].revents & POLLHUP)
          logerror ("poll hup\n");
+      }                         /* for (nfds) */
     }                          /* for (;;) */
 }                              /* main */
@@ -1497,6 +1523,23 @@ fprintlog (struct filed *f, const char *from, int flags, const char *msg)
        fsync (f->f_file);
       break;
+ case F_CLOG:
+      f->f_time = now;
+      dbg_printf(" %s\n", f->f_un.f_fname);
+      v->iov_base = "\n";
+      v->iov_len = 1;
+      if (clogwritev(f, iov, IOVCNT) < 0) {
+        /* failure, disable clog */
+        int e = errno;
+        close(f->f_file);
+        f->f_type = F_UNUSED;
+        errno = e;
+        logerror(f->f_un.f_fname);
+        free(f->f_un.f_fname);
+        f->f_un.f_fname = NULL;
+      }
+      break;
+
     case F_USERS:
     case F_WALL:
       f->f_time = now;
@@ -1771,6 +1814,7 @@ init (int signo _GL_UNUSED_PARAMETER)
        case F_TTY:
        case F_CONSOLE:
        case F_PIPE:
+        case F_CLOG:
          free (f->f_un.f_fname);
          close (f->f_file);
          break;
@@ -1924,6 +1968,7 @@ init (int signo _GL_UNUSED_PARAMETER)
            case F_TTY:
            case F_CONSOLE:
            case F_PIPE:
+            case F_CLOG:
              dbg_printf ("%s", f->f_un.f_fname);
              break;
@@ -2185,6 +2230,45 @@ cfline (const char *line, struct filed *f)
        f->f_type = F_FILE;
       break;
+ /* circular log file */
+    case '%':
+      f->f_type = F_UNUSED;
+      memset(&f->f_un.f_clog, 0, sizeof(f->f_un.f_clog));
+      f->f_un.f_clog.f_fname = strdup(p+1);
+      errno = 0;
+      q = strtok(f->f_un.f_clog.f_fname, " ");
+      if ((errno) || ((f->f_file = open(q, O_WRONLY | O_TRUNC | O_CREAT, 0644)) 
< 0))
+      {
+        free(f->f_un.f_fname);
+        logerror(p);
+        break;
+      }
+      /* parse size */
+      errno = 0;
+      q = strtok(NULL, " ");
+      f->f_un.f_clog.cf_max = strtol(q, NULL ,10);
+      if(errno) {
+        close(f->f_file);
+        free(f->f_un.f_fname);
+        logerror(p);
+        break;
+      }
+      /* parse offset */
+      q = strtok(NULL, " ");
+      errno = 0;
+      f->f_un.f_clog.cf_offset = strtol(q, NULL ,10);
+      if(errno) {
+        close(f->f_file);
+        free(f->f_un.f_fname);
+        logerror(p);
+        break;
+      }
+      /* prohibit invalid offsets */
+      if (f->f_un.f_clog.cf_offset > (f->f_un.f_clog.cf_max - WRAP_CHARS_SIZE) 
)
+        f->f_un.f_clog.cf_offset = 0;
+      f->f_type = F_CLOG;
+      break;
+
     case '*':
       f->f_type = F_WALL;
       break;
@@ -2215,6 +2299,40 @@ cfline (const char *line, struct filed *f)
     }
 }
+/* The following function handles the circular log file access */
+ssize_t clogwritev(struct filed *f, struct iovec *iov, int iovcnt) {
+  int i;
+  ssize_t  out = 0;
+  ssize_t  err = 0;
+  long int diff = 0;
+
+  /* wrap file when data not fit maximum size */
+  for(i=IOV_OFFSET; i<iovcnt; i++)
+    out += iov[i].iov_len;
+  diff = (f->f_un.f_clog.cf_max - f->f_un.f_clog.cf_next);
+  if((diff < 0) || (out >= diff))
+  {
+     /* hard wrap to offset and set mark */
+     f->f_un.f_clog.cf_next = f->f_un.f_clog.cf_offset;
+     err = pwrite(f->f_file, clog_wrap, strlen(clog_wrap), 
f->f_un.f_clog.cf_next);
+     if (err == -1)
+       return -1;
+     fsync(f->f_file);
+     f->f_un.f_clog.cf_next += err;
+  }
+  out = 0;
+
+  /* write out to circular log file */
+  err = pwritev(f->f_file,&iov[IOV_OFFSET],iovcnt - 
IOV_OFFSET,f->f_un.f_clog.cf_next);
+  if (err==-1)
+    return -1;
+  fsync(f->f_file);
+  f->f_un.f_clog.cf_next += err;
+  out += err;
+
+  return out;
+}
+
 /* Decode a symbolic name to a numeric value.  */
 int
 decode (const char *name, CODE * codetab)
--
1.7.2.5


----------------------------------------------------------------------------------


Best regards!

--
Daniel Lehne,
Dep. Development

AMK Drives and Controls Ltd.
Bulgaria / Gabrovo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]