Any ok?  I would like to work on the next step.

On Tue, Feb 03, 2015 at 01:59:39AM +0100, Alexander Bluhm wrote:
> To get reliable TCP and TLS logging, I want to report when messages
> get lost.  If the log server refuses to receive messages and the
> buffer gets full, count the dropped messages.  Log the counter when
> the server accepts messages again.  If there are messages in the
> buffer when a signal is received, count and log them.
> 
> Index: usr.sbin/syslogd/syslogd.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
> retrieving revision 1.147
> diff -u -p -r1.147 syslogd.c
> --- usr.sbin/syslogd/syslogd.c        2 Feb 2015 17:27:43 -0000       1.147
> +++ usr.sbin/syslogd/syslogd.c        3 Feb 2015 00:56:18 -0000
> @@ -145,6 +145,7 @@ struct filed {
>                       struct tls              *f_ctx;
>                       char                    *f_host;
>                       int                      f_reconnectwait;
> +                     int                      f_dropped;
>               } f_forw;               /* forwarding address */
>               char    f_fname[PATH_MAX];
>               struct {
> @@ -221,6 +222,7 @@ char      *path_ctlsock = NULL;   /* Path to co
>  struct       tls_config *tlsconfig;
>  const char *CAfile = "/etc/ssl/cert.pem"; /* file containing CA certificates 
> */
>  int  NoVerify = 0;           /* do not verify TLS server x509 certificate */
> +int  tcpbuf_dropped = 0;     /* count messages dropped from TCP or TLS */
>  
>  #define CTL_READING_CMD              1
>  #define CTL_WRITING_REPLY    2
> @@ -284,6 +286,7 @@ void       tcp_writecb(struct bufferevent *, 
>  void  tcp_errorcb(struct bufferevent *, short, void *);
>  void  tcp_connectcb(int, short, void *);
>  struct tls *tls_socket(struct filed *);
> +int   tcpbuf_countmsg(struct bufferevent *bufev);
>  void  die_signalcb(int, short, void *);
>  void  mark_timercb(int, short, void *);
>  void  init_signalcb(int, short, void *);
> @@ -775,12 +778,22 @@ void
>  tcp_writecb(struct bufferevent *bufev, void *arg)
>  {
>       struct filed    *f = arg;
> +     char             ebuf[256];
>  
>       /*
>        * Successful write, connection to server is good, reset wait time.
>        */
>       dprintf("loghost \"%s\" successful write\n", f->f_un.f_forw.f_loghost);
>       f->f_un.f_forw.f_reconnectwait = 0;
> +
> +     if (f->f_un.f_forw.f_dropped > 0 &&
> +         EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) < MAX_TCPBUF) {
> +             snprintf(ebuf, sizeof(ebuf),
> +                 "syslogd: dropped %d messages to loghost \"%s\"",
> +                 f->f_un.f_forw.f_dropped, f->f_un.f_forw.f_loghost);
> +             f->f_un.f_forw.f_dropped = 0;
> +             logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
> +     }
>  }
>  
>  void
> @@ -904,6 +917,21 @@ tls_socket(struct filed *f)
>       return (ctx);
>  }
>  
> +int
> +tcpbuf_countmsg(struct bufferevent *bufev)
> +{
> +     char    *p, *buf, *end;
> +     int      i = 0;
> +
> +     buf = EVBUFFER_DATA(bufev->output);
> +     end = buf + EVBUFFER_LENGTH(bufev->output);
> +     for (p = buf; p < end; p++) {
> +             if (*p == '\n')
> +                     i++;
> +     }
> +     return (i);
> +}
> +
>  void
>  usage(void)
>  {
> @@ -1211,10 +1239,13 @@ fprintlog(struct filed *f, int flags, ch
>  
>       case F_FORWTCP:
>       case F_FORWTLS:
> -             dprintf(" %s\n", f->f_un.f_forw.f_loghost);
> +             dprintf(" %s", f->f_un.f_forw.f_loghost);
>               if (EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) >=
> -                 MAX_TCPBUF)
> -                     break;  /* XXX log error message */
> +                 MAX_TCPBUF) {
> +                     dprintf(" (dropped)\n");
> +                     f->f_un.f_forw.f_dropped++;
> +                     break;
> +             }
>               /*
>                * RFC 6587  3.4.2.  Non-Transparent-Framing
>                * Use \n to split messages for now.
> @@ -1225,9 +1256,13 @@ fprintlog(struct filed *f, int flags, ch
>                   IncludeHostname ? LocalHostName : "",
>                   IncludeHostname ? " " : "",
>                   (char *)iov[4].iov_base);
> -             if (l < 0)
> -                     break;  /* XXX log error message */
> +             if (l < 0) {
> +                     dprintf(" (dropped)\n");
> +                     f->f_un.f_forw.f_dropped++;
> +                     break;
> +             }
>               bufferevent_enable(f->f_un.f_forw.f_bufev, EV_WRITE);
> +             dprintf("\n");
>               break;
>  
>       case F_CONSOLE:
> @@ -1414,11 +1449,21 @@ mark_timercb(int unused, short event, vo
>  void
>  init_signalcb(int signum, short event, void *arg)
>  {
> +     char     ebuf[256];
> +
>       init();
>  
>       logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart",
>           LocalHostName, ADDDATE);
>       dprintf("syslogd: restarted\n");
> +
> +     if (tcpbuf_dropped > 0) {
> +             snprintf(ebuf, sizeof(ebuf),
> +                 "syslogd: dropped %d messages to remote loghost",
> +                 tcpbuf_dropped);
> +             tcpbuf_dropped = 0;
> +             logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
> +     }
>  }
>  
>  /*
> @@ -1454,8 +1499,22 @@ die(int signo)
>               /* flush any pending output */
>               if (f->f_prevcount)
>                       fprintlog(f, 0, (char *)NULL);
> +             if (f->f_type == F_FORWTLS || f->f_type == F_FORWTCP) {
> +                     tcpbuf_dropped += f->f_un.f_forw.f_dropped +
> +                         tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
> +                     f->f_un.f_forw.f_dropped = 0;
> +             }
>       }
>       Initialized = was_initialized;
> +
> +     if (tcpbuf_dropped > 0) {
> +             snprintf(ebuf, sizeof(ebuf),
> +                 "syslogd: dropped %d messages to remote loghost",
> +                 tcpbuf_dropped);
> +             tcpbuf_dropped = 0;
> +             logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
> +     }
> +
>       if (signo) {
>               dprintf("syslogd: exiting on signal %d\n", signo);
>               (void)snprintf(ebuf, sizeof(ebuf), "exiting on signal %d",
> @@ -1508,7 +1567,8 @@ init(void)
>                       free(f->f_un.f_forw.f_host);
>                       /* FALLTHROUGH */
>               case F_FORWTCP:
> -                     /* XXX Save messages in output buffer for reconnect. */
> +                     tcpbuf_dropped += f->f_un.f_forw.f_dropped +
> +                          tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
>                       bufferevent_free(f->f_un.f_forw.f_bufev);
>                       /* FALLTHROUGH */
>               case F_FILE:

Reply via email to