• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License for more details.
11 
12 #ifndef ANDROID_BASE_LOG_H
13 #define ANDROID_BASE_LOG_H
14 
15 #include <errno.h>
16 #include <stdarg.h>
17 #include <stddef.h>
18 
19 namespace android {
20 namespace base {
21 
22 // The list of severity levels used for logging.
23 // Note that negative verbosity levels are used.
24 typedef int LogSeverity;
25 const LogSeverity LOG_VERBOSE = -1;
26 const LogSeverity LOG_INFO = 0;
27 const LogSeverity LOG_WARNING = 1;
28 const LogSeverity LOG_ERROR = 2;
29 const LogSeverity LOG_FATAL = 3;
30 const LogSeverity LOG_NUM_SEVERITIES = 4;
31 
32 // LOG_DFATAL will be LOG_ERROR in release builds, and LOG_FATAL in debug
33 // ones.
34 #ifdef NDEBUG
35 const LogSeverity LOG_DFATAL = LOG_ERROR;
36 #else
37 const LogSeverity LOG_DFATAL = LOG_FATAL;
38 #endif
39 
40 // Returns the minimal log level.
41 LogSeverity getMinLogLevel();
42 
43 // Helper macro used to test if logging for a given log level is
44 // currently enabled. |severity| must be a log level without the LOG_
45 // prefix, as in:
46 //
47 //  if (LOG_IS_ON(INFO)) {
48 //      ... do additionnal logging
49 //  }
50 //
51 #define LOG_IS_ON(severity) \
52   ((::android::base::LOG_ ## severity) >=  \
53         ::android::base::getMinLogLevel())
54 
55 // For performance reasons, it's important to avoid constructing a
56 // LogMessage instance every time a LOG() or CHECK() statement is
57 // encountered at runtime, i.e. these objects should only be constructed
58 // when absolutely necessary, which means:
59 //  - For LOG() statements, when the corresponding log level is enabled.
60 //  - For CHECK(), when the tested expression doesn't hold.
61 //
62 // At the same time, we really want to use expressions like:
63 //    LOG(severity) << some_stuff << some_more_stuff;
64 //
65 // This means LOG(severity) should expand to something that can take
66 // << operators on its right hand side. This is achieved with the
67 // ternary '? :', as implemented by this helper macro.
68 //
69 // Unfortunately, a simple thing like:
70 //
71 //   !(condition) ? (void)0 : (expr)
72 //
73 // will not work, because the compiler complains loudly with:
74 //
75 //   error: second operand to the conditional operator is of type 'void',
76 //   but the third operand is neither a throw-expression nor of type 'void'
77 #define LOG_LAZY_EVAL(condition, expr) \
78   !(condition) ? (void)0 : ::android::base::LogStreamVoidify() & (expr)
79 
80 // Send a message to the log if |severity| is higher or equal to the current
81 // logging severity level. This macro expands to an expression that acts as
82 // an input stream for strings, ints and floating point values, as well as
83 // LogString instances. Usage example:
84 //
85 //    LOG(INFO) << "Starting flux capacitor";
86 //    fluxCapacitor::start();
87 //    LOG(INFO) << "Flux capacitor started";
88 //
89 // Note that the macro implementation is optimized to avoid doing any work
90 // if the severity level is disabled.
91 //
92 // It's possible to do conditional logging with LOG_IF()
93 #define LOG(severity)  \
94         LOG_LAZY_EVAL(LOG_IS_ON(severity), \
95         LOG_MESSAGE_STREAM_COMPACT(severity))
96 
97 // A variant of LOG() that only performs logging if a specific condition
98 // is encountered. Note that |condition| is only evaluated if |severity|
99 // is high enough. Usage example:
100 //
101 //    LOG(INFO) << "Starting fuel injector";
102 //    fuelInjector::start();
103 //    LOG(INFO) << "Fuel injection started";
104 //    LOG_IF(INFO, fuelInjector::hasOptimalLevel())
105 //            << "Fuel injection at optimal level";
106 //
107 #define LOG_IF(severity, condition) \
108         LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \
109                       LOG_MESSAGE_STREAM_COMPACT(severity))
110 
111 
112 // A variant of LOG() that also appends the string message corresponding
113 // to the current value of 'errno' just before the macro is called. This
114 // also preserves the value of 'errno' so it can be tested after the
115 // macro call (i.e. any error during log output does not interfere).
116 #define PLOG(severity)  \
117         LOG_LAZY_EVAL(LOG_IS_ON(severity), \
118         PLOG_MESSAGE_STREAM_COMPACT(severity))
119 
120 // A variant of LOG_IF() that also appends the string message corresponding
121 // to the current value of 'errno' just before the macro is called. This
122 // also preserves the value of 'errno' so it can be tested after the
123 // macro call (i.e. any error during log output does not interfere).
124 #define PLOG_IF(severity, condition) \
125         LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \
126                       PLOG_MESSAGE_STREAM_COMPACT(severity))
127 
128 // Evaluate |condition|, and if it fails, log a fatal message.
129 // This is a better version of assert(), in the future, this will
130 // also break directly into the debugger for debug builds.
131 //
132 // Usage is similar to LOG(FATAL), e.g.:
133 //
134 //   CHECK(some_condition) << "Something really bad happened!";
135 //
136 #define CHECK(condition) \
137     LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
138 
139 
140 // A variant of CHECK() that also appends the errno message string at
141 // the end of the log message before exiting the process.
142 #define PCHECK(condition) \
143     PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
144 
145 
146 // Define ENABLE_DLOG to 1 here if DLOG() statements should be compiled
147 // as normal LOG() ones in the final binary. If 0, the statements will not
148 // be compiled.
149 #ifndef ENABLE_DLOG
150 #  if defined(NDEBUG)
151 #    define ENABLE_DLOG 0
152 #  else
153 #    define ENABLE_DLOG 1
154 #  endif
155 #endif
156 
157 // ENABLE_DCHECK controls how DCHECK() statements are compiled:
158 //    0 - DCHECK() are not compiled in the binary at all.
159 //    1 - DCHECK() are compiled, but are not performed at runtime, unless
160 //        the DCHECK level has been increased explicitely.
161 //    2 - DCHECK() are always compiled as CHECK() in the final binary.
162 #ifndef ENABLE_DCHECK
163 #  if defined(NDEBUG)
164 #    define ENABLE_DCHECK 1
165 #  else
166 #    define ENABLE_DCHECK 2
167 #  endif
168 #endif
169 
170 // DLOG_IS_ON(severity) is used to indicate whether DLOG() should print
171 // something for the current level.
172 #if ENABLE_DLOG
173 #  define DLOG_IS_ON(severity) LOG_IS_ON(severity)
174 #else
175 // NOTE: The compile-time constant ensures that the DLOG() statements are
176 //       not compiled in the final binary.
177 #  define DLOG_IS_ON(severity) false
178 #endif
179 
180 // DCHECK_IS_ON() is used to indicate whether DCHECK() should do anything.
181 #if ENABLE_DCHECK == 0
182     // NOTE: Compile-time constant ensures the DCHECK() statements are
183     // note compiled in the final binary.
184 #  define DCHECK_IS_ON()  false
185 #elif ENABLE_DCHECK == 1
186 #  define DCHECK_IS_ON()  ::android::base::dcheckIsEnabled()
187 #else
188 #  define DCHECK_IS_ON()  true
189 #endif
190 
191 // A function that returns true iff DCHECK() should actually do any checking.
192 bool dcheckIsEnabled();
193 
194 // Change the DCHECK() level to either false or true. Should only be called
195 // early, e.g. after parsing command-line arguments. Returns previous value.
196 bool setDcheckLevel(bool enabled);
197 
198 // DLOG() is like LOG() for debug builds, and doesn't do anything for
199 // release one. This is useful to add log messages that you don't want
200 // to see in the final binaries, but are useful during testing.
201 #define DLOG(severity)  LOG_IF(severity, DLOG_IS_ON())
202 
203 // DLOG_IF() is like DLOG() for debug builds, and doesn't do anything for
204 // release one. See DLOG() comments.
205 #define DLOG_IF(severity, condition)  \
206         LOG_IF(severity, DLOG_IS_ON() && (condition))
207 
208 // DCHECK(condition) is used to perform CHECK() in debug builds, or if
209 // the program called setDcheckLevel(true) previously. Note that it is
210 // also possible to completely remove them from the final binary by
211 // using the compiler flag -DENABLE_DCHECK=0
212 #define DCHECK(condition) \
213         LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) \
214             << "Check failed: " #condition ". "
215 
216 // Convenience class used hold a formatted string for logging reasons.
217 // Usage example:
218 //
219 //    LOG(INFO) << LogString("There are %d items in this set", count);
220 //
221 class LogString {
222 public:
223     LogString(const char* fmt, ...);
224     ~LogString();
string()225     const char* string() const { return mString; }
226 private:
227     char* mString;
228 };
229 
230 // Helper structure used to group the parameters of a LOG() or CHECK()
231 // statement.
232 struct LogParams {
LogParamsLogParams233     LogParams() : file(NULL), lineno(-1), severity(-1) {}
234 
LogParamsLogParams235     LogParams(const char* a_file, int a_lineno, LogSeverity a_severity)
236             : file(a_file), lineno(a_lineno), severity(a_severity) {}
237 
238     const char* file;
239     int lineno;
240     LogSeverity severity;
241 };
242 
243 // Helper class used to implement an input stream similar to std::istream
244 // where it's possible to inject strings, integers, floats and LogString
245 // instances with the << operator.
246 //
247 // This also takes a source file, line number and severity to avoid
248 // storing these in the stack of the functions were LOG() and CHECK()
249 // statements are called.
250 class LogStream {
251 public:
252     LogStream(const char* file, int lineno, LogSeverity severity);
253     ~LogStream();
254 
255     inline LogStream& operator<<(const char* str) {
256         append(str);
257         return *this;
258     }
259 
260     inline LogStream& operator<<(const LogString& str) {
261         append(str.string());
262         return *this;
263     }
264 
265     // Note: this prints the pointer value (address).
266     LogStream& operator<<(const void* v);
267 
268     LogStream& operator<<(char ch);
269     LogStream& operator<<(int v);
270     LogStream& operator<<(unsigned v);
271     LogStream& operator<<(long v);
272     LogStream& operator<<(unsigned long v);
273     //LogStream& operator<<(size_t v);
274     LogStream& operator<<(long long v);
275     LogStream& operator<<(unsigned long long v);
276     LogStream& operator<<(float v);
277     LogStream& operator<<(double v);
278 
string()279     const char* string() const { return mString ? mString : ""; }
size()280     size_t size() const { return mSize; }
params()281     const LogParams& params() const { return mParams; }
282 
283 private:
284     void append(const char* str);
285     void append(const char* str, size_t len);
286 
287     LogParams mParams;
288     char* mString;
289     size_t mSize;
290     size_t mCapacity;
291 };
292 
293 // Helper class used to avoid compiler errors, see LOG_LAZY_EVAL for
294 // more information.
295 class LogStreamVoidify {
296  public:
LogStreamVoidify()297   LogStreamVoidify() { }
298   // This has to be an operator with a precedence lower than << but
299   // higher than ?:
300   void operator&(LogStream&) { }
301 };
302 
303 // This represents an log message. At creation time, provide the name of
304 // the current file, the source line number and a severity.
305 // You can them stream stuff into it with <<. For example:
306 //
307 //   LogMessage(__FILE__, __LINE__, LOG_INFO) << "Hello World!\n";
308 //
309 // When destroyed, the message sends the final output to the appropriate
310 // log (e.g. stderr by default).
311 class LogMessage {
312 public:
313     LogMessage(const char* file, int line, LogSeverity severity);
314     ~LogMessage();
315 
stream()316     LogStream& stream() const { return *mStream; }
317 protected:
318     // Avoid that each LOG() statement
319     LogStream* mStream;
320 };
321 
322 // Helper macros to avoid too much typing. This creates a new LogMessage
323 // instance with the appropriate file source path, file source line and
324 // severity.
325 #define LOG_MESSAGE_COMPACT(severity) \
326     ::android::base::LogMessage( \
327             __FILE__, \
328             __LINE__, \
329             ::android::base::LOG_ ## severity)
330 
331 #define LOG_MESSAGE_STREAM_COMPACT(severity) \
332     LOG_MESSAGE_COMPACT(severity).stream()
333 
334 
335 // A variant of LogMessage that saves the errno value on creation,
336 // then restores it on destruction, as well as append a strerror()
337 // error message to the log before sending it for output. Used by
338 // the PLOG() implementation(s).
339 //
340 // This cannot be a sub-class of LogMessage because the destructor needs
341 // to restore the saved errno message after sending the message to the
342 // LogOutput and deleting the stream.
343 class ErrnoLogMessage {
344 public:
345     ErrnoLogMessage(const char* file,
346                     int line,
347                     LogSeverity severity,
348                     int errnoCode);
349     ~ErrnoLogMessage();
350 
stream()351     LogStream& stream() const { return *mStream; }
352 private:
353     LogStream* mStream;
354     int mErrno;
355 };
356 
357 // Helper macros to avoid too much typing.
358 #define PLOG_MESSAGE_COMPACT(severity) \
359     ::android::base::ErrnoLogMessage( \
360             __FILE__, \
361             __LINE__, \
362             ::android::base::LOG_ ## severity, \
363             errno)
364 
365 #define PLOG_MESSAGE_STREAM_COMPACT(severity) \
366     PLOG_MESSAGE_COMPACT(severity).stream()
367 
368 namespace testing {
369 
370 // Abstract interface to the output where the log messages are sent.
371 // IMPORTANT: Only use this for unit testing the log facility.
372 class LogOutput {
373 public:
LogOutput()374     LogOutput() {}
~LogOutput()375     virtual ~LogOutput() {}
376 
377     // Send a full log message to the output. Not zero terminated, and
378     // Does not have a trailing \n which can be added by the implementation
379     // when writing the message to a file.
380     // Note: if |severity| is LOG_FATAL, this should also terminate the
381     // process.
382     virtual void logMessage(const LogParams& params,
383                             const char* message,
384                             size_t message_len) = 0;
385 
386     // Set a new log output, and return pointer to the previous
387     // implementation, which will be NULL for the default one.
388     // |newOutput| is either NULL (which means the default), or a
389     // custom instance of LogOutput.
390     static LogOutput* setNewOutput(LogOutput* newOutput);
391 };
392 
393 }  // namespace testing
394 
395 }  // namespace base
396 }  // namespace android
397 
398 #endif  // ANDROID_BASE_LOG_H
399