Set main log format earlier.
[oweals/dinit.git] / src / includes / dinit-log.h
1 #ifndef DINIT_LOG_H
2 #define DINIT_LOG_H
3
4 // Logging for Dinit.
5 //
6 // The main log function is the variadic template 'log' function:
7 //
8 //     void log(loglevel_t, ...)
9 //
10 // It takes a list of items comprising a single log message, including strings (C/C++ style), and integers.
11 // The loglevel argument determines if the message will actually be logged (according to the configured log
12 // level of the log mechanisms).
13
14 #include <string>
15 #include <cstdio>
16 #include <climits>
17
18 class service_set;
19
20 enum class loglevel_t {
21     DEBUG,
22     INFO,
23     WARN,
24     ERROR,
25     ZERO    // log absolutely nothing
26 };
27
28 // These are defined in dinit-log.cc:
29 extern loglevel_t log_level[2];
30 void enable_console_log(bool do_enable) noexcept;
31 void init_log(service_set *sset, bool syslog_format);
32 void setup_main_log(int fd);
33 bool is_log_flushed() noexcept;
34 void discard_console_log_buffer() noexcept;
35
36 // Log a simple string:
37 void log(loglevel_t lvl, const char *msg) noexcept;
38 // Log a simple string, optionally without logging to console:
39 void log(loglevel_t lvl, bool to_cons, const char *msg) noexcept;
40
41 // Log a message in parts; a beginnning, various middle parts, and an end part. Calls to these functions
42 // must not be interleaved with calls to other logging functions.
43 void log_msg_begin(loglevel_t lvl, const char *msg) noexcept;
44 void log_msg_part(const char *msg) noexcept;
45 void log_msg_end(const char *msg) noexcept;
46
47 // Defined below:
48 void log_service_started(const char *service_name) noexcept;
49 void log_service_failed(const char *service_name) noexcept;
50 void log_service_stopped(const char *service_name) noexcept;
51
52 // Convenience methods which perform type conversion of the argument.
53 // There is some duplication here that could possibly be avoided, but
54 // it doesn't seem like a big deal.
55 static inline void log(loglevel_t lvl, const std::string &str) noexcept
56 {
57     log(lvl, str.c_str());
58 }
59
60 static inline void log_msg_begin(loglevel_t lvl, const std::string &str) noexcept
61 {
62     log_msg_begin(lvl, str.c_str());
63 }
64
65 static inline void log_msg_begin(loglevel_t lvl, int a) noexcept
66 {
67     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
68     char nbuf[bufsz];
69     snprintf(nbuf, bufsz, "%d", a);
70     log_msg_begin(lvl, nbuf);
71 }
72
73 static inline void log_msg_part(const std::string &str) noexcept
74 {
75     log_msg_part(str.c_str());
76 }
77
78 static inline void log_msg_part(int a) noexcept
79 {
80     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
81     char nbuf[bufsz];
82     snprintf(nbuf, bufsz, "%d", a);
83     log_msg_part(nbuf);
84 }
85
86 static inline void log_msg_end(const std::string &str) noexcept
87 {
88     log_msg_end(str.c_str());
89 }
90
91 static inline void log_msg_end(int a) noexcept
92 {
93     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
94     char nbuf[bufsz];
95     snprintf(nbuf, bufsz, "%d", a);
96     log_msg_end(nbuf);
97 }
98
99 static inline void log_service_started(const std::string &str) noexcept
100 {
101     log_service_started(str.c_str());
102 }
103
104 static inline void log_service_failed(const std::string &str) noexcept
105 {
106     log_service_failed(str.c_str());
107 }
108
109 static inline void log_service_stopped(const std::string &str) noexcept
110 {
111     log_service_stopped(str.c_str());
112 }
113
114 // It's not intended that methods in this namespace be called directly:
115 namespace dinit_log {
116     template <typename A> static inline void log_parts(A a) noexcept
117     {
118         log_msg_end(a);
119     }
120
121     template <typename A, typename ...B> static inline void log_parts(A a, B... b) noexcept
122     {
123         log_msg_part(a);
124         log_parts(b...);
125     }
126 }
127
128 // Variadic 'log' method.
129 template <typename A, typename ...B> static inline void log(loglevel_t lvl, bool log_cons, A a, B ...b) noexcept
130 {
131     log_msg_begin(lvl, a);
132     dinit_log::log_parts(b...);
133 }
134
135 template <typename A, typename ...B> static inline void log(loglevel_t lvl, A a, B ...b) noexcept
136 {
137     log_msg_begin(lvl, a);
138     dinit_log::log_parts(b...);
139 }
140
141 #endif