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