From f5f56e1a1c4d9e9496fcb9d81131066a964ccd23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:15:43 +0200 Subject: Adding upstream version 2.4.1. Signed-off-by: Daniel Baumann --- src/lib/log/logger_impl.cc | 231 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/lib/log/logger_impl.cc (limited to 'src/lib/log/logger_impl.cc') diff --git a/src/lib/log/logger_impl.cc b/src/lib/log/logger_impl.cc new file mode 100644 index 0000000..f0e5298 --- /dev/null +++ b/src/lib/log/logger_impl.cc @@ -0,0 +1,231 @@ +// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// Note: as log4cplus and the Kea logger have many concepts in common, and +// thus many similar names, to disambiguate types we don't "use" the log4cplus +// namespace: instead, all log4cplus types are explicitly qualified. + +using namespace std; + +namespace isc { +namespace log { + +/// @brief detects whether file locking is enabled or disabled +/// +/// The lockfile is enabled by default. The only way to disable it is to +/// set KEA_LOCKFILE_DIR variable to 'none'. +/// @return true if lockfile is enabled, false otherwise +bool lockfileEnabled() { + const char* const env = getenv("KEA_LOCKFILE_DIR"); + if (env && boost::iequals(string(env), string("none"))) { + return (false); + } + + return (true); +} + +// Constructor. The setting of logger_ must be done when the variable is +// constructed (instead of being left to the body of the function); at least +// one compiler requires that all member variables be constructed before the +// constructor is run, but log4cplus::Logger (the type of logger_) has no +// default constructor. +LoggerImpl::LoggerImpl(const string& name) : + name_(expandLoggerName(name)), + logger_(log4cplus::Logger::getInstance(name_)) +{ + if (lockfileEnabled()) { + sync_ = new interprocess::InterprocessSyncFile("logger"); + } else { + sync_ = new interprocess::InterprocessSyncNull("logger"); + } +} + +// Destructor. (Here because of virtual declaration.) + +LoggerImpl::~LoggerImpl() { + delete sync_; +} + +/// \brief Version +std::string +LoggerImpl::getVersion() { + std::ostringstream ver; + ver << "log4cplus "; + ver << log4cplus::versionStr; + return (ver.str()); +} + +// Set the severity for logging. +void +LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) { + Level level(severity, dbglevel); + logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level)); +} + +// Return severity level +isc::log::Severity +LoggerImpl::getSeverity() { + Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel()); + return level.severity; +} + +// Return current debug level (only valid if current severity level is DEBUG). +int +LoggerImpl::getDebugLevel() { + Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel()); + return level.dbglevel; +} + +// Get effective severity. Either the current severity or, if not set, the +// severity of the root level. +isc::log::Severity +LoggerImpl::getEffectiveSeverity() { + Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel()); + return level.severity; +} + +// Return effective debug level (only valid if current effective severity level +// is DEBUG). +int +LoggerImpl::getEffectiveDebugLevel() { + Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel()); + return level.dbglevel; +} + + +// Output a general message +boost::shared_ptr +LoggerImpl::lookupMessage(const MessageID& ident) { + return (boost::make_shared(string(ident) + " " + + MessageDictionary::globalDictionary()->getText(ident))); +} + +// Replace the interprocess synchronization object + +void +LoggerImpl::setInterprocessSync(interprocess::InterprocessSync* sync) { + if (sync == NULL) { + isc_throw(BadInterprocessSync, + "NULL was passed to setInterprocessSync()"); + } + + delete sync_; + sync_ = sync; +} + +void +LoggerImpl::outputRaw(const Severity& severity, const string& message) { + // Use a mutex locker for mutual exclusion from other threads in + // this process. + std::lock_guard mutex_locker(LoggerManager::getMutex()); + + // Use an interprocess sync locker for mutual exclusion from other + // processes to avoid log messages getting interspersed. + interprocess::InterprocessSyncLocker locker(*sync_); + + if (!locker.lock()) { + LOG4CPLUS_ERROR(logger_, "Unable to lock logger lockfile"); + } + + switch (severity) { + case DEBUG: + LOG4CPLUS_DEBUG(logger_, message); + break; + + case INFO: + LOG4CPLUS_INFO(logger_, message); + break; + + case WARN: + LOG4CPLUS_WARN(logger_, message); + break; + + case ERROR: + LOG4CPLUS_ERROR(logger_, message); + break; + + case FATAL: + LOG4CPLUS_FATAL(logger_, message); + break; + + case NONE: + break; + + default: + LOG4CPLUS_ERROR(logger_, + "Unsupported severity in LoggerImpl::outputRaw(): " + << severity); + } + + if (!locker.unlock()) { + LOG4CPLUS_ERROR(logger_, "Unable to unlock logger lockfile"); + } +} + +bool +LoggerImpl::hasAppender(OutputOption::Destination const destination) { + // Get the appender for the name under which this logger is registered. + log4cplus::SharedAppenderPtrList appenders( + log4cplus::Logger::getInstance(name_).getAllAppenders()); + + // If there are no appenders, they might be under the root name. + if (appenders.size() == 0) { + appenders = log4cplus::Logger::getInstance(getRootLoggerName()).getAllAppenders(); + } + + for (log4cplus::helpers::SharedObjectPtr logger : appenders) { + if (destination == OutputOption::DEST_CONSOLE && + dynamic_cast(logger.get())) { + return true; + } else if (destination == OutputOption::DEST_FILE && + dynamic_cast(logger.get())) { + return true; + } else if (destination == OutputOption::DEST_SYSLOG && + dynamic_cast(logger.get())) { + return true; + } + } + return false; +} + +} // namespace log +} // namespace isc -- cgit v1.2.3