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