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