blob: c1d2157cf3e60a0ac792c4fb01ed9fad93440a6d [file] [log] [blame]
Alexander Afanasyev216df012015-02-10 17:35:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyeva8d404b2016-11-05 10:07:08 -06003 * Copyright (c) 2014-2016, 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 Afanasyev216df012015-02-10 17:35:46 -080010 *
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 Afanasyeva8d404b2016-11-05 10:07:08 -060024 */
Alexander Afanasyev216df012015-02-10 17:35:46 -080025
26#include "custom-logger-factory.hpp"
27
28namespace nfd {
29
30NFD_LOG_INIT("LoggerFactory");
31
32LoggerFactory&
33LoggerFactory::getInstance()
34{
35 static LoggerFactory globalLoggerFactory;
36
37 return globalLoggerFactory;
38}
39
40LoggerFactory::LoggerFactory()
41 : m_defaultLevel(LOG_INFO)
42{
43 m_levelNames["NONE"] = LOG_NONE;
44 m_levelNames["ERROR"] = LOG_ERROR;
45 m_levelNames["WARN"] = LOG_WARN;
46 m_levelNames["INFO"] = LOG_INFO;
47 m_levelNames["DEBUG"] = LOG_DEBUG;
48 m_levelNames["TRACE"] = LOG_TRACE;
49 m_levelNames["ALL"] = LOG_ALL;
50}
51
52void
53LoggerFactory::setConfigFile(ConfigFile& config)
54{
55 config.addSectionHandler("log", bind(&LoggerFactory::onConfig, this, _1, _2, _3));
56}
57
58LogLevel
59LoggerFactory::parseLevel(const std::string& level)
60{
61 std::string upperLevel = level;
62 boost::to_upper(upperLevel);
63
64 // std::cerr << "parsing level: " << upperLevel << std::endl;;
65 // std::cerr << "# levels: " << m_levelNames.size() << std::endl;
66 // std::cerr << m_levelNames.begin()->first << std::endl;
67
68 LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
69 if (levelIt != m_levelNames.end())
70 {
71 return levelIt->second;
72 }
73 try
74 {
75 uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
76
77 if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
78 levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
79 levelNo == LOG_ALL)
80 {
81 return static_cast<LogLevel>(levelNo);
82 }
83 }
84 catch (const boost::bad_lexical_cast& error)
85 {
86 }
87 throw LoggerFactory::Error("Unsupported logging level \"" +
88 level + "\"");
89}
90
91LogLevel
92LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
93{
94 std::string levelString;
95 try
96 {
97 levelString = item.get_value<std::string>();
98 }
99 catch (const boost::property_tree::ptree_error& error)
100 {
101 }
102
103 if (levelString.empty())
104 {
105 throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
106 }
107
108 return parseLevel(levelString);
109}
110
111void
112LoggerFactory::onConfig(const ConfigSection& section,
113 bool isDryRun,
114 const std::string& filename)
115{
116// log
117// {
118// ; default_level specifies the logging level for modules
119// ; that are not explicitly named. All debugging levels
120// ; listed above the selected value are enabled.
121//
122// default_level INFO
123//
124// ; You may also override the default for specific modules:
125//
126// FibManager DEBUG
127// Forwarder WARN
128// }
129
130 if (!isDryRun)
131 {
132 ConfigSection::const_assoc_iterator item = section.find("default_level");
133 if (item != section.not_found())
134 {
135 LogLevel level = extractLevel(item->second, "default_level");
136 setDefaultLevel(level);
137 }
138 else
139 {
140 setDefaultLevel(LOG_INFO);
141 }
142 }
143
144 for (ConfigSection::const_iterator item = section.begin();
145 item != section.end();
146 ++item)
147 {
148 LogLevel level = extractLevel(item->second, item->first);
149
150 if (item->first == "default_level")
151 {
152 // do nothing
153 }
154 else
155 {
156 LoggerMap::iterator loggerIt = m_loggers.find(item->first);
157 if (loggerIt == m_loggers.end())
158 {
159 NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
160 item->first << "\" (module not found)");
161 }
162 else if (!isDryRun)
163 {
164 // std::cerr << "changing level for module " << item->first << " to " << level << std::endl;
165 loggerIt->second.setLogLevel(level);
166 }
167 }
168 }
169}
170
171void
172LoggerFactory::setDefaultLevel(LogLevel level)
173{
174 // std::cerr << "changing to default_level " << level << std::endl;
175
176 m_defaultLevel = level;
177 for (LoggerMap::iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
178 {
179 // std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
180 i->second.setLogLevel(m_defaultLevel);
181 }
182}
183
184Logger&
185LoggerFactory::create(const std::string& moduleName)
186{
187 return LoggerFactory::getInstance().createLogger(moduleName);
188}
189
190Logger&
191LoggerFactory::createLogger(const std::string& moduleName)
192{
193 // std::cerr << "creating logger for " << moduleName
194 // << " with level " << m_defaultLevel << std::endl;
195
196 std::pair<LoggerMap::iterator, bool> loggerIt =
197 m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
198
199 return loggerIt.first->second;
200}
201
202std::list<std::string>
203LoggerFactory::getModules() const
204{
205 std::list<std::string> modules;
206 for (LoggerMap::const_iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
207 {
208 modules.push_back(i->first);
209 }
210
211 return modules;
212}
213
214} // namespace nfd