Skip to content

Commit 0de8931

Browse files
committed
perf(utils): snapshot spdlog logger and avoid mutex contention
1 parent 6d3aa36 commit 0de8931

2 files changed

Lines changed: 98 additions & 42 deletions

File tree

include/vix/utils/Logger.hpp

Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <memory>
4242
#include <mutex>
4343
#include <map>
44+
#include <unordered_map>
4445
#include <utility>
4546
#include <stdexcept>
4647
#include <iostream>
@@ -147,43 +148,59 @@ namespace vix::utils
147148
if (level == Level::OFF)
148149
return;
149150

150-
std::lock_guard<std::mutex> lock(mutex_);
151-
if (!spd_)
152-
return;
153-
154-
vix::utils::console_wait_banner();
155-
std::lock_guard<std::mutex> lk(vix::utils::console_mutex());
151+
std::shared_ptr<spdlog::logger> spd;
152+
{
153+
std::lock_guard<std::mutex> lock(mutex_);
154+
spd = spd_;
155+
if (!spd)
156+
return;
157+
if (!spd->should_log(toSpdLevel(level)))
158+
return;
159+
}
156160

157-
switch (level)
161+
if (console_sync_enabled())
158162
{
159-
case Level::TRACE:
160-
spd_->trace(fmtstr, std::forward<Args>(args)...);
161-
break;
162-
case Level::DEBUG:
163-
spd_->debug(fmtstr, std::forward<Args>(args)...);
164-
break;
165-
case Level::INFO:
166-
spd_->info(fmtstr, std::forward<Args>(args)...);
167-
break;
168-
case Level::WARN:
169-
spd_->warn(fmtstr, std::forward<Args>(args)...);
170-
break;
171-
case Level::ERROR:
172-
spd_->error(fmtstr, std::forward<Args>(args)...);
173-
break;
174-
case Level::CRITICAL:
175-
spd_->critical(fmtstr, std::forward<Args>(args)...);
176-
break;
177-
case Level::OFF:
163+
vix::utils::console_wait_banner();
164+
std::lock_guard<std::mutex> lk(vix::utils::console_mutex());
165+
spd->log(toSpdLevel(level), fmtstr, std::forward<Args>(args)...);
178166
return;
179167
}
168+
169+
spd->log(toSpdLevel(level), fmtstr, std::forward<Args>(args)...);
180170
}
181171

182172
template <typename... Args>
183-
void logModule(const std::string &module, Level level,
184-
fmt::format_string<Args...> fmtstr, Args &&...args)
173+
void logModule(std::string_view module,
174+
Level level,
175+
fmt::format_string<Args...> fmtstr,
176+
Args &&...args)
185177
{
186-
log(level, "[{}] {}", module, fmt::format(fmtstr, std::forward<Args>(args)...));
178+
if (level == Level::OFF)
179+
return;
180+
181+
std::shared_ptr<spdlog::logger> spd;
182+
{
183+
std::lock_guard<std::mutex> lock(mutex_);
184+
spd = spd_;
185+
if (!spd)
186+
return;
187+
if (!spd->should_log(toSpdLevel(level)))
188+
return;
189+
}
190+
191+
fmt::memory_buffer buf;
192+
fmt::format_to(std::back_inserter(buf), "[{}] ", module);
193+
fmt::format_to(std::back_inserter(buf), fmtstr, std::forward<Args>(args)...);
194+
195+
if (console_sync_enabled())
196+
{
197+
vix::utils::console_wait_banner();
198+
std::lock_guard<std::mutex> lk(vix::utils::console_mutex());
199+
spd->log(toSpdLevel(level), "{}", fmt::to_string(buf));
200+
return;
201+
}
202+
203+
spd->log(toSpdLevel(level), "{}", fmt::to_string(buf));
187204
}
188205

