Install: allow specifying sbin and man directories.
[oweals/dinit.git] / src / dinit-log.h
1 #ifndef DINIT_LOG_H
2 #define DINIT_LOG_H
3
4 // Logging for Dinit
5
6 #include <string>
7 #include <cstdio>
8 #include <climits>
9
10 class service_set;
11
12 enum class loglevel_t {
13     DEBUG,
14     INFO,
15     WARN,
16     ERROR,
17     ZERO    // log absolutely nothing
18 };
19
20 extern loglevel_t log_level[2];
21 void enable_console_log(bool do_enable) noexcept;
22 void init_log(service_set *sset);
23 void setup_main_log(int fd);
24 bool is_log_flushed() noexcept;
25 void discard_console_log_buffer() noexcept;
26
27 void log(loglevel_t lvl, const char *msg) noexcept;
28 void log_msg_begin(loglevel_t lvl, const char *msg) noexcept;
29 void log_msg_part(const char *msg) noexcept;
30 void log_msg_end(const char *msg) noexcept;
31 void log_service_started(const char *service_name) noexcept;
32 void log_service_failed(const char *service_name) noexcept;
33 void log_service_stopped(const char *service_name) noexcept;
34
35 // Convenience methods which perform type conversion of the argument.
36 // There is some duplication here that could possibly be avoided, but
37 // it doesn't seem like a big deal.
38 static inline void log(loglevel_t lvl, const std::string &str) noexcept
39 {
40     log(lvl, str.c_str());
41 }
42
43 static inline void log_msg_begin(loglevel_t lvl, const std::string &str) noexcept
44 {
45     log_msg_begin(lvl, str.c_str());
46 }
47
48 static inline void log_msg_begin(loglevel_t lvl, int a) noexcept
49 {
50     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
51     char nbuf[bufsz];
52     snprintf(nbuf, bufsz, "%d", a);
53     log_msg_begin(lvl, nbuf);
54 }
55
56 static inline void log_msg_part(const std::string &str) noexcept
57 {
58     log_msg_part(str.c_str());
59 }
60
61 static inline void log_msg_part(int a) noexcept
62 {
63     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
64     char nbuf[bufsz];
65     snprintf(nbuf, bufsz, "%d", a);
66     log_msg_part(nbuf);
67 }
68
69 static inline void log_msg_end(const std::string &str) noexcept
70 {
71     log_msg_end(str.c_str());
72 }
73
74 static inline void log_msg_end(int a) noexcept
75 {
76     constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2;
77     char nbuf[bufsz];
78     snprintf(nbuf, bufsz, "%d", a);
79     log_msg_end(nbuf);
80 }
81
82 static inline void log_service_started(const std::string &str) noexcept
83 {
84     log_service_started(str.c_str());
85 }
86
87 static inline void log_service_failed(const std::string &str) noexcept
88 {
89     log_service_failed(str.c_str());
90 }
91
92 static inline void log_service_stopped(const std::string &str) noexcept
93 {
94     log_service_stopped(str.c_str());
95 }
96
97 // It's not intended that methods in this namespace be called directly:
98 namespace dinit_log {
99     template <typename A> static inline void log_parts(A a) noexcept
100     {
101         log_msg_end(a);
102     }
103
104     template <typename A, typename ...B> static inline void log_parts(A a, B... b) noexcept
105     {
106         log_msg_part(a);
107         log_parts(b...);
108     }
109 }
110
111 // Variadic 'log' method.
112 template <typename A, typename ...B> static inline void log(loglevel_t lvl, A a, B ...b) noexcept
113 {
114     log_msg_begin(lvl, a);
115     dinit_log::log_parts(b...);
116 }
117
118 #endif