Kea 2.7.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
10#include <algorithm>
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/static_assert.hpp>
21#include <boost/algorithm/string.hpp>
22
23#include <log4cplus/configurator.h>
24#include <log4cplus/consoleappender.h>
25#include <log4cplus/fileappender.h>
26#include <log4cplus/loggingmacros.h>
27#include <log4cplus/syslogappender.h>
28#include <log4cplus/version.h>
29
30#include <log/logger.h>
31#include <log/logger_impl.h>
32#include <log/logger_level.h>
34#include <log/logger_name.h>
35#include <log/logger_manager.h>
37#include <log/message_types.h>
40
41// Note: as log4cplus and the Kea logger have many concepts in common, and
42// thus many similar names, to disambiguate types we don't "use" the log4cplus
43// namespace: instead, all log4cplus types are explicitly qualified.
44
45using namespace std;
46
47namespace isc {
48namespace log {
49
56 const char* const env = getenv("KEA_LOCKFILE_DIR");
57 if (env && boost::iequals(string(env), string("none"))) {
58 return (false);
59 }
60
61 return (true);
62}
63
64// Constructor. The setting of logger_ must be done when the variable is
65// constructed (instead of being left to the body of the function); at least
66// one compiler requires that all member variables be constructed before the
67// constructor is run, but log4cplus::Logger (the type of logger_) has no
68// default constructor.
69LoggerImpl::LoggerImpl(const string& name) :
71 logger_(log4cplus::Logger::getInstance(name_))
72{
73 if (lockfileEnabled()) {
74 sync_ = new interprocess::InterprocessSyncFile("logger");
75 } else {
76 sync_ = new interprocess::InterprocessSyncNull("logger");
77 }
78}
79
80// Destructor. (Here because of virtual declaration.)
81
83 delete sync_;
84}
85
87std::string
89 std::ostringstream ver;
90 ver << "log4cplus ";
91 ver << log4cplus::versionStr;
92 return (ver.str());
93}
94
95// Set the severity for logging.
96void
98 Level level(severity, dbglevel);
99 logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
100}
101
102// Return severity level
105 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
106 return level.severity;
107}
108
109// Return current debug level (only valid if current severity level is DEBUG).
110int
112 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
113 return level.dbglevel;
114}
115
116// Get effective severity. Either the current severity or, if not set, the
117// severity of the root level.
120 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
121 return level.severity;
122}
123
124// Return effective debug level (only valid if current effective severity level
125// is DEBUG).
126int
128 Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
129 return level.dbglevel;
130}
131
132
133// Output a general message
134boost::shared_ptr<string>
136 return (boost::make_shared<string>(string(ident) + " " +
137 MessageDictionary::globalDictionary()->getText(ident)));
138}
139
140// Replace the interprocess synchronization object
141
142void
144 if (sync == NULL) {
146 "NULL was passed to setInterprocessSync()");
147 }
148
149 delete sync_;
150 sync_ = sync;
151}
152
153void
154LoggerImpl::outputRaw(const Severity& severity, const string& message) {
155 // Use a mutex locker for mutual exclusion from other threads in
156 // this process.
157 std::lock_guard<std::mutex> mutex_locker(LoggerManager::getMutex());
158
159 // Use an interprocess sync locker for mutual exclusion from other
160 // processes to avoid log messages getting interspersed.
162
163 if (!locker.lock()) {
164 LOG4CPLUS_ERROR(logger_, "Unable to lock logger lockfile");
165 }
166
167 switch (severity) {
168 case DEBUG:
169 LOG4CPLUS_DEBUG(logger_, message);
170 break;
171
172 case INFO:
173 LOG4CPLUS_INFO(logger_, message);
174 break;
175
176 case WARN:
177 LOG4CPLUS_WARN(logger_, message);
178 break;
179
180 case ERROR:
181 LOG4CPLUS_ERROR(logger_, message);
182 break;
183
184 case FATAL:
185 LOG4CPLUS_FATAL(logger_, message);
186 break;
187
188 case NONE:
189 break;
190
191 default:
192 LOG4CPLUS_ERROR(logger_,
193 "Unsupported severity in LoggerImpl::outputRaw(): "
194 << severity);
195 }
196
197 if (!locker.unlock()) {
198 LOG4CPLUS_ERROR(logger_, "Unable to unlock logger lockfile");
199 }
200}
201
202bool
204 // Get the appender for the name under which this logger is registered.
205 log4cplus::SharedAppenderPtrList appenders(
206 log4cplus::Logger::getInstance(name_).getAllAppenders());
207
208 // If there are no appenders, they might be under the root name.
209 if (appenders.size() == 0) {
210 appenders = log4cplus::Logger::getInstance(getRootLoggerName()).getAllAppenders();
211 }
212
213 for (const log4cplus::helpers::SharedObjectPtr<log4cplus::Appender>& logger : appenders) {
214 if (destination == OutputOption::DEST_CONSOLE &&
215 dynamic_cast<log4cplus::ConsoleAppender*>(logger.get())) {
216 return true;
217 } else if (destination == OutputOption::DEST_FILE &&
218 dynamic_cast<log4cplus::FileAppender*>(logger.get())) {
219 return true;
220 } else if (destination == OutputOption::DEST_SYSLOG &&
221 dynamic_cast<log4cplus::SysLogAppender*>(logger.get())) {
222 return true;
223 }
224 }
225 return false;
226}
227
228} // namespace log
229} // 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.
const Name & 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.