File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/libpanda.x/i/panda/log/log.h
Criterion Covered Total %
statement 5 9 55.5
branch 1 2 50.0
condition n/a
subroutine n/a
pod n/a
total 6 11 54.5


line stmt bran cond sub pod time code
1             #pragma once
2             #include "../pp.h"
3             #include "../string.h"
4             #include "../function.h"
5             #include
6             #include
7             #include
8             #include
9             #include
10             #include
11              
12             namespace panda { namespace log {
13             struct Module;
14             }}
15              
16             extern panda::log::Module panda_log_module;
17              
18             namespace panda { namespace log {
19              
20             #define PANDA_LOG_CODE_POINT panda::log::CodePoint{__FILE__, __LINE__, __func__}
21              
22             #define panda_should_log(...) PANDA_PP_VFUNC(PANDA_SHOULD_LOG, __VA_ARGS__)
23             #define PANDA_SHOULD_LOG1(lvl) PANDA_SHOULD_LOG2(lvl, panda_log_module)
24             #define PANDA_SHOULD_LOG2(lvl, mod) ((lvl) >= (mod).level())
25             #define panda_should_rlog(lvl) PANDA_SHOULD_LOG2(lvl, ::panda_log_module)
26              
27             #define panda_log(...) PANDA_LOG(__VA_ARGS__) // proxy to expand args
28             #define PANDA_LOG(lvl, ...) PANDA_PP_VFUNC(PANDA_LOG, PANDA_PP_VJOIN(lvl, __VA_ARGS__)) // separate first arg to detect empty args
29             #define PANDA_LOG1(lvl) PANDA_LOG2(lvl, default_message)
30             #define PANDA_LOG2(lvl, msg) PANDA_LOG3(lvl, panda_log_module, msg)
31             #define PANDA_LOG3(lvl, mod, msg) do { \
32             if (PANDA_SHOULD_LOG2(lvl, mod)) { \
33             std::ostream& log = panda::log::details::get_os(); \
34             panda::static_if::value>([&](auto) { \
35             (panda::log::details::LambdaStream&)log << msg; \
36             })(panda::log::details::Unique1{}); \
37             panda::static_if::value>([&](auto) { \
38             log << msg; \
39             })(panda::log::details::Unique2{}); \
40             panda::log::details::do_log(log, lvl, &(mod), PANDA_LOG_CODE_POINT); \
41             } \
42             } while (0)
43              
44             #define panda_log_verbose_debug(...) panda_log(panda::log::Level::VerboseDebug, __VA_ARGS__)
45             #define panda_log_debug(...) panda_log(panda::log::Level::Debug, __VA_ARGS__)
46             #define panda_log_info(...) panda_log(panda::log::Level::Info, __VA_ARGS__)
47             #define panda_log_notice(...) panda_log(panda::log::Level::Notice, __VA_ARGS__)
48             #define panda_log_warn(...) panda_log(panda::log::Level::Warning, __VA_ARGS__)
49             #define panda_log_warning(...) panda_log(panda::log::Level::Warning, __VA_ARGS__)
50             #define panda_log_error(...) panda_log(panda::log::Level::Error, __VA_ARGS__)
51             #define panda_log_critical(...) panda_log(panda::log::Level::Critical, __VA_ARGS__)
52             #define panda_log_alert(...) panda_log(panda::log::Level::Alert, __VA_ARGS__)
53             #define panda_log_emergency(...) panda_log(panda::log::Level::Emergency, __VA_ARGS__)
54              
55             #define panda_rlog(level, msg) panda_log(level, ::panda_log_module, msg)
56             #define panda_rlog_verbose_debug(msg) panda_rlog(panda::log::Level::VerboseDebug, msg)
57             #define panda_rlog_debug(msg) panda_rlog(panda::log::Level::Debug, msg)
58             #define panda_rlog_info(msg) panda_rlog(panda::log::Level::Info, msg)
59             #define panda_rlog_notice(msg) panda_rlog(panda::log::Level::Notice, msg)
60             #define panda_rlog_warn(msg) panda_rlog(panda::log::Level::Warning, msg)
61             #define panda_rlog_warning(msg) panda_rlog(panda::log::Level::Warning, msg)
62             #define panda_rlog_error(msg) panda_rlog(panda::log::Level::Error, msg)
63             #define panda_rlog_critical(msg) panda_rlog(panda::log::Level::Critical, msg)
64             #define panda_rlog_alert(msg) panda_rlog(panda::log::Level::Alert, msg)
65             #define panda_rlog_emergency(msg) panda_rlog(panda::log::Level::Emergency, msg)
66              
67             #define panda_log_ctor(...) PANDA_PP_VFUNC(PANDA_LOG_CTOR, __VA_ARGS__)
68             #define panda_log_dtor(...) PANDA_PP_VFUNC(PANDA_LOG_DTOR, __VA_ARGS__)
69             #define PANDA_LOG_CTOR0() PANDA_LOG_CTOR1(panda_log_module)
70             #define PANDA_LOG_CTOR1(mod) PANDA_LOG3(panda::log::Level::VerboseDebug, mod, __func__ << " [ctor]")
71             #define PANDA_LOG_DTOR0() PANDA_LOG_DTOR1(panda_log_module)
72             #define PANDA_LOG_DTOR1(mod) PANDA_LOG3(panda::log::Level::VerboseDebug, mod, __func__ << " [dtor]")
73             #define panda_rlog_ctor() panda_log_ctor(::panda_log_module)
74             #define panda_rlog_dtor() panda_log_dtor(::panda_log_module)
75              
76             #define panda_debug_v(var) panda_log_debug(#var << " = " << (var))
77              
78             #define PANDA_ASSERT(var, msg) if(!(auto assert_value = var)) { panda_log_emergency("assert failed: " << #var << " is " << assert_value << msg) }
79              
80             extern string_view default_message;
81              
82             enum class Level {
83             VerboseDebug = 0,
84             Debug,
85             Info,
86             Notice,
87             Warning,
88             Error,
89             Critical,
90             Alert,
91             Emergency
92             };
93              
94             struct CodePoint {
95             string_view file;
96             uint32_t line;
97             string_view func;
98             };
99              
100             struct Module;
101              
102             struct Info {
103             Info () : level(), module(), line() {}
104             Info (Level level, const Module* module, const string_view& file, uint32_t line, const string_view& func, const string_view& program_name)
105             : level(level), module(module), file(file), line(line), func(func), program_name{program_name} {}
106              
107             Level level;
108             const Module* module;
109             string_view file;
110             uint32_t line;
111             string_view func;
112             timespec time;
113             string_view program_name;
114             };
115              
116 68           struct IFormatter : AtomicRefcnt {
117             virtual string format (std::string&, const Info&) const = 0;
118 8 50         virtual ~IFormatter () {}
119             };
120             using IFormatterSP = iptr;
121              
122 82           struct ILogger : AtomicRefcnt {
123             virtual void log_format (std::string&, const Info&, const IFormatter&);
124             virtual void log (const string&, const Info&);
125             virtual ~ILogger () = 0;
126             };
127             using ILoggerSP = iptr;
128              
129             using format_fn = function;
130             using logger_format_fn = function;
131             using logger_fn = function;
132              
133 0           inline ILoggerSP make_logger (std::nullptr_t) { return {}; }
134             inline ILoggerSP make_logger (ILoggerSP l) { return l; }
135             ILoggerSP make_logger (const logger_fn& f);
136             ILoggerSP make_logger (const logger_format_fn& f);
137              
138 0           inline IFormatterSP make_formatter (std::nullptr_t) { return {}; }
139             inline IFormatterSP make_formatter (const IFormatterSP& f) { return f; }
140             IFormatterSP make_formatter (const format_fn& f);
141             IFormatterSP make_formatter (string_view pattern);
142              
143 130           struct ILoggerFromAny {
144             ILoggerSP value;
145             ILoggerFromAny () {}
146 0           template ILoggerFromAny (T&& l) : value(make_logger(std::forward(l))) {}
147             };
148              
149 120           struct IFormatterFromAny {
150             IFormatterSP value;
151             IFormatterFromAny () {}
152 0           template IFormatterFromAny (T&& f) : value(make_formatter(std::forward(f))) {}
153             };
154             struct Module {
155             using Modules = std::vector;
156              
157             Module (const string& name, Level level = Level::Warning); // module with root parent
158             Module (const string& name, Module& parent, Level level = Level::Warning); // module with parent
159             Module (const string& name, Module* parent, Level level = Level::Warning);
160             Module (const string& name, std::nullptr_t, Level level = Level::Warning); // root module
161              
162             Module (const Module&) = delete;
163             Module (Module&&) = delete;
164              
165             Module& operator= (const Module&) = delete;
166              
167             const string& name () const;
168             const Module* parent () const;
169             Level level () const;
170             const Modules& children () const;
171             bool passthrough () const;
172              
173             void set_level (Level);
174             void set_logger (ILoggerFromAny, bool passthrough = false);
175             void set_formatter (IFormatterFromAny);
176              
177             ILoggerSP get_logger ();
178             IFormatterSP get_formatter ();
179              
180             virtual ~Module ();
181             void init();
182              
183             private:
184             Module* _parent;
185             Level _level;
186             Modules _children;
187             string _name;
188             bool _passthrough = false;
189              
190             void _set_effective_logger (const ILoggerSP&);
191             void _set_effective_formatter (const IFormatterSP&);
192             };
193              
194             void set_level (Level, string_view module = "");
195             void set_logger (ILoggerFromAny l);
196             void set_formatter (IFormatterFromAny f);
197             void set_program_name(const string& value) noexcept;
198              
199             ILoggerSP get_logger ();
200             IFormatterSP get_formatter ();
201              
202             Module* get_module (string_view);
203             std::vector get_modules ();
204              
205             namespace details {
206             std::ostream& get_os ();
207             bool do_log (std::ostream&, Level, const Module*, const CodePoint&);
208              
209             template struct IsEval : std::false_type {};
210             template <> struct IsEval<'['> : std::true_type {};
211              
212             static constexpr inline char getf (const char* s) { return *s; }
213              
214             struct LambdaStream : std::ostream {};
215             struct Unique1 {};
216             struct Unique2 {};
217              
218             template
219             std::enable_if_t::value, LambdaStream&> operator<< (LambdaStream& os, T&& f) {
220             f();
221             return os;
222             }
223             }
224              
225             struct escaped { string_view src; };
226              
227             std::ostream& operator<< (std::ostream&, const escaped&);
228              
229             }}
230              
231             extern panda::log::Module panda_log_module;
232