Kea  1.5.0
logger_manager.cc
Go to the documentation of this file.
1 // Copyright (C) 2011-2015 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>
23 #include <log/message_reader.h>
24 #include <log/message_types.h>
26 
27 using namespace std;
28 
29 namespace {
30 
31 // Logger used for logging messages within the logging code itself.
33 
34 // Static stores for the initialization severity and debug level.
35 // These are put in methods to avoid a "static initialization fiasco".
36 
37 isc::log::Severity& initSeverity() {
38  static isc::log::Severity severity = isc::log::INFO;
39  return (severity);
40 }
41 
42 int& initDebugLevel() {
43  static int dbglevel = 0;
44  return (dbglevel);
45 }
46 
47 std::string& initRootName() {
48  static std::string root(isc::log::getDefaultRootLoggerName());
49  return (root);
50 }
51 
52 } // Anonymous namespace
53 
54 
55 namespace isc {
56 namespace log {
57 
58 // Constructor - create the implementation class.
59 LoggerManager::LoggerManager() {
60  impl_ = new LoggerManagerImpl();
61 }
62 
63 // Destructor - get rid of the implementation class
64 LoggerManager::~LoggerManager() {
65  delete impl_;
66 }
67 
68 // Initialize processing
69 void
70 LoggerManager::processInit() {
71  impl_->processInit();
72 }
73 
74 // Process logging specification
75 void
76 LoggerManager::processSpecification(const LoggerSpecification& spec) {
77  impl_->processSpecification(spec);
78 }
79 
80 // End Processing
81 void
82 LoggerManager::processEnd() {
83  impl_->processEnd();
84 }
85 
86 
88 
89 void
90 LoggerManager::init(const std::string& root, isc::log::Severity severity,
91  int dbglevel, const char* file, bool buffer)
92 {
93  // Load in the messages declared in the program and registered by
94  // statically-declared MessageInitializer objects.
95  MessageInitializer::loadDictionary();
96 
97  // Save name, severity and debug level for later. No need to save the
98  // file name as once the local message file is read the messages will
99  // not be lost.
100  initRootName() = root;
101  initSeverity() = severity;
102  initDebugLevel() = dbglevel;
103 
104  // Create the Kea root logger and set the default severity and
105  // debug level. This is the logger that has the name of the application.
106  // All other loggers created in this application will be its children.
107  setRootLoggerName(root);
108 
109  // Initialize the implementation logging. After this point, some basic
110  // logging has been set up and messages can be logged.
111  // However, they will not appear until a logging specification has been
112  // processed (or the program exits), see TODO
113  LoggerManagerImpl::init(severity, dbglevel, buffer);
115 
116  // Check if there were any duplicate message IDs in the default dictionary
117  // and if so, log them. Log using the logging facility logger.
118  logDuplicatedMessages();
119 
120  // Replace any messages with local ones (if given)
121  if (file) {
122  readLocalMessageFile(file);
123  }
124 
125  // Ensure that the mutex is constructed and ready at this point.
126  (void) getMutex();
127 }
128 
129 void
130 LoggerManager::logDuplicatedMessages() {
131  const list<string>& duplicates = MessageInitializer::getDuplicates();
132  if (!duplicates.empty()) {
133 
134  // There are duplicates present. This list itself may contain
135  // duplicates; if so, the message ID is listed as many times as
136  // there are duplicates.
137  for (list<string>::const_iterator i = duplicates.begin();
138  i != duplicates.end(); ++i) {
140  }
141  MessageInitializer::clearDuplicates();
142  }
143 }
144 
145 
146 // Read local message file
147 // TODO This should be done after the configuration has been read so that
148 // the file can be placed in the local configuration
149 void
150 LoggerManager::readLocalMessageFile(const char* file) {
151 
152  const MessageDictionaryPtr& dictionary = MessageDictionary::globalDictionary();
153  MessageReader reader(dictionary.get());
154 
155  // Turn off use of any lock files. This is because this logger can
156  // be used by standalone programs which may not have write access to
157  // the local state directory (to create lock files). So we switch to
158  // using a null interprocess sync object here.
161 
162  try {
163 
165  reader.readFile(file, MessageReader::REPLACE);
166 
167  // File successfully read. As each message in the file is supposed to
168  // replace one in the dictionary, any ID read that can't be located in
169  // the dictionary will not be used. To aid problem diagnosis, the
170  // unknown message IDs are listed.
171  MessageReader::MessageIDCollection unknown = reader.getNotAdded();
172  for (MessageReader::MessageIDCollection::const_iterator
173  i = unknown.begin(); i != unknown.end(); ++i) {
174  string message_id = boost::lexical_cast<string>(*i);
175  logger.warn(LOG_NO_SUCH_MESSAGE).arg(message_id);
176  }
177  }
178  catch (MessageException& e) {
179  MessageID ident = e.id();
180  vector<string> args = e.arguments();
181 
182  // Log the variable number of arguments. The actual message will be
183  // logged when the error_message variable is destroyed.
184  Formatter<isc::log::Logger> error_message = logger.error(ident);
185  for (vector<string>::size_type i = 0; i < args.size(); ++i) {
186  error_message = error_message.arg(args[i]);
187  }
188  }
189 }
190 
191 // Reset logging to settings passed to init()
192 void
193 LoggerManager::reset() {
194  setRootLoggerName(initRootName());
195  LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
196 }
197 
199 LoggerManager::getMutex() {
200  static isc::util::thread::Mutex mutex;
201 
202  return (mutex);
203 }
204 
205 } // namespace log
206 } // namespace isc
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
std::vector< std::string > arguments() const
Return Arguments.
Logger Class.
Definition: log/logger.h:143
const std::string & getDefaultRootLoggerName()
Returns the default ('kea') root logger name.
Definition: logger_name.cc:37
Logger Manager Implementation.
void setRootLoggerName(const std::string &name)
Set root logger name.
Definition: logger_name.cc:29
Severity
Severity Levels.
Definition: logger_level.h:23
void setLoggingInitialized(bool state)
Set state of "logging initialized" flag.
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.
Mutex with very simple interface.
Definition: sync.h:39
Logging initialization functions.
Formatter error(const MessageID &ident)
Output Error Message.
Definition: log/logger.cc:168
MessageID id() const
Return Message ID.
boost::shared_ptr< MessageDictionary > MessageDictionaryPtr
Shared pointer to the MessageDictionary.
Formatter warn(const MessageID &ident)
Output Warning Message.
Definition: log/logger.cc:158
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:148
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:190
std::vector< std::string > MessageIDCollection
Visible collection types.