Make all log messages go via the log buffer.
authorDavin McCall <davmac@davmac.org>
Sun, 5 Jun 2016 20:05:40 +0000 (21:05 +0100)
committerDavin McCall <davmac@davmac.org>
Sun, 5 Jun 2016 20:05:40 +0000 (21:05 +0100)
Flush the log buffer before exit.

src/cpbuffer.h
src/dinit-log.cc
src/dinit-log.h
src/dinit.cc

index 978720430b47a0b51d8a8e11eb75b35c139fba04..1c05174a6ea8db0f1be1519a0a14cb8702fe9a40 100644 (file)
@@ -66,6 +66,12 @@ template <int SIZE> class CPBuffer
         return 1;
     }
     
+    // Trim the buffer to the specified length (must be less than current length)
+    void trim_to(int new_length)
+    {
+        length = new_length;
+    }
+    
     char operator[](int idx) noexcept
     {
         int dest_idx = cur_idx + idx;
index 8dd08c64f225b7427cbf973fa9c5ee759ffac4e1..5d79971a940afd3f402b78c0d9f6c0231ec21d36 100644 (file)
@@ -17,6 +17,7 @@ extern EventLoop_t eventLoop;
 
 LogLevel log_level = LogLevel::WARN;
 LogLevel cons_log_level = LogLevel::WARN;
+
 static bool log_to_console = false;   // whether we should output log messages to
                                      // console immediately
 static bool log_current_line;  // Whether the current line is being logged
@@ -179,6 +180,11 @@ void init_log(ServiceSet *sset) noexcept
     enable_console_log(true);
 }
 
+bool is_log_flushed() noexcept
+{
+    return log_stream[DLOG_CONS].current_index > 0;
+}
+
 // Enable or disable console logging. If disabled, console logging will be disabled on the
 // completion of output of the current message (if any), at which point the first service record
 // queued in the service set will acquire the console.
@@ -236,7 +242,6 @@ template <typename ... T> static void do_log(T ... args) noexcept
         bool was_first = (log_stream[DLOG_CONS].current_index == 0);
         log_stream[DLOG_CONS].current_index += amount;
         if (was_first && log_to_console) {
-            //ev_io_start(ev_default_loop(EVFLAG_AUTO), & log_stream[DLOG_CONS].eviocb);
             log_stream[DLOG_CONS].registerWith(&eventLoop, log_stream[DLOG_CONS].fd, out_events);
         }
     }
@@ -253,13 +258,39 @@ template <typename ... T> static void do_log(LogLevel lvl, T ... args) noexcept
     }
 }
 
-
 // Log a message. A newline will be appended.
 void log(LogLevel lvl, const char *msg) noexcept
 {
     do_log(lvl, "dinit: ", msg, "\n");
 }
 
+// Log part of a message. A series of calls to do_log_part must be followed by a call to do_log_commit.
+template <typename T> static void do_log_part(T arg) noexcept
+{
+    int amount = sum_length(arg);
+    if (log_stream[DLOG_CONS].log_buffer.get_free() >= amount) {
+        append(log_stream[DLOG_CONS].log_buffer, arg);
+    }
+    else {
+        // reset
+        log_stream[DLOG_CONS].log_buffer.trim_to(log_stream[DLOG_CONS].current_index);
+        log_current_line = false;
+        // TODO mark discarded message
+    }
+}
+
+// Commit a message that was issued as a series of parts (via do_log_part).
+static void do_log_commit() noexcept
+{
+    if (log_current_line) {
+        bool was_first = log_stream[DLOG_CONS].current_index == 0;
+        log_stream[DLOG_CONS].current_index = log_stream[DLOG_CONS].log_buffer.get_length();
+        if (was_first && log_to_console) {
+            log_stream[DLOG_CONS].registerWith(&eventLoop, log_stream[DLOG_CONS].fd, out_events);
+        }
+    }
+}
+
 // Log a multi-part message beginning
 void logMsgBegin(LogLevel lvl, const char *msg) noexcept
 {
@@ -267,7 +298,8 @@ void logMsgBegin(LogLevel lvl, const char *msg) noexcept
     log_current_line = lvl >= log_level;
     if (log_current_line) {
         if (log_to_console) {
-            std::cout << "dinit: " << msg;
+            do_log_part("dinit: ");
+            do_log_part(msg);
         }
     }
 }
