25 #include <boost/log/expressions.hpp> 26 #include <boost/range/adaptor/map.hpp> 27 #include <boost/range/algorithm/copy.hpp> 28 #include <boost/range/iterator_range.hpp> 36 #pragma clang diagnostic ignored "-Wundefined-func-template" 55 this->setDestinationImpl(shared_ptr<std::ostream>(&std::clog, [] (
auto) {}));
57 const char* environ = std::getenv(
"NDN_LOG");
58 if (environ !=
nullptr) {
59 this->setLevelImpl(environ);
64 Logging::addLoggerImpl(
Logger& logger)
66 std::lock_guard<std::mutex> lock(m_mutex);
69 m_loggers.emplace(moduleName, &logger);
71 logger.
setLevel(findLevel(moduleName));
75 Logging::registerLoggerNameImpl(std::string name)
77 std::lock_guard<std::mutex> lock(m_mutex);
78 m_loggers.emplace(
std::move(name),
nullptr);
82 Logging::getLoggerNamesImpl()
const 84 std::lock_guard<std::mutex> lock(m_mutex);
86 std::set<std::string> loggerNames;
87 boost::copy(m_loggers | boost::adaptors::map_keys, std::inserter(loggerNames, loggerNames.end()));
92 Logging::findLevel(std::string mn)
const 95 auto it = m_enabledLevel.find(mn);
96 if (it != m_enabledLevel.end()) {
99 size_t pos = mn.find_last_of(
'.');
100 if (pos < mn.size() - 1) {
101 mn = mn.substr(0, pos + 1);
103 else if (pos == mn.size() - 1) {
105 pos = mn.find_last_of(
'.');
106 if (pos != std::string::npos) {
107 mn = mn.substr(0, pos + 1);
118 auto it = m_enabledLevel.find(mn);
122 #ifdef NDN_CXX_HAVE_TESTS 124 Logging::removeLogger(
Logger& logger)
127 auto range = m_loggers.equal_range(moduleName);
128 for (
auto i = range.first; i != range.second; ++i) {
129 if (i->second == &logger) {
136 #endif // NDN_CXX_HAVE_TESTS 139 Logging::setLevelImpl(
const std::string& prefix,
LogLevel level)
141 std::lock_guard<std::mutex> lock(m_mutex);
143 if (prefix.empty() || prefix.back() ==
'*') {
144 std::string p = prefix;
149 for (
auto i = m_enabledLevel.begin(); i != m_enabledLevel.end();) {
150 if (i->first.compare(0, p.size(), p) == 0) {
151 i = m_enabledLevel.erase(i);
157 m_enabledLevel[p] = level;
159 for (
const auto& pair : m_loggers) {
160 if (pair.first.compare(0, p.size(), p) == 0 && pair.second !=
nullptr) {
161 pair.second->setLevel(level);
166 m_enabledLevel[prefix] = level;
167 auto range = boost::make_iterator_range(m_loggers.equal_range(prefix));
168 for (
const auto& pair : range) {
169 if (pair.second !=
nullptr) {
170 pair.second->setLevel(level);
177 Logging::setLevelImpl(
const std::string& config)
179 std::stringstream ss(config);
180 std::string configModule;
181 while (std::getline(ss, configModule,
':')) {
182 size_t ind = configModule.find(
'=');
183 if (ind == std::string::npos) {
184 NDN_THROW(std::invalid_argument(
"malformed logging config: '=' is missing"));
187 std::string moduleName = configModule.substr(0, ind);
189 this->setLevelImpl(moduleName, level);
193 #ifdef NDN_CXX_HAVE_TESTS 195 Logging::resetLevels()
197 this->setLevelImpl(
"*", INITIAL_DEFAULT_LEVEL);
198 m_enabledLevel.clear();
200 #endif // NDN_CXX_HAVE_TESTS 209 Logging::setDestinationImpl(shared_ptr<std::ostream> os)
211 std::lock_guard<std::mutex> lock(m_mutex);
215 auto backend = boost::make_shared<boost::log::sinks::text_ostream_backend>();
216 backend->auto_flush(
true);
217 backend->add_stream(boost::shared_ptr<std::ostream>(m_destination.get(), [] (
auto) {}));
219 if (m_sink !=
nullptr) {
225 m_sink = boost::make_shared<Sink>(backend);
226 m_sink->set_formatter(boost::log::expressions::stream << boost::log::expressions::message);
230 #ifdef NDN_CXX_HAVE_TESTS 231 shared_ptr<std::ostream>
232 Logging::getDestination()
const 234 return m_destination;
238 Logging::setLevelImpl(
const std::unordered_map<std::string, LogLevel>& prefixRules)
241 for (
const auto& rule : prefixRules) {
242 setLevelImpl(rule.first, rule.second);
246 const std::unordered_map<std::string, LogLevel>&
247 Logging::getLevels()
const 249 return m_enabledLevel;
251 #endif // NDN_CXX_HAVE_TESTS Controls the logging facility.
static void setDestination(shared_ptr< std::ostream > os)
Set log destination.
LogLevel
Indicates the severity level of a log message.
R & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &v, nonstd::in_place_t(&)(nonstd::detail::in_place_type_tag< R >)=nonstd::in_place_type< R >)
LogLevel parseLogLevel(const std::string &s)
Parse LogLevel from a string.
static const LogLevel INITIAL_DEFAULT_LEVEL
Represents a log module in the logging facility.
const std::string & getModuleName() const
void setLevel(LogLevel level)