Github   Telegram
Loading...
Searching...
No Matches
log.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <chrono>
7
13
14USERVER_NAMESPACE_BEGIN
15
16namespace logging {
17
18namespace impl {
19
22LoggerRef DefaultLoggerRef() noexcept;
23
24void SetDefaultLoggerRef(LoggerRef new_logger) noexcept;
25
26} // namespace impl
27
31class DefaultLoggerGuard final {
32 public:
38 explicit DefaultLoggerGuard(LoggerPtr new_default_logger) noexcept;
39
41 DefaultLoggerGuard& operator=(DefaultLoggerGuard&&) = delete;
42
44
45 private:
46 LoggerRef logger_prev_;
47 const Level level_prev_;
48 LoggerPtr logger_new_;
49};
50
53
54void SetLoggerLevel(LoggerRef, Level);
55
58
59bool LoggerShouldLog(LoggerCRef logger, Level level) noexcept;
60
61bool LoggerShouldLog(const LoggerPtr& logger, Level level) noexcept;
62
63Level GetLoggerLevel(LoggerCRef logger) noexcept;
64
66void LogFlush();
67
69void LogFlush(LoggerCRef logger);
70
71namespace impl {
72
73// Not thread-safe, static lifetime data
74class RateLimitData {
75 public:
76 uint64_t count_since_reset = 0;
77 uint64_t dropped_count = 0;
78 std::chrono::steady_clock::time_point last_reset_time{};
79};
80
81// Represents a single rate limit usage
82class RateLimiter {
83 public:
84 RateLimiter(LoggerCRef logger, RateLimitData& data, Level level) noexcept;
85 bool ShouldLog() const { return should_log_; }
86 void SetShouldNotLog() { should_log_ = false; }
87 Level GetLevel() const { return level_; }
88 friend LogHelper& operator<<(LogHelper& lh, const RateLimiter& rl) noexcept;
89
90 private:
91 const Level level_;
92 bool should_log_{false};
93 uint64_t dropped_count_{0};
94};
95
96// Register location during static initialization for dynamic debug logs.
97class StaticLogEntry final {
98 public:
99 StaticLogEntry(const char* path, int line) noexcept;
100
101 StaticLogEntry(StaticLogEntry&&) = delete;
102 StaticLogEntry& operator=(StaticLogEntry&&) = delete;
103
104 bool ShouldLog() const noexcept;
105 bool ShouldNotLog(Level level) const noexcept;
106
107 private:
108 static constexpr std::size_t kContentSize =
109 compiler::SelectSize().For64Bit(40).For32Bit(24);
110 alignas(void*) std::byte content[kContentSize];
111};
112
113template <class NameHolder, int Line>
114struct EntryStorage final {
115 static inline StaticLogEntry entry{NameHolder::Get(), Line};
116};
117
118} // namespace impl
119
120} // namespace logging
121
124// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
125#define DO_LOG_TO(logger, lvl) \
126 USERVER_NAMESPACE::logging::LogHelper(logger, lvl, USERVER_FILEPATH, \
127 __LINE__, __func__) \
128 .AsLvalue()
129
130// static_cast<int> below are workarounds for clangs -Wtautological-compare
131
135// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
136#define LOG(lvl) \
137 __builtin_expect( \
138 [](USERVER_NAMESPACE::logging::Level level) -> bool { \
139 struct NameHolder { \
140 static constexpr const char* Get() noexcept { \
141 return USERVER_FILEPATH; \
142 } \
143 }; \
144 const auto& entry = \
145 USERVER_NAMESPACE::logging::impl::EntryStorage<NameHolder, \
146 __LINE__>::entry; \
147 return (!USERVER_NAMESPACE::logging::ShouldLog(level) || \
148 entry.ShouldNotLog(level)) && \
149 !entry.ShouldLog(); \
150 }(lvl), \
151 static_cast<int>(lvl) < \
152 static_cast<int>(USERVER_NAMESPACE::logging::Level::kInfo)) \
153 ? USERVER_NAMESPACE::logging::impl::Noop{} \
154 : DO_LOG_TO(USERVER_NAMESPACE::logging::impl::DefaultLoggerRef(), (lvl))
155
159// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
160#define LOG_TO(logger, lvl) \
161 !USERVER_NAMESPACE::logging::LoggerShouldLog((logger), (lvl)) \
162 ? USERVER_NAMESPACE::logging::impl::Noop{} \
163 : DO_LOG_TO((logger), (lvl))
164
167// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
168#define LOG_TRACE() LOG(USERVER_NAMESPACE::logging::Level::kTrace)
169
172// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
173#define LOG_DEBUG() LOG(USERVER_NAMESPACE::logging::Level::kDebug)
174
177// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
178#define LOG_INFO() LOG(USERVER_NAMESPACE::logging::Level::kInfo)
179
182// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
183#define LOG_WARNING() LOG(USERVER_NAMESPACE::logging::Level::kWarning)
184
187// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
188#define LOG_ERROR() LOG(USERVER_NAMESPACE::logging::Level::kError)
189
192// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
193#define LOG_CRITICAL() LOG(USERVER_NAMESPACE::logging::Level::kCritical)
194
196
199// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
200#define LOG_TRACE_TO(logger) \
201 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kTrace)
202
205// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
206#define LOG_DEBUG_TO(logger) \
207 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kDebug)
208
211// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
212#define LOG_INFO_TO(logger) \
213 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kInfo)
214
217// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
218#define LOG_WARNING_TO(logger) \
219 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kWarning)
220
223// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
224#define LOG_ERROR_TO(logger) \
225 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kError)
226
229// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
230#define LOG_CRITICAL_TO(logger) \
231 LOG_TO(logger, USERVER_NAMESPACE::logging::Level::kCritical)
232
234
238// Note: we have to jump through the hoops to keep lazy evaluation of the logged
239// data AND log the dropped logs count from the correct LogHelper in the face of
240// multithreading and coroutines.
241// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
242#define LOG_LIMITED_TO(logger, lvl) \
243 for (USERVER_NAMESPACE::logging::impl::RateLimiter log_limited_to_rl{ \
244 logger, \
245 []() -> USERVER_NAMESPACE::logging::impl::RateLimitData& { \
246 thread_local USERVER_NAMESPACE::logging::impl::RateLimitData \
247 rl_data; \
248 return rl_data; \
249 }(), \
250 (lvl)}; \
251 log_limited_to_rl.ShouldLog(); log_limited_to_rl.SetShouldNotLog()) \
252 LOG_TO((logger), log_limited_to_rl.GetLevel()) << log_limited_to_rl
253
256// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
257#define LOG_LIMITED(lvl) \
258 LOG_LIMITED_TO(USERVER_NAMESPACE::logging::impl::DefaultLoggerRef(), lvl)
259
263// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
264#define LOG_LIMITED_TRACE() \
265 LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kTrace)
266
270// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
271#define LOG_LIMITED_DEBUG() \
272 LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kDebug)
273
277// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
278#define LOG_LIMITED_INFO() LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kInfo)
279
283// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
284#define LOG_LIMITED_WARNING() \
285 LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kWarning)
286
290// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
291#define LOG_LIMITED_ERROR() \
292 LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kError)
293
297// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
298#define LOG_LIMITED_CRITICAL() \
299 LOG_LIMITED(USERVER_NAMESPACE::logging::Level::kCritical)
300
302
306// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
307#define LOG_LIMITED_TRACE_TO(logger) \
308 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kTrace)
309
313// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
314#define LOG_LIMITED_DEBUG_TO(logger) \
315 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kDebug)
316
320// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
321#define LOG_LIMITED_INFO_TO(logger) \
322 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kInfo)
323
327// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
328#define LOG_LIMITED_WARNING_TO(logger) \
329 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kWarning)
330
334// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
335#define LOG_LIMITED_ERROR_TO(logger) \
336 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kError)
337
341// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
342#define LOG_LIMITED_CRITICAL_TO(logger) \
343 LOG_LIMITED_TO(logger, USERVER_NAMESPACE::logging::Level::kCritical)
344
345USERVER_NAMESPACE_END