Refactor logging code

This commit is contained in:
Oliver Hamlet
2023-09-12 19:52:30 +01:00
parent 0a7efcb4d3
commit f0450a5bf4
4 changed files with 94 additions and 51 deletions
+1
View File
@@ -208,6 +208,7 @@ set(LIBLOOT_SRC_API_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/api/sorting/plugin_sorting_data.cpp"
"${CMAKE_SOURCE_DIR}/src/api/sorting/undefined_group_error.cpp"
"${CMAKE_SOURCE_DIR}/src/api/helpers/crc.cpp"
"${CMAKE_SOURCE_DIR}/src/api/helpers/logging.cpp"
"${CMAKE_SOURCE_DIR}/src/api/helpers/text.cpp"
"${CMAKE_SOURCE_DIR}/src/api/vertex.cpp")
+2 -4
View File
@@ -80,11 +80,9 @@ std::filesystem::path ResolvePath(const std::filesystem::path& path) {
LOOT_API void SetLoggingCallback(
std::function<void(LogLevel, const char*)> callback) {
auto sink = std::make_shared<SpdLoggingSink>(callback);
auto logger = std::make_shared<spdlog::logger>(LOGGER_NAME, sink);
logger->set_level(spdlog::level::level_enum::trace);
const auto logger = createLogger(callback);
spdlog::drop(LOGGER_NAME);
spdlog::drop(logger->name());
spdlog::register_logger(logger);
}
+88
View File
@@ -0,0 +1,88 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#include "api/helpers/logging.h"
#define FMT_USE_STD_STRING_VIEW
#include <spdlog/sinks/base_sink.h>
namespace {
using loot::LogLevel;
constexpr const char* LOGGER_NAME = "loot_api_logger";
LogLevel mapFromSpdlog(spdlog::level::level_enum severity) {
using spdlog::level::level_enum;
switch (severity) {
case level_enum::trace:
return LogLevel::trace;
case level_enum::debug:
return LogLevel::debug;
case level_enum::info:
return LogLevel::info;
case level_enum::warn:
return LogLevel::warning;
case level_enum::err:
return LogLevel::error;
case level_enum::critical:
return LogLevel::fatal;
default:
return LogLevel::trace;
}
}
class SpdLoggingSink : public spdlog::sinks::base_sink<std::mutex> {
public:
explicit SpdLoggingSink(std::function<void(LogLevel, const char*)> callback) {
this->callback = callback;
}
protected:
void sink_it_(const spdlog::details::log_msg& msg) override {
// string_view isn't necessarily null-terminated, so using
// msg.payload.data() directly isn't a good idea.
std::string payload = std::string(msg.payload.data(), msg.payload.size());
callback(mapFromSpdlog(msg.level), payload.c_str());
}
void flush_() override {}
private:
std::function<void(LogLevel, const char*)> callback;
};
}
namespace loot {
std::shared_ptr<spdlog::logger> getLogger() { return spdlog::get(LOGGER_NAME); }
std::shared_ptr<spdlog::logger> createLogger(
std::function<void(LogLevel, const char*)> callback) {
auto sink = std::make_shared<SpdLoggingSink>(callback);
auto logger = std::make_shared<spdlog::logger>(LOGGER_NAME, sink);
logger->set_level(spdlog::level::level_enum::trace);
return logger;
}
}
+3 -47
View File
@@ -24,59 +24,15 @@
#ifndef LOOT_API_HELPERS_LOGGING
#define LOOT_API_HELPERS_LOGGING
#define FMT_USE_STD_STRING_VIEW
#include <spdlog/sinks/base_sink.h>
#include <spdlog/spdlog.h>
#include "loot/enum/log_level.h"
namespace loot {
static constexpr const char* LOGGER_NAME = "loot_api_logger";
std::shared_ptr<spdlog::logger> getLogger();
inline std::shared_ptr<spdlog::logger> getLogger() {
return spdlog::get(LOGGER_NAME);
}
class SpdLoggingSink : public spdlog::sinks::base_sink<std::mutex> {
public:
explicit SpdLoggingSink(std::function<void(LogLevel, const char*)> callback) {
this->callback = callback;
}
protected:
void sink_it_(const spdlog::details::log_msg& msg) override {
// string_view isn't necessarily null-terminated, so using
// msg.payload.data() directly isn't a good idea.
std::string payload = std::string(msg.payload.data(), msg.payload.size());
callback(mapFromSpdlog(msg.level), payload.c_str());
}
void flush_() override {}
private:
std::function<void(LogLevel, const char*)> callback;
static LogLevel mapFromSpdlog(spdlog::level::level_enum severity) {
using spdlog::level::level_enum;
switch (severity) {
case level_enum::trace:
return LogLevel::trace;
case level_enum::debug:
return LogLevel::debug;
case level_enum::info:
return LogLevel::info;
case level_enum::warn:
return LogLevel::warning;
case level_enum::err:
return LogLevel::error;
case level_enum::critical:
return LogLevel::fatal;
default:
return LogLevel::trace;
}
}
};
std::shared_ptr<spdlog::logger> createLogger(
std::function<void(LogLevel, const char*)> callback);
}
#endif