malcontent/nss/logger.cc

77 lines
1.9 KiB
C++
Raw Normal View History

2024-01-05 18:10:45 +01:00
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "logger.hh"
#include <cstdlib>
#include <mutex>
#include <limits>
#include <sys/syslog.h>
#include <syslog.h>
namespace /* anonymous */ {
auto get_log_priority() -> int {
auto level = getenv("NSS_MALCONTENT_LOG_LEVEL");
if (level != nullptr) {
return atoi(level);
}
#ifdef NDEBUG
return LOG_WARNING;
#else
return LOG_DEBUG;
#endif
}
} // ~ namespace anonymous
std::unique_ptr<malcontent::Logger> malcontent::Logger::_instance = nullptr;
std::shared_mutex malcontent::Logger::_instance_mtx = {};
auto malcontent::Logger::debug(const std::string_view& msg) -> void {
instance().log(LOG_DEBUG, msg);
}
auto malcontent::Logger::info(const std::string_view& msg) -> void {
instance().log(LOG_INFO, msg);
}
auto malcontent::Logger::warn(const std::string_view& msg) -> void {
instance().log(LOG_WARNING, msg);
}
auto malcontent::Logger::error(const std::string_view& msg) -> void {
instance().log(LOG_ERR, msg);
}
auto malcontent::Logger::instance() -> Logger& {
{
std::shared_lock lock { _instance_mtx };
if (_instance) return *_instance;
}
// First invocation: construct lazily
std::unique_lock lock { _instance_mtx };
if (!_instance) {
_instance = std::make_unique<Logger>();
}
return *_instance;
}
auto malcontent::Logger::log(int priority, std::string_view msg) -> void {
if (priority <= _max_log_priority) {
msg = msg.substr(0, std::numeric_limits<int>::max()); // clamp to avoid malicious overflows
::syslog(priority, "%.*s", static_cast<int>(msg.length()), msg.data());
}
}
malcontent::Logger::Logger()
: _max_log_priority(get_log_priority())
{
::openlog("nss_malcontent", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
}
malcontent::Logger::~Logger() noexcept {
::closelog();
}