Kea  1.9.9-git
logger_manager.cc
Go to the documentation of this file.
1 // Copyright (C) 2011-2021 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>
19 #include <log/message_dictionary.h>
20 #include <log/message_exception.h>
22 #include <log/message_reader.h>
23 #include <log/message_types.h>
25 
26 using 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>
34 namespace {
35 log4cplus::Initializer initializer;
36 }
37 #endif
38 
39 namespace {
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 
47 isc::log::Severity& initSeverity() {
48  static isc::log::Severity severity = isc::log::INFO;
49  return (severity);
50 }
51 
52 int& initDebugLevel() {
53  static int dbglevel = 0;
54  return (dbglevel);
55 }
56 
57 std::string& initRootName() {
58  static std::string root(isc::log::getDefaultRootLoggerName());
59  return (root);
60 }
61 
62 } // Anonymous namespace
63 
64 
65 namespace isc {
66 namespace log {
67 
68 // Constructor - create the implementation class.
69 LoggerManager::LoggerManager() {
70  impl_ = new LoggerManagerImpl();
71 }
72 
73 // Destructor - get rid of the implementation class
74 LoggerManager::~LoggerManager() {
75  delete impl_;
76 }
77 
78 // Initialize processing
79 void
80 LoggerManager::processInit() {
81  impl_->processInit();
82 }
83 
84 // Process logging specification
85 void
86 LoggerManager::processSpecification(const LoggerSpecification& spec) {
87  impl_->processSpecification(spec);
88 }
89 
90 // End Processing
91 void
92 LoggerManager::processEnd() {
93  impl_->processEnd();
94 }
95 
96 
98 
99 void
100 LoggerManager::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.
105  MessageInitializer::loadDictionary();
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.
128  logDuplicatedMessages();
129 
130  // Replace any messages with local ones (if given)
131  if (file) {
132  readLocalMessageFile(file);
133  }
134 
135  // Ensure that the mutex is constructed and ready at this point.
136  (void) getMutex();
137 }
138 
139 void
140 LoggerManager::logDuplicatedMessages() {
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 (list<string>::const_iterator i = duplicates.begin();
148  i != duplicates.end(); ++i) {
150  }
151  MessageInitializer::clearDuplicates();
152  }
153 }
154 
155 
156 // Read local message file
157 // TODO This should be done after the configuration has been read so that
158 // the file can be placed in the local configuration
159 void
160 LoggerManager::readLocalMessageFile(const char* file) {
161 
162  const MessageDictionaryPtr& dictionary = MessageDictionary::globalDictionary();
163  MessageReader reader(dictionary.get());
164 
165  // Turn off use of any lock files. This is because this logger can
166  // be used by standalone programs which may not have write access to
167  // the local state directory (to create lock files). So we switch to
168  // using a null interprocess sync object here.
171 
172  try {
173 
175  reader.readFile(file, MessageReader::REPLACE);
176 
177  // File successfully read. As each message in the file is supposed to
178  // replace one in the dictionary, any ID read that can't be located in
179  // the dictionary will not be used. To aid problem diagnosis, the
180  // unknown message IDs are listed.
181  MessageReader::MessageIDCollection unknown = reader.getNotAdded();
182  for (MessageReader::MessageIDCollection::const_iterator
183  i = unknown.begin(); i != unknown.end(); ++i) {
184  string message_id = boost::lexical_cast<string>(*i);
185  logger.warn(LOG_NO_SUCH_MESSAGE).arg(message_id);
186  }
187  }
188  catch (const MessageException& e) {
189  MessageID ident = e.id();
190  vector<string> args = e.arguments();
191 
192  // Log the variable number of arguments. The actual message will be
193  // logged when the error_message variable is destroyed.
194  Formatter<isc::log::Logger> error_message = logger.error(ident);
195  for (vector<string>::size_type i = 0; i < args.size(); ++i) {
196  error_message = error_message.arg(args[i]);
197  }
198  }
199 }
200 
201 // Reset logging to settings passed to init()
202 void
203 LoggerManager::reset() {
204  setRootLoggerName(initRootName());
205  LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
206 }
207 
208 std::mutex&
209 LoggerManager::getMutex() {
210  static std::mutex mutex;
211 
212  return (mutex);
213 }
214 
215 } // namespace log
216 } // namespace isc
Initializer initializer
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
Logger Class.
Definition: log/logger.h:141
const std::string & getDefaultRootLoggerName()
Returns the default ('kea') root logger name.
Definition: logger_name.cc:37
Logger Manager Implementation.
STL namespace.
void setRootLoggerName(const std::string &name)
Set root logger name.
Definition: logger_name.cc:29
std::vector< std::string > arguments() const
Return Arguments.
Severity
Severity Levels.
Definition: logger_level.h:23
void setLoggingInitialized(bool state)
Set state of "logging initialized" flag.
MessageID id() const
Return Message ID.
Formatter & arg(const Arg &value)
Replaces another placeholder.
const isc::log::MessageID LOG_READING_LOCAL_FILE
Definition: log_messages.h:27
Defines the logger used by the top-level component of kea-dhcp-ddns.
isc::log::Logger logger("asiodns")
Use the ASIO logger.
The log message formatter.
Logging initialization functions.
Formatter error(const MessageID &ident)
Output Error Message.
Definition: log/logger.cc:181
boost::shared_ptr< MessageDictionary > MessageDictionaryPtr
Shared pointer to the MessageDictionary.
Formatter warn(const MessageID &ident)
Output Warning Message.
Definition: log/logger.cc:171
const isc::log::MessageID LOG_DUPLICATE_MESSAGE_ID
Definition: log_messages.h:14
Read Message File.
Formatter info(const MessageID &ident)
Output Informational Message.
Definition: log/logger.cc:161
const char * MessageID
Definition: message_types.h:15
const isc::log::MessageID LOG_NO_SUCH_MESSAGE
Definition: log_messages.h:23
void setInterprocessSync(isc::log::interprocess::InterprocessSync *sync)
Replace the interprocess synchronization object.
Definition: log/logger.cc:203
std::vector< std::string > MessageIDCollection
Visible collection types.