// SPDX-FileCopyrightText: Matteo Settenvini // SPDX-License-Identifier: GPL-3.0-or-later #include "logger.hh" #include #include #include #include #include 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::_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(); } 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::max()); // clamp to avoid malicious overflows ::syslog(priority, "%.*s", static_cast(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(); }