blob: 45dbe0767b86deed984da8292b0c403f18975873 [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
Alexander Afanasyeved1e99d2016-11-05 09:59:35 -060027#ifdef HAVE_NDN_CXX_CUSTOM_LOGGER
28#include "ndn-cxx-custom-logging.hpp"
29#else
30
Junxiao Shi7d054272016-08-04 17:00:41 +000031#include <boost/log/sinks.hpp>
32#include <mutex>
33#include <unordered_map>
34
35namespace ndn {
36namespace util {
37
38enum class LogLevel;
39class Logger;
40
41/** \brief controls the logging facility
42 *
43 * \note Public static methods are thread safe.
44 * Non-public methods are not guaranteed to be thread safe.
45 */
46class Logging : noncopyable
47{
48public:
49 /** \brief register a new logger
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000050 * \note App should declare a new logger with \p NDN_LOG_INIT macro.
Junxiao Shi7d054272016-08-04 17:00:41 +000051 */
52 static void
53 addLogger(Logger& logger);
54
55 /** \brief set severity level
56 * \param moduleName logger name, or "*" for default level
57 * \param level minimum severity level
58 *
59 * Log messages are output only if its severity is greater than the set minimum severity level.
60 * Initial default severity level is \p LogLevel::NONE which enables FATAL only.
61 *
62 * Changing the default level overwrites individual settings.
63 */
64 static void
65 setLevel(const std::string& moduleName, LogLevel level);
66
67 /** \brief set severity levels with a config string
68 * \param config colon-separate key=value pairs
69 * \throw std::invalid_argument config string is malformed
70 *
71 * \code
72 * Logging::setSeverityLevels("*=INFO:Face=DEBUG:NfdController=WARN");
73 * \endcode
74 * is equivalent to
75 * \code
76 * Logging::setSeverityLevel("*", LogLevel::INFO);
77 * Logging::setSeverityLevel("Face", LogLevel::DEBUG);
78 * Logging::setSeverityLevel("NfdController", LogLevel::WARN);
79 * \endcode
80 */
81 static void
82 setLevel(const std::string& config);
83
84 /** \brief set log destination
85 * \param os a stream for log output
86 *
87 * Initial destination is \p std::clog .
88 */
89 static void
90 setDestination(shared_ptr<std::ostream> os);
91
92 /** \brief set log destination
93 * \param os a stream for log output; caller must ensure this is valid
94 * until setDestination is invoked again or program exits
95 *
96 * This is equivalent to setDestination(shared_ptr<std::ostream>(&os, nullDeleter))
97 */
98 static void
99 setDestination(std::ostream& os);
100
101 /** \brief flush log backend
102 *
103 * This ensures log messages are written to the destination stream.
104 */
105 static void
106 flush();
107
108private:
109 Logging();
110
111 void
112 addLoggerImpl(Logger& logger);
113
114 void
115 setLevelImpl(const std::string& moduleName, LogLevel level);
116
117 void
118 setDefaultLevel(LogLevel level);
119
120 void
121 setLevelImpl(const std::string& config);
122
123 void
124 setDestinationImpl(shared_ptr<std::ostream> os);
125
126 void
127 flushImpl();
128
129NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
130 static Logging&
131 get();
132
133#ifdef NDN_CXX_HAVE_TESTS
134 bool
135 removeLogger(Logger& logger);
136
137 std::string
138 getLevels() const;
139
140 void
141 resetLevels();
142
143 shared_ptr<std::ostream>
144 getDestination();
145#endif // NDN_CXX_HAVE_TESTS
146
147private:
148 std::mutex m_mutex;
149 std::unordered_map<std::string, LogLevel> m_enabledLevel; ///< moduleName => minimum level
150 std::unordered_multimap<std::string, Logger*> m_loggers; ///< moduleName => logger
151
152 shared_ptr<std::ostream> m_destination;
153 typedef boost::log::sinks::asynchronous_sink<boost::log::sinks::text_ostream_backend> Sink;
154 boost::shared_ptr<Sink> m_sink;
155};
156
157inline void
158Logging::addLogger(Logger& logger)
159{
160 get().addLoggerImpl(logger);
161}
162
163inline void
164Logging::setLevel(const std::string& moduleName, LogLevel level)
165{
166 get().setLevelImpl(moduleName, level);
167}
168
169inline void
170Logging::setLevel(const std::string& config)
171{
172 get().setLevelImpl(config);
173}
174
175inline void
176Logging::setDestination(shared_ptr<std::ostream> os)
177{
178 get().setDestinationImpl(os);
179}
180
181inline void
182Logging::flush()
183{
184 get().flushImpl();
185}
186
187
188} // namespace util
189} // namespace ndn
190
Alexander Afanasyeved1e99d2016-11-05 09:59:35 -0600191#endif // HAVE_NDN_CXX_CUSTOM_LOGGER
192
Junxiao Shi7d054272016-08-04 17:00:41 +0000193#endif // NDN_UTIL_LOGGING_HPP