chiark / gitweb /
journald: log when we fail to forward messages to syslog
[elogind.git] / src / journal / journald-syslog.c
index 9db9198..d3e0f6f 100644 (file)
 #include <stddef.h>
 #include <sys/epoll.h>
 
+#include "systemd/sd-messages.h"
 #include "socket-util.h"
 #include "journald.h"
 #include "journald-syslog.h"
 #include "journald-kmsg.h"
 #include "journald-console.h"
 
+/* Warn once every 30s if we missed syslog message */
+#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
+
 static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
         struct msghdr msghdr;
         struct cmsghdr *cmsg;
@@ -74,8 +78,10 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
 
         /* The socket is full? I guess the syslog implementation is
          * too slow, and we shouldn't wait for that... */
-        if (errno == EAGAIN)
+        if (errno == EAGAIN) {
+                s->n_forward_syslog_missed++;
                 return;
+        }
 
         if (ucred && errno == ESRCH) {
                 struct ucred u;
@@ -91,8 +97,10 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
                 if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
                         return;
 
-                if (errno == EAGAIN)
+                if (errno == EAGAIN) {
+                        s->n_forward_syslog_missed++;
                         return;
+                }
         }
 
         if (errno != ENOENT)
@@ -464,3 +472,20 @@ int server_open_syslog_socket(Server *s) {
 
         return 0;
 }
+
+void server_maybe_warn_forward_syslog_missed(Server *s) {
+        usec_t n;
+        assert(s);
+
+        if (s->n_forward_syslog_missed <= 0)
+                return;
+
+        n = now(CLOCK_MONOTONIC);
+        if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
+                return;
+
+        server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, "Forwarding to syslog missed %u messages.", s->n_forward_syslog_missed);
+
+        s->n_forward_syslog_missed = 0;
+        s->last_warn_forward_syslog_missed = n;
+}