Logging: support for supressing output to console per message.
authorDavin McCall <davmac@davmac.org>
Tue, 27 Feb 2018 17:27:39 +0000 (17:27 +0000)
committerDavin McCall <davmac@davmac.org>
Tue, 27 Feb 2018 17:51:00 +0000 (17:51 +0000)
src/dinit-log.cc
src/includes/dinit-log.h

index 76044b9c6104014b3a9717113c259451e9f4fce9..8465520a01182bf77cd0f0bda3c3a2cc0976ab88 100644 (file)
@@ -69,7 +69,6 @@ class buffered_log_stream : public eventloop_t::fd_watcher_impl<buffered_log_str
 
     // Check whether the console can be released.
     void flush_for_release();
-    void release_console();
     bool is_release_set() { return release; }
     
     // Commit a log message
@@ -109,6 +108,9 @@ class buffered_log_stream : public eventloop_t::fd_watcher_impl<buffered_log_str
     {
         discarded = true;
     }
+
+    private:
+    void release_console();
 };
 }
 
@@ -276,10 +278,9 @@ void enable_console_log(bool enable) noexcept
 {
     bool log_to_console = ! log_stream[DLOG_CONS].is_release_set();
     if (enable && ! log_to_console) {
-        // Console is fd 1 - stdout
         // Set non-blocking IO:
-        int flags = fcntl(1, F_GETFL, 0);
-        fcntl(1, F_SETFL, flags | O_NONBLOCK);
+        int flags = fcntl(STDOUT_FILENO, F_GETFL, 0);
+        fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
         // Activate watcher:
         log_stream[DLOG_CONS].init(STDOUT_FILENO);
         log_stream[DLOG_CONS].set_enabled(event_loop, true);
@@ -349,10 +350,10 @@ template <typename ... T> static void push_to_log(int idx, T ... args) noexcept
 }
 
 // Variadic method to potentially log a sequence of strings as a single message with the given log level:
-template <typename ... T> static void do_log(loglevel_t lvl, T ... args) noexcept
+template <typename ... T> static void do_log(loglevel_t lvl, bool to_cons, T ... args) noexcept
 {
-    log_current_line[DLOG_CONS] = lvl >= log_level[DLOG_CONS];
-    log_current_line[DLOG_MAIN] = lvl >= log_level[DLOG_MAIN];
+    log_current_line[DLOG_CONS] = (lvl >= log_level[DLOG_CONS]) && to_cons;
+    log_current_line[DLOG_MAIN] = (lvl >= log_level[DLOG_MAIN]);
     push_to_log(DLOG_CONS, args...);
     
     if (log_current_line[DLOG_MAIN]) {
@@ -385,7 +386,12 @@ template <typename ... T> static void do_log_main(T ... args) noexcept
 // Log a message. A newline will be appended.
 void log(loglevel_t lvl, const char *msg) noexcept
 {
-    do_log(lvl, "dinit: ", msg, "\n");
+    do_log(lvl, true, "dinit: ", msg, "\n");
+}
+
+void log(loglevel_t lvl, bool to_cons, const char *msg) noexcept
+{
+    do_log(lvl, to_cons, "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.
@@ -418,6 +424,7 @@ void log_msg_begin(loglevel_t lvl, const char *msg) noexcept
     log_current_line[DLOG_CONS] = lvl >= log_level[DLOG_CONS];
     log_current_line[DLOG_MAIN] = lvl >= log_level[DLOG_MAIN];
 
+    // Prepend the syslog priority level string ("<N>") for the main log:
     if (log_current_line[DLOG_MAIN]) {
         char svcbuf[10];
         snprintf(svcbuf, 10, "<%d>", LOG_DAEMON | log_level_to_syslog_level(lvl));
index b94a658be8c898c369224982d675c32e7891dcc7..7a0c26fde11f5a8f7f06b1717c9ee338dd847196 100644 (file)
@@ -1,7 +1,15 @@
 #ifndef DINIT_LOG_H
 #define DINIT_LOG_H
 
-// Logging for Dinit
+// Logging for Dinit.
+//
+// The main log function is the variadic template 'log' function:
+//
+//     void log(loglevel_t, ...)
+//
+// It takes a list of items comprising a single log message, including strings (C/C++ style), and integers.
+// The loglevel argument determines if the message will actually be logged (according to the configured log
+// level of the log mechanisms).
 
 #include <string>
 #include <cstdio>
@@ -17,6 +25,7 @@ enum class loglevel_t {
     ZERO    // log absolutely nothing
 };
 
+// These are defined in dinit-log.cc:
 extern loglevel_t log_level[2];
 void enable_console_log(bool do_enable) noexcept;
 void init_log(service_set *sset);
@@ -24,10 +33,18 @@ void setup_main_log(int fd);
 bool is_log_flushed() noexcept;
 void discard_console_log_buffer() noexcept;
 
+// Log a simple string:
 void log(loglevel_t lvl, const char *msg) noexcept;
+// Log a simple string, optionally without logging to console:
+void log(loglevel_t lvl, bool to_cons, const char *msg) noexcept;
+
+// Log a message in parts; a beginnning, various middle parts, and an end part. Calls to these functions
+// must not be interleaved with calls to other logging functions.
 void log_msg_begin(loglevel_t lvl, const char *msg) noexcept;
 void log_msg_part(const char *msg) noexcept;
 void log_msg_end(const char *msg) noexcept;
+
+// Defined below:
 void log_service_started(const char *service_name) noexcept;
 void log_service_failed(const char *service_name) noexcept;
 void log_service_stopped(const char *service_name) noexcept;
@@ -109,6 +126,12 @@ namespace dinit_log {
 }
 
 // Variadic 'log' method.
+template <typename A, typename ...B> static inline void log(loglevel_t lvl, bool log_cons, A a, B ...b) noexcept
+{
+    log_msg_begin(lvl, a);
+    dinit_log::log_parts(b...);
+}
+
 template <typename A, typename ...B> static inline void log(loglevel_t lvl, A a, B ...b) noexcept
 {
     log_msg_begin(lvl, a);