Fix mistakes in cptest asserts
[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 constexpr static int DLOG_MAIN = 0; // main log facility
29 constexpr static int DLOG_CONS = 1; // console
30
31 // These are defined in dinit-log.cc:
32 extern loglevel_t log_level[2];
33 extern bool console_service_status;  // show service status messages to console?
34
35 void enable_console_log(bool do_enable) noexcept;
36 void init_log(service_set *sset, bool syslog_format);
37 void close_log();
38 void setup_main_log(int fd);
39 bool is_log_flushed() noexcept;
40 void discard_console_log_buffer() noexcept;
41
42 // Log a simple string:
43 void log(loglevel_t lvl, const char *msg) noexcept;
44 // Log a simple string, optionally without logging to console:
45 void log(loglevel_t lvl, bool to_cons, const char *msg) noexcept;
46
47 // Log a message in parts; a beginnning, various middle parts, and an end part. Calls to these functions
48 // must not be interleaved with calls to other logging functions.
49 void log_msg_begin(loglevel_t lvl, const char *msg) noexcept;
50 void log_msg_part(const char *msg) noexcept;
51 void log_msg_end(const char *msg) noexcept;
52
53 // Defined below:
54 void log_service_started(const char *service_name) noexcept;
55 void log_service_failed(const char *service_name) noexcept;
56 void log_service_stopped(const char *service_name) noexcept;
57
58 // Convenience methods which perform type conversion of the argument.
59 // There is some duplication here that could possibly be avoided, but
60 // it doesn't seem like a big deal.
61 static inline void log(loglevel_t lvl, const std::string &str) noexcept
62 {
63     log(lvl, str.c_str());
64 }
65
66 static inline void log_msg_begin(loglevel_t lvl, const std::string &str) noexcept
67 {
68     log_msg_begin(lvl, str.c_str());
69 }
70
71 static inline void log_msg_begin(loglevel_t lvl, int a) noexcept
72 {
73     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
74     char nbuf[bufsz];
75     snprintf(nbuf, bufsz, "%d", a);
76     log_msg_begin(lvl, nbuf);
77 }
78
79 static inline void log_msg_part(const std::string &str) noexcept
80 {
81     log_msg_part(str.c_str());
82 }
83
84 static inline void log_msg_part(int a) noexcept
85 {
86     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
87     char nbuf[bufsz];
88     snprintf(nbuf, bufsz, "%d", a);
89     log_msg_part(nbuf);
90 }
91
92 static inline void log_msg_end(const std::string &str) noexcept
93 {
94     log_msg_end(str.c_str());
95 }
96
97 static inline void log_msg_end(int a) noexcept
98 {
99     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
100     char nbuf[bufsz];
101     snprintf(nbuf, bufsz, "%d", a);
102     log_msg_end(nbuf);
103 }
104
105 static inline void log_service_started(const std::string &str) noexcept
106 {
107     log_service_started(str.c_str());
108 }
109
110 static inline void log_service_failed(const std::string &str) noexcept
111 {
112     log_service_failed(str.c_str());
113 }
114
115 static inline void log_service_stopped(const std::string &str) noexcept
116 {
117     log_service_stopped(str.c_str());
118 }
119
120 // It's not intended that methods in this namespace be called directly:
121 namespace dinit_log {
122     template <typename A> static inline void log_parts(const A &a) noexcept
123     {
124         log_msg_end(a);
125     }
126
127     template <typename A, typename ...B> static inline void log_parts(const A &a, const B & ...b) noexcept
128     {
129         log_msg_part(a);
130         log_parts(b...);
131     }
132 }
133
134 // Variadic 'log' method.
135 template <typename A, typename ...B> static inline void log(loglevel_t lvl, const A &a, const B & ...b) noexcept
136 {
137     log_msg_begin(lvl, a);
138     dinit_log::log_parts(b...);
139 }
140
141 #endif