blob: 0b545e0a845747a457db176307dbb16cbbcb2e23 [file] [log] [blame]
Ilya Moiseenkoa807e652014-01-28 11:51:01 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 *
6 * Author: Ilya Moiseenko <iliamo@ucla.edu>
7 */
8
9#ifndef NFD_CORE_LOGGER_HPP
10#define NFD_CORE_LOGGER_HPP
11
12#include "common.hpp"
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -060013#include <ndn-cpp-dev/util/time.hpp>
14
15/// \todo use when we enable C++11 (see todo in now())
16// #include <cinttypes>
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080017
18namespace nfd {
19
20enum LogLevel {
21 LOG_NONE = 0, // no messages
22 LOG_ERROR = 1, // serious error messages
23 LOG_WARN = 2, // warning messages
Alexander Afanasyevb84cc922014-02-24 17:52:58 -080024 LOG_INFO = 3, // informational messages
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080025 LOG_DEBUG = 4, // debug messages
Alexander Afanasyevb84cc922014-02-24 17:52:58 -080026 LOG_TRACE = 5, // trace messages (most verbose)
27 // LOG_FATAL is not a level and is logged unconditionally
28 LOG_ALL = 255, // all messages
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080029};
30
31class Logger
32{
33public:
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060034
35 Logger(const std::string& name, LogLevel level)
36 : m_moduleName(name)
37 , m_enabledLogLevel(level)
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080038 {
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060039 }
40
41 bool
42 isEnabled(LogLevel level) const
43 {
44 // std::cerr << m_moduleName <<
45 // " enabled = " << m_enabledLogLevel
46 // << " level = " << level << std::endl;
Alexander Afanasyevb84cc922014-02-24 17:52:58 -080047 return (m_enabledLogLevel >= level);
48 }
49
50 void
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060051 setLogLevel(LogLevel level)
Alexander Afanasyevb84cc922014-02-24 17:52:58 -080052 {
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060053 m_enabledLogLevel = level;
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080054 }
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060055
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080056 const std::string&
57 getName() const
58 {
59 return m_moduleName;
60 }
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060061
62 void
63 setName(const std::string& name)
64 {
65 m_moduleName = name;
66 }
67
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -060068
69 /// \brief return a string representation of time since epoch: seconds.microseconds
70 static std::string
71 now()
72 {
73 using namespace ndn::time;
74
75 static const microseconds::rep ONE_SECOND = 1000000;
76
77 // 10 (whole seconds) + '.' + 6 (fraction) + 1 (\0)
78 char buffer[10 + 1 + 6 + 1];
79
80 microseconds::rep microseconds_since_epoch =
81 duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
82
83 ::snprintf(buffer, sizeof(buffer), "%lld.%06lld",
84 static_cast<long long int>(microseconds_since_epoch / ONE_SECOND),
85 static_cast<long long int>(microseconds_since_epoch % ONE_SECOND));
86
87 /// \todo use this version when we enable C++11 to avoid casting
88 // ::snprintf(buffer, sizeof(buffer), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
89 // microseconds_since_epoch / ONE_SECOND,
90 // microseconds_since_epoch % ONE_SECOND);
91
92 return std::string(buffer);
93 }
94
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080095private:
96 std::string m_moduleName;
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060097 LogLevel m_enabledLogLevel;
Ilya Moiseenkoa807e652014-01-28 11:51:01 -080098};
99
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600100inline std::ostream&
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600101operator<<(std::ostream& output, const Logger& logger)
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600102{
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600103 output << logger.getName();
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600104 return output;
105}
106
107} // namespace nfd
108
109#include "core/logger-factory.hpp"
110
111namespace nfd {
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800112
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600113#define NFD_LOG_INIT(name) \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600114static nfd::Logger& g_logger = nfd::LoggerFactory::create(name);
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800115
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600116#define NFD_LOG_INCLASS_DECLARE() \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600117static nfd::Logger& g_logger;
Alexander Afanasyev66886812014-01-31 14:48:48 -0800118
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600119#define NFD_LOG_INCLASS_DEFINE(cls, name) \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600120nfd::Logger& cls::g_logger = nfd::LoggerFactory::create(name);
Alexander Afanasyev66886812014-01-31 14:48:48 -0800121
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600122#define NFD_LOG_INCLASS_TEMPLATE_DEFINE(cls, name) \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600123template<class T> \
124nfd::Logger& cls<T>::g_logger = nfd::LoggerFactory::create(name);
Alexander Afanasyev66886812014-01-31 14:48:48 -0800125
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600126#define NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(cls, specialization, name) \
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600127template<> \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600128nfd::Logger& cls<specialization>::g_logger = nfd::LoggerFactory::create(name);
Alexander Afanasyev66886812014-01-31 14:48:48 -0800129
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800130#define NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(cls, s1, s2, name) \
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600131template<> \
132nfd::Logger& cls<s1, s2>::g_logger = nfd::LoggerFactory::create(name);
133
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800134
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600135#define NFD_LOG(level, expression) \
136do { \
137 if (g_logger.isEnabled(::nfd::LOG_##level)) \
Steve DiBenedetto4d43a452014-04-06 18:55:29 -0600138 std::clog << ::nfd::Logger::now() << " "#level": " \
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600139 << "[" << g_logger << "] " << expression << "\n"; \
140} while (false)
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800141
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600142#define NFD_LOG_TRACE(expression) NFD_LOG(TRACE, expression)
143#define NFD_LOG_DEBUG(expression) NFD_LOG(DEBUG, expression)
144#define NFD_LOG_INFO(expression) NFD_LOG(INFO, expression)
145#define NFD_LOG_ERROR(expression) NFD_LOG(ERROR, expression)
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800146
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600147// specialize WARN because the message is "WARNING" instead of "WARN"
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600148#define NFD_LOG_WARN(expression) \
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600149do { \
150 if (g_logger.isEnabled(::nfd::LOG_WARN)) \
Steve DiBenedetto4d43a452014-04-06 18:55:29 -0600151 std::clog << ::nfd::Logger::now() << " WARNING: " \
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600152 << "[" << g_logger << "] " << expression << "\n"; \
153} while (false)
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800154
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600155#define NFD_LOG_FATAL(expression) \
156do { \
Steve DiBenedetto4d43a452014-04-06 18:55:29 -0600157 std::clog << ::nfd::Logger::now() << " FATAL: " \
Steve DiBenedetto3a61fb42014-04-04 10:32:51 -0600158 << "[" << g_logger << "] " << expression << "\n"; \
159} while (false)
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -0600160
161} //namespace nfd
Ilya Moiseenkoa807e652014-01-28 11:51:01 -0800162
163#endif