Kea 3.1.5
logger_impl.cc
Go to the documentation of this file.
1// Copyright (C) 2011-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <algorithm>
10#include <cstdlib>
11#include <cstring>
12#include <iomanip>
13#include <iostream>
14#include <stdarg.h>
15#include <stdio.h>
16#include <sstream>
17
18#include <boost/make_shared.hpp>
19#include <boost/lexical_cast.hpp>
20#include <boost/algorithm/string.hpp>
21
22#include <log4cplus/configurator.h>
23#include <log4cplus/consoleappender.h>
24#include <log4cplus/fileappender.h>
25#include <log4cplus/loggingmacros.h>
26#include <log4cplus/syslogappender.h>
27#include <log4cplus/version.h>
28
29#include <log/logger.h>
30#include <log/logger_impl.h>
31#include <log/logger_level.h>
33#include <log/logger_name.h>
34#include <log/logger_manager.h>
36#include <log/message_types.h>
39
40// Note: as log4cplus and the Kea logger have many concepts in common, and
41// thus many similar names, to disambiguate types we don't "use" the log4cplus
42// namespace: instead, all log4cplus types are explicitly qualified.
43
44using namespace std;
45
46namespace isc {
47namespace log {
48
55 const char* const env = getenv("KEA_LOCKFILE_DIR");
56 if (env && boost::iequals(string(env), string("none"))) {
57 return (false);
58 }
59
60 return (true);
61}
62
63// Constructor. The setting of logger_ must be done when the variable is
64// constructed (instead of being left to the body of the function); at least
65// one compiler requires that all member variables be constructed before the
66// constructor is run, but log4cplus::Logger (the type of logger_) has no
67// default constructor.
68LoggerImpl::LoggerImpl(const string& name) :
69 name_(expandLoggerName(name)),
70 logger_(log4cplus::Logger::getInstance(name_))
71{
72 if (lockfileEnabled()) {
73 sync_ = new interprocess::InterprocessSyncFile("logger");
74 } else {
75 sync_ = new interprocess::InterprocessSyncNull("logger");
76 }
77}
78
79// Destructor. (Here because of virtual declaration.)
80
82 delete sync_;
83}
84
86std::string
88 std::ostringstream ver;
89 ver << "log4cplus ";
90 ver << log4cplus::versionStr;
91 return (ver.str());
92}
93
94// Set the severity for logging.
95void
97 Level level(severity, dbglevel);
98 logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
99}
100
101// Return severity level
104 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
105 return level.severity;
106}
107
108// Return current debug level (only valid if current severity level is DEBUG).
109int
111 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
112 return level.dbglevel;
113}
114
115// Get effective severity. Either the current severity or, if not set, the
116// severity of the root level.
119 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
120 return level.severity;
121}
122
123// Return effective debug level (only valid if current effective severity level
124// is DEBUG).
125int
127 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
128 return level.dbglevel;
129}
130
131
132// Output a general message
133boost::shared_ptr<string>
135 return (boost::make_shared<string>(string(ident) + " " +
136 MessageDictionary::globalDictionary()->getText(ident)));
137}
138
139// Replace the interprocess synchronization object
140
141void
143 if (sync == NULL) {
145 "NULL was passed to setInterprocessSync()");
146 }
147
148 delete sync_;
149 sync_ = sync;
150}
151
152void
153LoggerImpl::outputRaw(const Severity& severity, const string& message) {
154 // Use a mutex locker for mutual exclusion from other threads in
155 // this process.
156 std::lock_guard<std::mutex> mutex_locker(LoggerManager::getMutex());
157
158 // Use an interprocess sync locker for mutual exclusion from other
159 // processes to avoid log messages getting interspersed.
161
162 if (!locker.lock()) {
163 LOG4CPLUS_ERROR(logger_, "Unable to lock logger lockfile");
164 }
165
166 switch (severity) {
167 case DEBUG:
168 LOG4CPLUS_DEBUG(logger_, message);
169 break;
170
171 case INFO:
172 LOG4CPLUS_INFO(logger_, message);
173 break;
174
175 case WARN:
176 LOG4CPLUS_WARN(logger_, message);
177 break;
178
179 case ERROR:
180 LOG4CPLUS_ERROR(logger_, message);
181 break;
182
183 case FATAL:
184 LOG4CPLUS_FATAL(logger_, message);
185 break;
186
187 case NONE:
188 break;
189
190 default:
191 LOG4CPLUS_ERROR(logger_,
192 "Unsupported severity in LoggerImpl::outputRaw(): "
193 << severity);
194 }
195
196 if (!locker.unlock()) {
197 LOG4CPLUS_ERROR(logger_, "Unable to unlock logger lockfile");
198 }
199}
200
201bool
203 // Get the appender for the name under which this logger is registered.
204 log4cplus::SharedAppenderPtrList appenders(
205 log4cplus::Logger::getInstance(name_).getAllAppenders());
206
207 // If there are no appenders, they might be under the root name.
208 if (appenders.size() == 0) {
209 appenders = log4cplus::Logger::getInstance(getRootLoggerName()).getAllAppenders();
210 }
211
212 for (const log4cplus::helpers::SharedObjectPtr<log4cplus::Appender>& logger : appenders) {
213 if (destination == OutputOption::DEST_CONSOLE &&
214 dynamic_cast<log4cplus::ConsoleAppender*>(logger.get())) {
215 return true;
216 } else if (destination == OutputOption::DEST_FILE &&
217 dynamic_cast<log4cplus::FileAppender*>(logger.get())) {
218 return true;
219 } else if (destination == OutputOption::DEST_SYSLOG &&
220 dynamic_cast<log4cplus::SysLogAppender*>(logger.get())) {
221 return true;
222 }
223 }
224 return false;
225}
226
227} // namespace log
228} // namespace isc
Bad Interprocess Sync.
Definition log/logger.h:92
void outputRaw(const Severity &severity, const std::string &message)
Raw output.
virtual int getEffectiveDebugLevel()
Return effective debug level.
virtual void setSeverity(Severity severity, int dbglevel=1)
Set Severity Level for Logger.
boost::shared_ptr< std::string > lookupMessage(const MessageID &id)
Look up message text in dictionary.
virtual ~LoggerImpl()
Destructor.
void setInterprocessSync(isc::log::interprocess::InterprocessSync *sync)
Replace the interprocess synchronization object.
virtual Severity getEffectiveSeverity()
Get Effective Severity Level for Logger.
LoggerImpl(const std::string &name)
Constructor.
virtual int getDebugLevel()
Return debug level.
bool hasAppender(OutputOption::Destination const destination)
Check if this logger has an appender of the given type.
virtual Severity getSeverity()
Get Severity Level for Logger.
static std::string getVersion()
Version.
static log4cplus::LogLevel convertFromBindLevel(const isc::log::Level &level)
Convert Kea level to log4cplus logging level.
static isc::log::Level convertToBindLevel(const log4cplus::LogLevel loglevel)
Convert log4cplus logging level to Kea logging level.
static std::mutex & getMutex()
Return a process-global mutex that's used for mutual exclusion among threads of a single process duri...
Logger Class.
Definition log/logger.h:142
static const MessageDictionaryPtr & globalDictionary()
Return Global Dictionary.
bool lock()
Acquire the lock (blocks if something else has acquired a lock on the same task name)
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const std::string & getRootLoggerName()
Get root logger name.
std::string expandLoggerName(const std::string &name)
Expand logger name.
bool lockfileEnabled()
detects whether file locking is enabled or disabled
const char * MessageID
Severity
Severity Levels.
Defines the logger used by the top-level component of kea-lfc.
Log level structure.
int dbglevel
Debug level.
Severity severity
Logging severity.