Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <algorithm>
16 : : #include <vector>
17 : :
18 : : #include <log/logger.h>
19 : : #include <log/logger_manager.h>
20 : : #include <log/logger_manager_impl.h>
21 : : #include <log/logger_name.h>
22 : : #include <log/logger_support.h>
23 : : #include <log/log_messages.h>
24 : : #include <log/macros.h>
25 : : #include <log/message_dictionary.h>
26 : : #include <log/message_exception.h>
27 : : #include <log/message_initializer.h>
28 : : #include <log/message_initializer.h>
29 : : #include <log/message_reader.h>
30 : : #include <log/message_types.h>
31 : :
32 : : using namespace std;
33 : :
34 : : namespace {
35 : :
36 : : // Logger used for logging messages within the logging code itself.
37 : 141 : isc::log::Logger logger("log");
38 : :
39 : : // Static stores for the initialization severity and debug level.
40 : : // These are put in methods to avoid a "static initialization fiasco".
41 : :
42 : : isc::log::Severity& initSeverity() {
43 : : static isc::log::Severity severity = isc::log::INFO;
44 : : return (severity);
45 : : }
46 : :
47 : : int& initDebugLevel() {
48 : : static int dbglevel = 0;
49 : : return (dbglevel);
50 : : }
51 : :
52 : 150 : std::string& initRootName() {
53 [ + + ][ + - ]: 150 : static std::string root("bind10");
[ + - ]
54 : 150 : return (root);
55 : : }
56 : :
57 : : } // Anonymous namespace
58 : :
59 : :
60 : : namespace isc {
61 : : namespace log {
62 : :
63 : : // Constructor - create the implementation class.
64 : 198 : LoggerManager::LoggerManager() {
65 : 198 : impl_ = new LoggerManagerImpl();
66 : 198 : }
67 : :
68 : : // Destructor - get rid of the implementation class
69 : 198 : LoggerManager::~LoggerManager() {
70 : 198 : delete impl_;
71 : 198 : }
72 : :
73 : : // Initialize processing
74 : : void
75 : 200 : LoggerManager::processInit() {
76 : 200 : impl_->processInit();
77 : 200 : }
78 : :
79 : : // Process logging specification
80 : : void
81 : 62 : LoggerManager::processSpecification(const LoggerSpecification& spec) {
82 : 62 : impl_->processSpecification(spec);
83 : 62 : }
84 : :
85 : : // End Processing
86 : : void
87 : 200 : LoggerManager::processEnd() {
88 : : impl_->processEnd();
89 : 200 : }
90 : :
91 : :
92 : : /// Logging system initialization
93 : :
94 : : void
95 : 120 : LoggerManager::init(const std::string& root, isc::log::Severity severity,
96 : : int dbglevel, const char* file)
97 : : {
98 : : // Load in the messages declared in the program and registered by
99 : : // statically-declared MessageInitializer objects.
100 : 120 : MessageInitializer::loadDictionary();
101 : :
102 : : // Save name, severity and debug level for later. No need to save the
103 : : // file name as once the local message file is read the messages will
104 : : // not be lost.
105 : 120 : initRootName() = root;
106 : 120 : initSeverity() = severity;
107 : 120 : initDebugLevel() = dbglevel;
108 : :
109 : : // Create the BIND 10 root logger and set the default severity and
110 : : // debug level. This is the logger that has the name of the application.
111 : : // All other loggers created in this application will be its children.
112 : 120 : setRootLoggerName(root);
113 : :
114 : : // Initialize the implementation logging. After this point, some basic
115 : : // logging has been set up and messages can be logged.
116 : 120 : LoggerManagerImpl::init(severity, dbglevel);
117 : 120 : setLoggingInitialized();
118 : :
119 : : // Check if there were any duplicate message IDs in the default dictionary
120 : : // and if so, log them. Log using the logging facility logger.
121 : 120 : vector<string>& duplicates = MessageInitializer::getDuplicates();
122 [ + + ]: 120 : if (!duplicates.empty()) {
123 : :
124 : : // There are duplicates present. This will be listed in alphabetic
125 : : // order of message ID, so they need to be sorted. This list itself may
126 : : // contain duplicates; if so, the message ID is listed as many times as
127 : : // there are duplicates.
128 : 1 : sort(duplicates.begin(), duplicates.end());
129 [ + + ]: 2 : for (vector<string>::iterator i = duplicates.begin();
130 : 2 : i != duplicates.end(); ++i) {
131 [ + - ][ + - ]: 1 : LOG_WARN(logger, LOG_DUPLICATE_MESSAGE_ID).arg(*i);
132 : : }
133 : :
134 : : }
135 : :
136 : : // Replace any messages with local ones (if given)
137 [ + + ]: 120 : if (file) {
138 : 1 : readLocalMessageFile(file);
139 : : }
140 : 120 : }
141 : :
142 : :
143 : : // Read local message file
144 : : // TODO This should be done after the configuration has been read so that
145 : : // the file can be placed in the local configuration
146 : : void
147 : 3 : LoggerManager::readLocalMessageFile(const char* file) {
148 : :
149 : 3 : MessageDictionary& dictionary = MessageDictionary::globalDictionary();
150 : 3 : MessageReader reader(&dictionary);
151 : : try {
152 : :
153 [ + - ][ + - ]: 3 : logger.info(LOG_READING_LOCAL_FILE).arg(file);
[ + - ]
154 [ + - ][ + + ]: 3 : reader.readFile(file, MessageReader::REPLACE);
155 : :
156 : : // File successfully read. As each message in the file is supposed to
157 : : // replace one in the dictionary, any ID read that can't be located in
158 : : // the dictionary will not be used. To aid problem diagnosis, the
159 : : // unknown message IDs are listed.
160 : 1 : MessageReader::MessageIDCollection unknown = reader.getNotAdded();
161 [ + + ]: 2 : for (MessageReader::MessageIDCollection::const_iterator
162 : 3 : i = unknown.begin(); i != unknown.end(); ++i) {
163 : 1 : string message_id = boost::lexical_cast<string>(*i);
164 [ + - ][ + - ]: 1 : logger.warn(LOG_NO_SUCH_MESSAGE).arg(message_id);
[ + - ]
165 : : }
166 : : }
167 [ - + ]: 4 : catch (MessageException& e) {
168 : 2 : MessageID ident = e.id();
169 : 2 : vector<string> args = e.arguments();
170 : :
171 : : // Log the variable number of arguments. The actual message will be
172 : : // logged when the error_message variable is destroyed.
173 [ - + ][ - + ]: 4 : Formatter<isc::log::Logger> error_message = logger.error(ident);
174 [ + + ]: 6 : for (vector<string>::size_type i = 0; i < args.size(); ++i) {
175 [ - + ]: 4 : error_message = error_message.arg(args[i]);
176 : : }
177 : : }
178 : 3 : }
179 : :
180 : : // Reset logging to settings passed to init()
181 : : void
182 : 30 : LoggerManager::reset() {
183 : 30 : setRootLoggerName(initRootName());
184 : 30 : LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
185 : 30 : }
186 : :
187 : : } // namespace log
188 : 141 : } // namespace isc
|