blob: 483387ff556d8d02e29e0fe5d26261c8b7a0de8b [file] [log] [blame]
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev8269a052015-02-09 16:25:36 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev8269a052015-02-09 16:25:36 -080024 */
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060025
26#include "logger-factory.hpp"
27
Alexander Afanasyev8269a052015-02-09 16:25:36 -080028#ifdef HAVE_CUSTOM_LOGGER
29#error "This file should not be compiled when custom logger is used"
30#endif
31
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060032namespace nfd {
33
Steve DiBenedetto6ad48ca2014-04-22 09:39:31 -060034NFD_LOG_INIT("LoggerFactory");
35
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060036LoggerFactory&
37LoggerFactory::getInstance()
38{
39 static LoggerFactory globalLoggerFactory;
40
41 return globalLoggerFactory;
42}
43
44LoggerFactory::LoggerFactory()
45 : m_defaultLevel(LOG_INFO)
46{
47 m_levelNames["NONE"] = LOG_NONE;
48 m_levelNames["ERROR"] = LOG_ERROR;
49 m_levelNames["WARN"] = LOG_WARN;
50 m_levelNames["INFO"] = LOG_INFO;
51 m_levelNames["DEBUG"] = LOG_DEBUG;
52 m_levelNames["TRACE"] = LOG_TRACE;
53 m_levelNames["ALL"] = LOG_ALL;
54}
55
56void
57LoggerFactory::setConfigFile(ConfigFile& config)
58{
59 config.addSectionHandler("log", bind(&LoggerFactory::onConfig, this, _1, _2, _3));
60}
61
62LogLevel
63LoggerFactory::parseLevel(const std::string& level)
64{
65 std::string upperLevel = level;
66 boost::to_upper(upperLevel);
67
68 // std::cerr << "parsing level: " << upperLevel << std::endl;;
69 // std::cerr << "# levels: " << m_levelNames.size() << std::endl;
70 // std::cerr << m_levelNames.begin()->first << std::endl;
71
72 LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
73 if (levelIt != m_levelNames.end())
74 {
75 return levelIt->second;
76 }
77 try
78 {
79 uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
80
Alexander Afanasyevf4e89b42014-05-31 15:54:18 +030081 if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
82 levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060083 levelNo == LOG_ALL)
84 {
85 return static_cast<LogLevel>(levelNo);
86 }
87 }
88 catch (const boost::bad_lexical_cast& error)
89 {
90 }
91 throw LoggerFactory::Error("Unsupported logging level \"" +
92 level + "\"");
93}
94
Alexander Afanasyev5959b012014-06-02 19:18:12 +030095LogLevel
96LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
97{
98 std::string levelString;
99 try
100 {
101 levelString = item.get_value<std::string>();
102 }
103 catch (const boost::property_tree::ptree_error& error)
104 {
105 }
106
107 if (levelString.empty())
108 {
109 throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
110 }
111
112 return parseLevel(levelString);
113}
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600114
115void
116LoggerFactory::onConfig(const ConfigSection& section,
117 bool isDryRun,
118 const std::string& filename)
119{
120// log
121// {
122// ; default_level specifies the logging level for modules
123// ; that are not explicitly named. All debugging levels
124// ; listed above the selected value are enabled.
125//
126// default_level INFO
127//
128// ; You may also override the default for specific modules:
129//
130// FibManager DEBUG
131// Forwarder WARN
132// }
133
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300134 if (!isDryRun)
135 {
136 ConfigSection::const_assoc_iterator item = section.find("default_level");
137 if (item != section.not_found())
138 {
139 LogLevel level = extractLevel(item->second, "default_level");
140 setDefaultLevel(level);
141 }
142 else
143 {
144 setDefaultLevel(LOG_INFO);
145 }
146 }
147
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600148 for (ConfigSection::const_iterator item = section.begin();
149 item != section.end();
150 ++item)
151 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300152 LogLevel level = extractLevel(item->second, item->first);
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600153
154 if (item->first == "default_level")
155 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300156 // do nothing
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600157 }
158 else
159 {
160 LoggerMap::iterator loggerIt = m_loggers.find(item->first);
161 if (loggerIt == m_loggers.end())
162 {
Steve DiBenedetto6ad48ca2014-04-22 09:39:31 -0600163 NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
164 item->first << "\" (module not found)");
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600165 }
Steve DiBenedetto2e948b12014-05-03 21:02:47 -0600166 else if (!isDryRun)
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600167 {
168 // std::cerr << "changing level for module " << item->first << " to " << level << std::endl;
169 loggerIt->second.setLogLevel(level);
170 }
171 }
172 }
173}
174
175void
176LoggerFactory::setDefaultLevel(LogLevel level)
177{
178 // std::cerr << "changing to default_level " << level << std::endl;
179
180 m_defaultLevel = level;
181 for (LoggerMap::iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
182 {
183 // std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
184 i->second.setLogLevel(m_defaultLevel);
185 }
186}
187
188Logger&
189LoggerFactory::create(const std::string& moduleName)
190{
191 return LoggerFactory::getInstance().createLogger(moduleName);
192}
193
194Logger&
195LoggerFactory::createLogger(const std::string& moduleName)
196{
197 // std::cerr << "creating logger for " << moduleName
198 // << " with level " << m_defaultLevel << std::endl;
199
200 std::pair<LoggerMap::iterator, bool> loggerIt =
201 m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
202
203 return loggerIt.first->second;
204}
205
206std::list<std::string>
207LoggerFactory::getModules() const
208{
209 std::list<std::string> modules;
210 for (LoggerMap::const_iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
211 {
212 modules.push_back(i->first);
213 }
214
215 return modules;
216}
217
218} // namespace nfd