/src/muduo/muduo/base/Logging.h
Line | Count | Source |
1 | | // Use of this source code is governed by a BSD-style license |
2 | | // that can be found in the License file. |
3 | | // |
4 | | // Author: Shuo Chen (chenshuo at chenshuo dot com) |
5 | | |
6 | | #ifndef MUDUO_BASE_LOGGING_H |
7 | | #define MUDUO_BASE_LOGGING_H |
8 | | |
9 | | #include "muduo/base/LogStream.h" |
10 | | #include "muduo/base/Timestamp.h" |
11 | | |
12 | | namespace muduo |
13 | | { |
14 | | |
15 | | class TimeZone; |
16 | | |
17 | | class Logger |
18 | | { |
19 | | public: |
20 | | enum LogLevel |
21 | | { |
22 | | TRACE, |
23 | | DEBUG, |
24 | | INFO, |
25 | | WARN, |
26 | | ERROR, |
27 | | FATAL, |
28 | | NUM_LOG_LEVELS, |
29 | | }; |
30 | | |
31 | | // compile time calculation of basename of source file |
32 | | class SourceFile |
33 | | { |
34 | | public: |
35 | | template<int N> |
36 | | SourceFile(const char (&arr)[N]) |
37 | 0 | : data_(arr), |
38 | 0 | size_(N-1) |
39 | 0 | { |
40 | 0 | const char* slash = strrchr(data_, '/'); // builtin function |
41 | 0 | if (slash) |
42 | 0 | { |
43 | 0 | data_ = slash + 1; |
44 | 0 | size_ -= static_cast<int>(data_ - arr); |
45 | 0 | } |
46 | 0 | } Unexecuted instantiation: muduo::Logger::SourceFile::SourceFile<35>(char const (&) [35]) Unexecuted instantiation: muduo::Logger::SourceFile::SourceFile<32>(char const (&) [32]) |
47 | | |
48 | | explicit SourceFile(const char* filename) |
49 | | : data_(filename) |
50 | 0 | { |
51 | 0 | const char* slash = strrchr(filename, '/'); |
52 | 0 | if (slash) |
53 | 0 | { |
54 | 0 | data_ = slash + 1; |
55 | 0 | } |
56 | 0 | size_ = static_cast<int>(strlen(data_)); |
57 | 0 | } |
58 | | |
59 | | const char* data_; |
60 | | int size_; |
61 | | }; |
62 | | |
63 | | Logger(SourceFile file, int line); |
64 | | Logger(SourceFile file, int line, LogLevel level); |
65 | | Logger(SourceFile file, int line, LogLevel level, const char* func); |
66 | | Logger(SourceFile file, int line, bool toAbort); |
67 | | ~Logger(); |
68 | | |
69 | 0 | LogStream& stream() { return impl_.stream_; } |
70 | | |
71 | | static LogLevel logLevel(); |
72 | | static void setLogLevel(LogLevel level); |
73 | | |
74 | | typedef void (*OutputFunc)(const char* msg, int len); |
75 | | typedef void (*FlushFunc)(); |
76 | | static void setOutput(OutputFunc); |
77 | | static void setFlush(FlushFunc); |
78 | | static void setTimeZone(const TimeZone& tz); |
79 | | |
80 | | private: |
81 | | |
82 | | class Impl |
83 | | { |
84 | | public: |
85 | | typedef Logger::LogLevel LogLevel; |
86 | | Impl(LogLevel level, int old_errno, const SourceFile& file, int line); |
87 | | void formatTime(); |
88 | | void finish(); |
89 | | |
90 | | Timestamp time_; |
91 | | LogStream stream_; |
92 | | LogLevel level_; |
93 | | int line_; |
94 | | SourceFile basename_; |
95 | | }; |
96 | | |
97 | | Impl impl_; |
98 | | |
99 | | }; |
100 | | |
101 | | extern Logger::LogLevel g_logLevel; |
102 | | |
103 | | inline Logger::LogLevel Logger::logLevel() |
104 | 0 | { |
105 | 0 | return g_logLevel; |
106 | 0 | } |
107 | | |
108 | | // |
109 | | // CAUTION: do not write: |
110 | | // |
111 | | // if (good) |
112 | | // LOG_INFO << "Good news"; |
113 | | // else |
114 | | // LOG_WARN << "Bad news"; |
115 | | // |
116 | | // this expends to |
117 | | // |
118 | | // if (good) |
119 | | // if (logging_INFO) |
120 | | // logInfoStream << "Good news"; |
121 | | // else |
122 | | // logWarnStream << "Bad news"; |
123 | | // |
124 | | #define LOG_TRACE if (muduo::Logger::logLevel() <= muduo::Logger::TRACE) \ |
125 | | muduo::Logger(__FILE__, __LINE__, muduo::Logger::TRACE, __func__).stream() |
126 | | #define LOG_DEBUG if (muduo::Logger::logLevel() <= muduo::Logger::DEBUG) \ |
127 | | muduo::Logger(__FILE__, __LINE__, muduo::Logger::DEBUG, __func__).stream() |
128 | | #define LOG_INFO if (muduo::Logger::logLevel() <= muduo::Logger::INFO) \ |
129 | | muduo::Logger(__FILE__, __LINE__).stream() |
130 | | #define LOG_WARN muduo::Logger(__FILE__, __LINE__, muduo::Logger::WARN).stream() |
131 | | #define LOG_ERROR muduo::Logger(__FILE__, __LINE__, muduo::Logger::ERROR).stream() |
132 | 0 | #define LOG_FATAL muduo::Logger(__FILE__, __LINE__, muduo::Logger::FATAL).stream() |
133 | 0 | #define LOG_SYSERR muduo::Logger(__FILE__, __LINE__, false).stream() |
134 | 0 | #define LOG_SYSFATAL muduo::Logger(__FILE__, __LINE__, true).stream() |
135 | | |
136 | | const char* strerror_tl(int savedErrno); |
137 | | |
138 | | // Taken from glog/logging.h |
139 | | // |
140 | | // Check that the input is non NULL. This very useful in constructor |
141 | | // initializer lists. |
142 | | |
143 | | #define CHECK_NOTNULL(val) \ |
144 | | ::muduo::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) |
145 | | |
146 | | // A small helper for CHECK_NOTNULL(). |
147 | | template <typename T> |
148 | | T* CheckNotNull(Logger::SourceFile file, int line, const char *names, T* ptr) |
149 | | { |
150 | | if (ptr == NULL) |
151 | | { |
152 | | Logger(file, line, Logger::FATAL).stream() << names; |
153 | | } |
154 | | return ptr; |
155 | | } |
156 | | |
157 | | } // namespace muduo |
158 | | |
159 | | #endif // MUDUO_BASE_LOGGING_H |