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