VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
Logger.cpp
Go to the documentation of this file.
2#include <atomic>
3#include <deque>
4#include <mutex>
5#include <thread>
6#include <utility>
7
8namespace VoltMod::Log
9{
10
12static std::thread::id g_gameThread{};
13/** What the host wants from this module. Read on every log call, written once a frame. */
14static std::atomic<LogLevel> g_minimumLevel{LogLevel::Info};
15
16static std::mutex g_deferredMutex;
17static std::deque<std::pair<LogLevel, std::string>> g_deferred;
18/** Read by DeliverPending every game frame, so the common empty case never takes the lock or
19 * builds a container. Only ever set true under @ref g_deferredMutex. */
20static std::atomic<bool> g_hasDeferred{false};
21
22/** A worker that logs in a tight failure loop must not grow this without bound; past the cap
23 * the oldest lines go, because the first error is rarely the interesting one. */
24static constexpr size_t MaxDeferred = 256;
25
27{
28 g_handler = std::move(handler);
29 g_gameThread = std::this_thread::get_id();
30}
31
32bool Enabled()
33{
34 return static_cast<bool>(g_handler);
35}
36
38{
39 g_minimumLevel.store(level, std::memory_order_relaxed);
40}
41
43{
44 return g_minimumLevel.load(std::memory_order_relaxed);
45}
46
47void Emit(LogLevel level, std::string message)
48{
49 if (!g_handler)
50 {
51 return;
52 }
53
54 if (std::this_thread::get_id() == g_gameThread)
55 {
57 return;
58 }
59
60 std::lock_guard lock(g_deferredMutex);
61 if (g_deferred.size() >= MaxDeferred)
62 {
63 g_deferred.pop_front();
64 }
65 g_deferred.emplace_back(level, std::move(message));
66 g_hasDeferred.store(true, std::memory_order_release);
67}
68
70{
71 if (!g_hasDeferred.load(std::memory_order_acquire))
72 {
73 return;
74 }
75
76 std::deque<std::pair<LogLevel, std::string>> ready;
77 {
78 std::lock_guard lock(g_deferredMutex);
79 ready.swap(g_deferred);
80 g_hasDeferred.store(false, std::memory_order_release);
81 }
82
83 if (!g_handler)
84 {
85 return;
86 }
87
88 for (const auto& [level, message] : ready)
89 {
91 }
92}
93
94} // namespace VoltMod::Log
bool Enabled()
Definition Logger.cpp:32
static constexpr size_t MaxDeferred
Definition Logger.cpp:24
std::function< void(LogLevel level, std::string_view message)> Handler
Where log lines end up.
Definition Log.hpp:30
LogLevel MinimumLevel()
Definition Logger.cpp:42
static Handler g_handler
Definition Logger.cpp:11
void DeliverPending()
Definition Logger.cpp:69
void Emit(LogLevel level, std::string message)
Definition Logger.cpp:47
static std::thread::id g_gameThread
Definition Logger.cpp:12
static std::deque< std::pair< LogLevel, std::string > > g_deferred
Definition Logger.cpp:17
static std::mutex g_deferredMutex
Definition Logger.cpp:16
void SetHandler(Handler handler)
Definition Logger.cpp:26
static std::atomic< LogLevel > g_minimumLevel
Definition Logger.cpp:14
static std::atomic< bool > g_hasDeferred
Definition Logger.cpp:20
void SetMinimumLevel(LogLevel level)
Definition Logger.cpp:37
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56
LogLevel
Definition Log.hpp:13