@@ -278,7 +310,7 @@ void logMsgPart(const char *msg) noexcept
     // TODO use buffer
     if (log_current_line) {
         if (log_to_console) {
-            std::cout << msg;
+            do_log_part(msg);
         }
     }
 }
@@ -289,7 +321,9 @@ void logMsgEnd(const char *msg) noexcept
     // TODO use buffer
     if (log_current_line) {
         if (log_to_console) {
-            std::cout << msg << std::endl;
+            do_log_part(msg);
+            do_log_part("\n");
+            do_log_commit();
         }
     }
 }
index d51bf08709ddd1ddbf25a5e0b7ffbd310c7b87d7..2ba474ffb8bcd3b7bf8d4272af9af7b3f7921562 100644 (file)
@@ -20,6 +20,7 @@ enum class LogLevel {
 extern LogLevel log_level;
 void enable_console_log(bool do_enable) noexcept;
 void init_log(ServiceSet *sset) noexcept;
+bool is_log_flushed() noexcept;
 
 void log(LogLevel lvl, const char *msg) noexcept;
 void logMsgBegin(LogLevel lvl, const char *msg) noexcept;
index a0e7a5f7f45aadd974422ffc62801872d51b6c15..8315af1a8e9c13bdf4db97752687b545159c2fb3 100644 (file)
@@ -303,36 +303,24 @@ int main(int argc, char **argv)
     //ev_signal sigint_ev_signal;
     CallbackSignalHandler sigint_watcher;
     if (am_system_init) {
-      //ev_signal_init(&sigint_ev_signal, sigint_reboot_cb, SIGINT);
       sigint_watcher.setCbFunc(sigint_reboot_cb);
     }
     else {
-      //ev_signal_init(&sigint_ev_signal, sigterm_cb, SIGINT);
       sigint_watcher.setCbFunc(sigterm_cb);
     }
     
-    //ev_signal sigquit_ev_signal;
     CallbackSignalHandler sigquit_watcher;
     if (am_system_init) {
         // PID 1: SIGQUIT exec's shutdown
-        //ev_signal_init(&sigquit_ev_signal, sigquit_cb, SIGQUIT);
         sigquit_watcher.setCbFunc(sigquit_cb);
     }
     else {
         // Otherwise: SIGQUIT terminates dinit
-        //ev_signal_init(&sigquit_ev_signal, sigterm_cb, SIGQUIT);
         sigquit_watcher.setCbFunc(sigterm_cb);
     }
     
-    //ev_signal sigterm_ev_signal;
-    //ev_signal_init(&sigterm_ev_signal, sigterm_cb, SIGTERM);
     auto sigterm_watcher = CallbackSignalHandler(sigterm_cb);
     
-    /* Set up libev */
-    //struct ev_loop *loop = ev_default_loop(EVFLAG_AUTO /* | EVFLAG_SIGNALFD */);
-    //ev_signal_start(loop, &sigint_ev_signal);
-    //ev_signal_start(loop, &sigquit_ev_signal);
-    //ev_signal_start(loop, &sigterm_ev_signal);
     sigint_watcher.registerWatch(&eventLoop, SIGINT);
     sigquit_watcher.registerWatch(&eventLoop, SIGQUIT);
     sigterm_watcher.registerWatch(&eventLoop, SIGTERM);
@@ -375,7 +363,6 @@ int main(int argc, char **argv)
     
     // Process events until all services have terminated.
     while (service_set->count_active_services() != 0) {
-        // ev_loop(loop, EVLOOP_ONESHOT);
         eventLoop.run();
     }
 
@@ -398,6 +385,10 @@ int main(int argc, char **argv)
         }
     }
     
+    while (! is_log_flushed()) {
+        eventLoop.run();
+    }
+    
     close_control_socket(&eventLoop);
     
     if (am_system_init) {