189206
template <typename... Args>
@@ -204,7 +221,7 @@ namespace vix::utils
204221
{
205222
std::string request_id;
206223
std::string module;
207-
std::map<std::string, std::string> fields;
224+
std::unordered_map<std::string, std::string> fields;
208225

209226
Context() : request_id(), module(), fields() {}
210227
};
@@ -219,25 +236,27 @@ namespace vix::utils
219236
template <typename... Args>
220237
void logf(Level level, const std::string &msg, Args &&...kvpairs)
221238
{
222-
std::lock_guard<std::mutex> lock(mutex_);
223-
if (!spd_)
239+
if (level == Level::OFF)
224240
return;
225241

226-
vix::utils::console_wait_banner();
242+
std::lock_guard<std::mutex> lock(mutex_);
243+
if (!spd_ || !spd_->should_log(toSpdLevel(level)))
244+
return;
227245

228-
std::lock_guard<std::mutex> lk(vix::utils::console_mutex());
246+
if (console_sync_enabled())
247+
{
248+
vix::utils::console_wait_banner();
249+
std::lock_guard<std::mutex> lk(vix::utils::console_mutex());
250+
}
229251

230252
if (format_ == Format::JSON_PRETTY)
231253
{
232-
const std::string json = buildJsonPretty(level, msg, std::forward<Args>(kvpairs)...);
233-
spd_->log(toSpdLevel(level), "{}", json);
254+
spd_->log(toSpdLevel(level), "{}", buildJsonPretty(level, msg, std::forward<Args>(kvpairs)...));
234255
return;
235256
}
236-
237257
if (format_ == Format::JSON)
238258
{
239-
const std::string json = buildJsonLine(level, msg, std::forward<Args>(kvpairs)...);
240-
spd_->log(toSpdLevel(level), "{}", json);
259+
spd_->log(toSpdLevel(level), "{}", buildJsonLine(level, msg, std::forward<Args>(kvpairs)...));
241260
return;
242261
}
243262

@@ -260,6 +279,36 @@ namespace vix::utils
260279
static Level parseLevelFromEnv(std::string_view envName = "VIX_LOG_LEVEL", Level fallback = Level::WARN);
261280
static bool jsonColorsEnabled();
262281

282+
Level level() const noexcept
283+
{
284+
std::lock_guard<std::mutex> lock(mutex_);
285+
if (!spd_)
286+
return Level::OFF;
287+
288+
const auto lvl = spd_->level();
289+
if (lvl == spdlog::level::trace)
290+
return Level::TRACE;
291+
if (lvl == spdlog::level::debug)
292+
return Level::DEBUG;
293+
if (lvl == spdlog::level::info)
294+
return Level::INFO;
295+
if (lvl == spdlog::level::warn)
296+
return Level::WARN;
297+
if (lvl == spdlog::level::err)
298+
return Level::ERROR;
299+
if (lvl == spdlog::level::critical)
300+
return Level::CRITICAL;
301+
return Level::OFF;
302+
}
303+
304+
bool enabled(Level lvl) const noexcept
305+
{
306+
std::lock_guard<std::mutex> lock(mutex_);
307+
if (!spd_)
308+
return false;
309+
return spd_->should_log(toSpdLevel(lvl));
310+
}
311+
263312
private:
264313
Logger();
265314

@@ -287,7 +336,7 @@ namespace vix::utils
287336
}
288337

289338
std::shared_ptr<spdlog::logger> spd_;
290-
std::mutex mutex_;
339+
mutable std::mutex mutex_;
291340
Format format_ = Format::KV;
292341

293342
static thread_local Context tls_ctx_;
@@ -734,6 +783,13 @@ namespace vix::utils
734783
static std::string c_num(std::string_view s, bool on) { return ansi_wrap("\033[33m", s, on); } // yellow
735784
static std::string c_bool(std::string_view s, bool on) { return ansi_wrap("\033[35m", s, on); } // magenta
736785
static std::string c_punc(std::string_view s, bool on) { return ansi_wrap("\033[90m", s, on); } // gray
786+
787+
static bool console_sync_enabled()
788+
{
789+
if (const char *v = std::getenv("VIX_CONSOLE_SYNC"); v && *v)
790+
return std::string_view(v) != "0" && std::string_view(v) != "false";
791+
return false;
792+
}
737793
};
738794
}
739795

src/Logger.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ namespace vix::utils
123123
if (enable)
124124
{
125125
if (!spdlog::thread_pool())
126-
spdlog::init_thread_pool(8192, 1);
126+
spdlog::init_thread_pool(262144, 1);
127127

128128
auto async_logger = std::make_shared<spdlog::async_logger>(
129129
"vix",
130130
sinks.begin(),
131131
sinks.end(),
132132
spdlog::thread_pool(),
133-
spdlog::async_overflow_policy::block);
133+
spdlog::async_overflow_policy::overrun_oldest);
134134

135135
async_logger->set_level(lvl);
136136
async_logger->flush_on(flush);

0 commit comments

Comments
 (0)