blob: 96e1bcb2d019bb0f470337e0c8570d9a152283df [file] [log] [blame]
Junxiao Shi7d054272016-08-04 17:00:41 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2016 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_UTIL_LOGGING_HPP
23#define NDN_UTIL_LOGGING_HPP
24
25#include "../common.hpp"
26
27#include <boost/log/sinks.hpp>
28#include <mutex>
29#include <unordered_map>
30
31namespace ndn {
32namespace util {
33
34enum class LogLevel;
35class Logger;
36
37/** \brief controls the logging facility
38 *
39 * \note Public static methods are thread safe.
40 * Non-public methods are not guaranteed to be thread safe.
41 */
42class Logging : noncopyable
43{
44public:
45 /** \brief register a new logger
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000046 * \note App should declare a new logger with \p NDN_LOG_INIT macro.
Junxiao Shi7d054272016-08-04 17:00:41 +000047 */
48 static void
49 addLogger(Logger& logger);
50
51 /** \brief set severity level
52 * \param moduleName logger name, or "*" for default level
53 * \param level minimum severity level
54 *
55 * Log messages are output only if its severity is greater than the set minimum severity level.
56 * Initial default severity level is \p LogLevel::NONE which enables FATAL only.
57 *
58 * Changing the default level overwrites individual settings.
59 */
60 static void
61 setLevel(const std::string& moduleName, LogLevel level);
62
63 /** \brief set severity levels with a config string
64 * \param config colon-separate key=value pairs
65 * \throw std::invalid_argument config string is malformed
66 *
67 * \code
68 * Logging::setSeverityLevels("*=INFO:Face=DEBUG:NfdController=WARN");
69 * \endcode
70 * is equivalent to
71 * \code
72 * Logging::setSeverityLevel("*", LogLevel::INFO);
73 * Logging::setSeverityLevel("Face", LogLevel::DEBUG);
74 * Logging::setSeverityLevel("NfdController", LogLevel::WARN);
75 * \endcode
76 */
77 static void
78 setLevel(const std::string& config);
79
80 /** \brief set log destination
81 * \param os a stream for log output
82 *
83 * Initial destination is \p std::clog .
84 */
85 static void
86 setDestination(shared_ptr<std::ostream> os);
87
88 /** \brief set log destination
89 * \param os a stream for log output; caller must ensure this is valid
90 * until setDestination is invoked again or program exits
91 *
92 * This is equivalent to setDestination(shared_ptr<std::ostream>(&os, nullDeleter))
93 */
94 static void
95 setDestination(std::ostream& os);
96
97 /** \brief flush log backend
98 *
99 * This ensures log messages are written to the destination stream.
100 */
101 static void
102 flush();
103
104private:
105 Logging();
106
107 void
108 addLoggerImpl(Logger& logger);
109
110 void
111 setLevelImpl(const std::string& moduleName, LogLevel level);
112
113 void
114 setDefaultLevel(LogLevel level);
115
116 void
117 setLevelImpl(const std::string& config);
118
119 void
120 setDestinationImpl(shared_ptr<std::ostream> os);
121
122 void
123 flushImpl();
124
125NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
126 static Logging&
127 get();
128
129#ifdef NDN_CXX_HAVE_TESTS
130 bool
131 removeLogger(Logger& logger);
132
133 std::string
134 getLevels() const;
135
136 void
137 resetLevels();
138
139 shared_ptr<std::ostream>
140 getDestination();
141#endif // NDN_CXX_HAVE_TESTS
142
143private:
144 std::mutex m_mutex;
145 std::unordered_map<std::string, LogLevel> m_enabledLevel; ///< moduleName => minimum level
146 std::unordered_multimap<std::string, Logger*> m_loggers; ///< moduleName => logger
147
148 shared_ptr<std::ostream> m_destination;
149 typedef boost::log::sinks::asynchronous_sink<boost::log::sinks::text_ostream_backend> Sink;
150 boost::shared_ptr<Sink> m_sink;
151};
152
153inline void
154Logging::addLogger(Logger& logger)
155{
156 get().addLoggerImpl(logger);
157}
158
159inline void
160Logging::setLevel(const std::string& moduleName, LogLevel level)
161{
162 get().setLevelImpl(moduleName, level);
163}
164
165inline void
166Logging::setLevel(const std::string& config)
167{
168 get().setLevelImpl(config);
169}
170
171inline void
172Logging::setDestination(shared_ptr<std::ostream> os)
173{
174 get().setDestinationImpl(os);
175}
176
177inline void
178Logging::flush()
179{
180 get().flushImpl();
181}
182
183
184} // namespace util
185} // namespace ndn
186
187#endif // NDN_UTIL_LOGGING_HPP