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