blob: 436bdf1c5ce7eb4450bc7a52127e9527e5db51b9 [file] [log] [blame]
Alexander Afanasyev216df012015-02-10 17:35:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -05003 * Copyright (c) 2014-2017, Regents of the University of California,
Alexander Afanasyeva8d404b2016-11-05 10:07:08 -06004 * 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
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050028#include <boost/algorithm/string/case_conv.hpp>
29
Alexander Afanasyev216df012015-02-10 17:35:46 -080030namespace nfd {
31
32NFD_LOG_INIT("LoggerFactory");
33
34LoggerFactory&
35LoggerFactory::getInstance()
36{
37 static LoggerFactory globalLoggerFactory;
38
39 return globalLoggerFactory;
40}
41
42LoggerFactory::LoggerFactory()
43 : m_defaultLevel(LOG_INFO)
44{
45 m_levelNames["NONE"] = LOG_NONE;
46 m_levelNames["ERROR"] = LOG_ERROR;
47 m_levelNames["WARN"] = LOG_WARN;
48 m_levelNames["INFO"] = LOG_INFO;
49 m_levelNames["DEBUG"] = LOG_DEBUG;
50 m_levelNames["TRACE"] = LOG_TRACE;
51 m_levelNames["ALL"] = LOG_ALL;
52}
53
54void
55LoggerFactory::setConfigFile(ConfigFile& config)
56{
57 config.addSectionHandler("log", bind(&LoggerFactory::onConfig, this, _1, _2, _3));
58}
59
60LogLevel
61LoggerFactory::parseLevel(const std::string& level)
62{
63 std::string upperLevel = level;
64 boost::to_upper(upperLevel);
65
66 // std::cerr << "parsing level: " << upperLevel << std::endl;;
67 // std::cerr << "# levels: " << m_levelNames.size() << std::endl;
68 // std::cerr << m_levelNames.begin()->first << std::endl;
69
70 LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050071 if (levelIt != m_levelNames.end()) {
72 return levelIt->second;
73 }
74 try {
75 uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
Alexander Afanasyev216df012015-02-10 17:35:46 -080076
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050077 if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
78 levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
79 levelNo == LOG_ALL) {
80 return static_cast<LogLevel>(levelNo);
Alexander Afanasyev216df012015-02-10 17:35:46 -080081 }
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050082 }
83 catch (const boost::bad_lexical_cast& error) {
84 }
85 throw LoggerFactory::Error("Unsupported logging level \"" + level + "\"");
Alexander Afanasyev216df012015-02-10 17:35:46 -080086}
87
88LogLevel
89LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
90{
91 std::string levelString;
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050092 try {
93 levelString = item.get_value<std::string>();
94 }
95 catch (const boost::property_tree::ptree_error& error) {
96 }
Alexander Afanasyev216df012015-02-10 17:35:46 -080097
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -050098 if (levelString.empty()) {
99 throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
100 }
Alexander Afanasyev216df012015-02-10 17:35:46 -0800101
102 return parseLevel(levelString);
103}
104
105void
106LoggerFactory::onConfig(const ConfigSection& section,
107 bool isDryRun,
108 const std::string& filename)
109{
110// log
111// {
112// ; default_level specifies the logging level for modules
113// ; that are not explicitly named. All debugging levels
114// ; listed above the selected value are enabled.
115//
116// default_level INFO
117//
118// ; You may also override the default for specific modules:
119//
120// FibManager DEBUG
121// Forwarder WARN
122// }
123
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500124 if (!isDryRun) {
125 ConfigSection::const_assoc_iterator item = section.find("default_level");
126 if (item != section.not_found()) {
127 LogLevel level = extractLevel(item->second, "default_level");
128 setDefaultLevel(level);
Alexander Afanasyev216df012015-02-10 17:35:46 -0800129 }
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500130 else {
131 setDefaultLevel(LOG_INFO);
132 }
133 }
Alexander Afanasyev216df012015-02-10 17:35:46 -0800134
135 for (ConfigSection::const_iterator item = section.begin();
136 item != section.end();
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500137 ++item) {
138 LogLevel level = extractLevel(item->second, item->first);
Alexander Afanasyev216df012015-02-10 17:35:46 -0800139
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500140 if (item->first == "default_level") {
141 // do nothing
Alexander Afanasyev216df012015-02-10 17:35:46 -0800142 }
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500143 else {
144 LoggerMap::iterator loggerIt = m_loggers.find(item->first);
145 if (loggerIt == m_loggers.end()) {
146 NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
147 item->first << "\" (module not found)");
148 }
149 else if (!isDryRun) {
150 // std::cerr << "changing level for module " << item->first << " to " << level << std::endl;
151 loggerIt->second.setLogLevel(level);
152 }
153 }
154 }
Alexander Afanasyev216df012015-02-10 17:35:46 -0800155}
156
157void
158LoggerFactory::setDefaultLevel(LogLevel level)
159{
160 // std::cerr << "changing to default_level " << level << std::endl;
161
162 m_defaultLevel = level;
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500163 for (LoggerMap::iterator i = m_loggers.begin(); i != m_loggers.end(); ++i) {
164 // std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
165 i->second.setLogLevel(m_defaultLevel);
166 }
Alexander Afanasyev216df012015-02-10 17:35:46 -0800167}
168
169Logger&
170LoggerFactory::create(const std::string& moduleName)
171{
172 return LoggerFactory::getInstance().createLogger(moduleName);
173}
174
175Logger&
176LoggerFactory::createLogger(const std::string& moduleName)
177{
178 // std::cerr << "creating logger for " << moduleName
179 // << " with level " << m_defaultLevel << std::endl;
180
181 std::pair<LoggerMap::iterator, bool> loggerIt =
182 m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
183
184 return loggerIt.first->second;
185}
186
187std::list<std::string>
188LoggerFactory::getModules() const
189{
190 std::list<std::string> modules;
Alexander Afanasyev79a0fff2017-12-05 12:45:14 -0500191 for (LoggerMap::const_iterator i = m_loggers.begin(); i != m_loggers.end(); ++i) {
192 modules.push_back(i->first);
193 }
Alexander Afanasyev216df012015-02-10 17:35:46 -0800194
195 return modules;
196}
197
198} // namespace nfd