chiark / gitweb /
build-sys: store journald code in a noinst library
[elogind.git] / src / journal / journald-syslog.c
index daed095c291a4394c7eb25079ddae76c139ad5b8..afddca3630097162bc7c6677efaa3b309f1d263b 100644 (file)
 ***/
 
 #include <unistd.h>
+#include <stddef.h>
 #include <sys/epoll.h>
 
+#include "systemd/sd-messages.h"
 #include "socket-util.h"
-#include "journald.h"
+#include "journald-server.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;
@@ -73,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;
@@ -90,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)
@@ -176,7 +185,7 @@ int syslog_fixup_facility(int priority) {
         return priority;
 }
 
-void syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
+size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
         const char *p;
         char *t;
         size_t l, e;
@@ -192,7 +201,7 @@ void syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
 
         if (l <= 0 ||
             p[l-1] != ':')
-                return;
+                return 0;
 
         e = l;
         l--;
@@ -222,8 +231,9 @@ void syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
         if (t)
                 *identifier = t;
 
+        e += strspn(p + e, WHITESPACE);
         *buf = p + e;
-        *buf += strspn(*buf, WHITESPACE);
+        return e;
 }
 
 void syslog_parse_priority(char **p, int *priority) {
@@ -463,3 +473,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;
+}