Kea 2.7.5
logger_manager.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 <vector>
11
12#include <log/logger.h>
13#include <log/logger_manager.h>
15#include <log/logger_name.h>
16#include <log/logger_support.h>
17#include <log/log_messages.h>
18#include <log/macros.h>
22#include <log/message_reader.h>
23#include <log/message_types.h>
25
26using namespace std;
27
28// Older log4cplus versions (1.2.0) don't have the initializer.h header that
29// would allow explicit initialization. Newer versions (2.0.4 for sure, possibly
30// older as well) have it and it's recommended to use it. We detect whether
31// it's present or not and do explicit initialization if possible.
32#ifdef LOG4CPLUS_INITIALIZER_H
33#include <log4cplus/initializer.h>
34namespace {
35log4cplus::Initializer initializer;
36}
37#endif
38
39namespace {
40
41// Logger used for logging messages within the logging code itself.
43
44// Static stores for the initialization severity and debug level.
45// These are put in methods to avoid a "static initialization fiasco".
46
47isc::log::Severity& initSeverity() {
48 static isc::log::Severity severity = isc::log::INFO;
49 return (severity);
50}
51
52int& initDebugLevel() {
53 static int dbglevel = 0;
54 return (dbglevel);
55}
56
57std::string& initRootName() {
58 static std::string root(isc::log::getDefaultRootLoggerName());
59 return (root);
60}
61
62} // Anonymous namespace
63
64
65namespace isc {
66namespace log {
67
68// Constructor - create the implementation class.
72
73// Destructor - get rid of the implementation class
75 delete impl_;
76}
77
78// Initialize processing
79void
80LoggerManager::processInit() {
81 impl_->processInit();
82}
83
84// Process logging specification
85void
86LoggerManager::processSpecification(const LoggerSpecification& spec) {
87 impl_->processSpecification(spec);
88}
89
90// End Processing
91void
92LoggerManager::processEnd() {
93 impl_->processEnd();
94}
95
96
98
99void
100LoggerManager::init(const std::string& root, isc::log::Severity severity,
101 int dbglevel, const char* file, bool buffer)
102{
103 // Load in the messages declared in the program and registered by
104 // statically-declared MessageInitializer objects.
106
107 // Save name, severity and debug level for later. No need to save the
108 // file name as once the local message file is read the messages will
109 // not be lost.
110 initRootName() = root;
111 initSeverity() = severity;
112 initDebugLevel() = dbglevel;
113
114 // Create the Kea root logger and set the default severity and
115 // debug level. This is the logger that has the name of the application.
116 // All other loggers created in this application will be its children.
117 setRootLoggerName(root);
118
119 // Initialize the implementation logging. After this point, some basic
120 // logging has been set up and messages can be logged.
121 // However, they will not appear until a logging specification has been
122 // processed (or the program exits), see TODO
123 LoggerManagerImpl::init(severity, dbglevel, buffer);
125
126 // Check if there were any duplicate message IDs in the default dictionary
127 // and if so, log them. Log using the logging facility logger.
129
130 // Replace any messages with local ones (if given)
131 if (file) {
133 }
134
135 // Ensure that the mutex is constructed and ready at this point.
136 (void) getMutex();
137}
138
139void
141 const list<string>& duplicates = MessageInitializer::getDuplicates();
142 if (!duplicates.empty()) {
143
144 // There are duplicates present. This list itself may contain
145 // duplicates; if so, the message ID is listed as many times as
146 // there are duplicates.
147 for (auto const& i : duplicates) {
148 LOG_WARN(logger, LOG_DUPLICATE_MESSAGE_ID).arg(i);
149 }
151 }
152}
153
154
155// Read local message file
156// TODO This should be done after the configuration has been read so that
157// the file can be placed in the local configuration
158void
160
162 MessageReader reader(dictionary.get());
163
164 // Turn off use of any lock files. This is because this logger can
165 // be used by standalone programs which may not have write access to
166 // the local state directory (to create lock files). So we switch to
167 // using a null interprocess sync object here.
168 logger.setInterprocessSync(
170
171 try {
172
173 logger.info(LOG_READING_LOCAL_FILE).arg(file);
174 reader.readFile(file, MessageReader::REPLACE);
175
176 // File successfully read. As each message in the file is supposed to
177 // replace one in the dictionary, any ID read that can't be located in
178 // the dictionary will not be used. To aid problem diagnosis, the
179 // unknown message IDs are listed.
180 MessageReader::MessageIDCollection unknown = reader.getNotAdded();
181 for (MessageReader::MessageIDCollection::const_iterator
182 i = unknown.begin(); i != unknown.end(); ++i) {
183 string message_id = boost::lexical_cast<string>(*i);
184 logger.warn(LOG_NO_SUCH_MESSAGE).arg(message_id);
185 }
186 }
187 catch (const MessageException& e) {
188 MessageID ident = e.id();
189 vector<string> args = e.arguments();
190
191 // Log the variable number of arguments. The actual message will be
192 // logged when the error_message variable is destroyed.
193 Formatter<isc::log::Logger> error_message = logger.error(ident);
194 for (vector<string>::size_type i = 0; i < args.size(); ++i) {
195 error_message = error_message.arg(args[i]);
196 }
197 }
198}
199
200// Reset logging to settings passed to init()
201void
203 setRootLoggerName(initRootName());
204 LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
205}
206
207std::mutex&
209 static std::mutex mutex;
210
211 return (mutex);
212}
213
214} // namespace log
215} // namespace isc
Formatter & arg(const Arg &value)
Replaces another placeholder.
Logger Manager Implementation.
void processSpecification(const LoggerSpecification &spec)
Process Specification.
void processEnd()
End Processing.
static void init(isc::log::Severity severity=isc::log::INFO, int dbglevel=0, bool buffer=false)
Implementation-specific initialization.
static void reset(isc::log::Severity severity=isc::log::INFO, int dbglevel=0)
Reset logging.
void processInit()
Initialize Processing.
static void init(const std::string &root, isc::log::Severity severity=isc::log::INFO, int dbglevel=0, const char *file=NULL, bool buffer=false)
Run-Time Initialization.
static void reset()
Reset logging.
static void logDuplicatedMessages()
List duplicated log messages.
static std::mutex & getMutex()
Return a process-global mutex that's used for mutual exclusion among threads of a single process duri...
static void readLocalMessageFile(const char *file)
Read local message file.
Logger Class.
Definition log/logger.h:142
Formatter error(const MessageID &ident)
Output Error Message.
Formatter info(const MessageID &ident)
Output Informational Message.
Formatter warn(const MessageID &ident)
Output Warning Message.
void setInterprocessSync(isc::log::interprocess::InterprocessSync *sync)
Replace the interprocess synchronization object.
static const MessageDictionaryPtr & globalDictionary()
Return Global Dictionary.
static void loadDictionary(bool ignore_duplicates=false)
Run-Time Initialization.
static const std::list< std::string > & getDuplicates()
Return Duplicates.
static void clearDuplicates()
Clear the static duplicates list.
Read Message File.
std::vector< std::string > MessageIDCollection
Visible collection types.
Logging initialization functions.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
isc::log::Logger logger("asiodns")
Use the ASIO logger.
void setLoggingInitialized(bool state)
Set state of "logging initialized" flag.
const isc::log::MessageID LOG_NO_SUCH_MESSAGE
const isc::log::MessageID LOG_DUPLICATE_MESSAGE_ID
void setRootLoggerName(const std::string &name)
Set root logger name.
const isc::log::MessageID LOG_READING_LOCAL_FILE
const std::string & getDefaultRootLoggerName()
Returns the default ('kea') root logger name.
boost::shared_ptr< MessageDictionary > MessageDictionaryPtr
Shared pointer to the MessageDictionary.
const char * MessageID
Severity
Severity Levels.
Defines the logger used by the top-level component of kea-lfc.