diff options
Diffstat (limited to 'src/common/logging/backend.cpp')
| -rw-r--r-- | src/common/logging/backend.cpp | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index a5e031189..4462ff3fb 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -39,10 +39,10 @@ public: | |||
| 39 | Impl(Impl const&) = delete; | 39 | Impl(Impl const&) = delete; |
| 40 | const Impl& operator=(Impl const&) = delete; | 40 | const Impl& operator=(Impl const&) = delete; |
| 41 | 41 | ||
| 42 | void PushEntry(Entry e) { | 42 | void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, |
| 43 | std::lock_guard<std::mutex> lock(message_mutex); | 43 | const char* function, std::string message) { |
| 44 | message_queue.Push(std::move(e)); | 44 | message_queue.Push( |
| 45 | message_cv.notify_one(); | 45 | CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void AddBackend(std::unique_ptr<Backend> backend) { | 48 | void AddBackend(std::unique_ptr<Backend> backend) { |
| @@ -86,15 +86,13 @@ private: | |||
| 86 | } | 86 | } |
| 87 | }; | 87 | }; |
| 88 | while (true) { | 88 | while (true) { |
| 89 | { | 89 | entry = message_queue.PopWait(); |
| 90 | std::unique_lock<std::mutex> lock(message_mutex); | 90 | if (entry.final_entry) { |
| 91 | message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); }); | ||
| 92 | } | ||
| 93 | if (!running) { | ||
| 94 | break; | 91 | break; |
| 95 | } | 92 | } |
| 96 | write_logs(entry); | 93 | write_logs(entry); |
| 97 | } | 94 | } |
| 95 | |||
| 98 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case | 96 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case |
| 99 | // where a system is repeatedly spamming logs even on close. | 97 | // where a system is repeatedly spamming logs even on close. |
| 100 | const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; | 98 | const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; |
| @@ -106,18 +104,36 @@ private: | |||
| 106 | } | 104 | } |
| 107 | 105 | ||
| 108 | ~Impl() { | 106 | ~Impl() { |
| 109 | running = false; | 107 | Entry entry; |
| 110 | message_cv.notify_one(); | 108 | entry.final_entry = true; |
| 109 | message_queue.Push(entry); | ||
| 111 | backend_thread.join(); | 110 | backend_thread.join(); |
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | std::atomic_bool running{true}; | 113 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, |
| 115 | std::mutex message_mutex, writing_mutex; | 114 | const char* function, std::string message) const { |
| 116 | std::condition_variable message_cv; | 115 | using std::chrono::duration_cast; |
| 116 | using std::chrono::steady_clock; | ||
| 117 | |||
| 118 | Entry entry; | ||
| 119 | entry.timestamp = | ||
| 120 | duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 121 | entry.log_class = log_class; | ||
| 122 | entry.log_level = log_level; | ||
| 123 | entry.filename = Common::TrimSourcePath(filename); | ||
| 124 | entry.line_num = line_nr; | ||
| 125 | entry.function = function; | ||
| 126 | entry.message = std::move(message); | ||
| 127 | |||
| 128 | return entry; | ||
| 129 | } | ||
| 130 | |||
| 131 | std::mutex writing_mutex; | ||
| 117 | std::thread backend_thread; | 132 | std::thread backend_thread; |
| 118 | std::vector<std::unique_ptr<Backend>> backends; | 133 | std::vector<std::unique_ptr<Backend>> backends; |
| 119 | Common::MPSCQueue<Log::Entry> message_queue; | 134 | Common::MPSCQueue<Log::Entry> message_queue; |
| 120 | Filter filter; | 135 | Filter filter; |
| 136 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; | ||
| 121 | }; | 137 | }; |
| 122 | 138 | ||
| 123 | void ConsoleBackend::Write(const Entry& entry) { | 139 | void ConsoleBackend::Write(const Entry& entry) { |
| @@ -276,25 +292,6 @@ const char* GetLevelName(Level log_level) { | |||
| 276 | #undef LVL | 292 | #undef LVL |
| 277 | } | 293 | } |
| 278 | 294 | ||
| 279 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 280 | const char* function, std::string message) { | ||
| 281 | using std::chrono::duration_cast; | ||
| 282 | using std::chrono::steady_clock; | ||
| 283 | |||
| 284 | static steady_clock::time_point time_origin = steady_clock::now(); | ||
| 285 | |||
| 286 | Entry entry; | ||
| 287 | entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 288 | entry.log_class = log_class; | ||
| 289 | entry.log_level = log_level; | ||
| 290 | entry.filename = Common::TrimSourcePath(filename); | ||
| 291 | entry.line_num = line_nr; | ||
| 292 | entry.function = function; | ||
| 293 | entry.message = std::move(message); | ||
| 294 | |||
| 295 | return entry; | ||
| 296 | } | ||
| 297 | |||
| 298 | void SetGlobalFilter(const Filter& filter) { | 295 | void SetGlobalFilter(const Filter& filter) { |
| 299 | Impl::Instance().SetGlobalFilter(filter); | 296 | Impl::Instance().SetGlobalFilter(filter); |
| 300 | } | 297 | } |
| @@ -319,9 +316,7 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | |||
| 319 | if (!filter.CheckMessage(log_class, log_level)) | 316 | if (!filter.CheckMessage(log_class, log_level)) |
| 320 | return; | 317 | return; |
| 321 | 318 | ||
| 322 | Entry entry = | 319 | instance.PushEntry(log_class, log_level, filename, line_num, function, |
| 323 | CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); | 320 | fmt::vformat(format, args)); |
| 324 | |||
| 325 | instance.PushEntry(std::move(entry)); | ||
| 326 | } | 321 | } |
| 327 | } // namespace Log | 322 | } // namespace Log |