// Check whether the console can be released.
void flush_for_release();
- void release_console();
bool is_release_set() { return release; }
// Commit a log message
{
discarded = true;
}
+
+ private:
+ void release_console();
};
}
{
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);
}
// 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]) {
// 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.
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));
#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>
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);
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;
}
// 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);