• 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 
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 #define LOG_IS_ON(severity) (LOG_SEVERITY_FROM(severity) >= getMinLogLevel())
100 
101 // For performance reasons, it's important to avoid constructing a
102 // LogMessage instance every time a LOG() or CHECK() statement is
103 // encountered at runtime, i.e. these objects should only be constructed
104 // when absolutely necessary, which means:
105 //  - For LOG() statements, when the corresponding log level is enabled.
106 //  - For CHECK(), when the tested expression doesn't hold.
107 //
108 // At the same time, we really want to use expressions like:
109 //    LOG(severity) << some_stuff << some_more_stuff;
110 //
111 // This means LOG(severity) should expand to something that can take
112 // << operators on its right hand side. This is achieved with the
113 // ternary '? :', as implemented by this helper macro.
114 //
115 // Unfortunately, a simple thing like:
116 //
117 //   !(condition) ? (void)0 : (expr)
118 //
119 // will not work, because the compiler complains loudly with:
120 //
121 //   error: second operand to the conditional operator is of type 'void',
122 //   but the third operand is neither a throw-expression nor of type 'void'
123 #define LOG_LAZY_EVAL(condition, expr) \
124     !(condition) ? (void)0 : ::android::base::LogStreamVoidify() & (expr)
125 
126 // Send a message to the log if |severity| is higher or equal to the current
127 // logging severity level. This macro expands to an expression that acts as
128 // an input stream for strings, ints and floating point values, as well as
129 // LogString instances. Usage example:
130 //
131 //    LOG(INFO) << "Starting flux capacitor";
132 //    fluxCapacitor::start();
133 //    LOG(INFO) << "Flux capacitor started";
134 //
135 // Note that the macro implementation is optimized to avoid doing any work
136 // if the severity level is disabled.
137 //
138 // It's possible to do conditional logging with LOG_IF()
139 #define LOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), LOG_MESSAGE_STREAM_COMPACT(severity))
140 
141 // A variant of LOG() that only performs logging if a specific condition
142 // is encountered. Note that |condition| is only evaluated if |severity|
143 // is high enough. Usage example:
144 //
145 //    LOG(INFO) << "Starting fuel injector";
146 //    fuelInjector::start();
147 //    LOG(INFO) << "Fuel injection started";
148 //    LOG_IF(INFO, fuelInjector::hasOptimalLevel())
149 //            << "Fuel injection at optimal level";
150 //
151 #define LOG_IF(severity, condition) \
152     LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), LOG_MESSAGE_STREAM_COMPACT(severity))
153 
154 // A variant of LOG() that avoids printing debug information such as file/line
155 // information, for user-visible output.
156 #define QLOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), QLOG_MESSAGE_STREAM_COMPACT(severity))
157 
158 // A variant of LOG_IF() that avoids printing debug information such as
159 // file/line information, for user-visible output.
160 #define QLOG_IF(severity, condition) \
161     LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), QLOG_MESSAGE_STREAM_COMPACT(severity))
162 
163 // A variant of LOG() that integrates with the utils/debug.h verbose tags,
164 // enabling statements to only appear on the console if the "-debug-<tag>"
165 // command line parameter is provided.  Example:
166 //
167 //    VLOG(virtualscene) << "Starting scene.";
168 //
169 // Which would only be visible if -debug-virtualscene or -debug-all is passed
170 // as a command line parameter.
171 //
172 // When logging is enabled, VLOG statements are logged at the INFO severity.
173 #define VLOG(tag) LOG_LAZY_EVAL(VERBOSE_CHECK(tag), LOG_MESSAGE_STREAM_COMPACT(INFO))
174 
175 // A variant of LOG() that also appends the string message corresponding
176 // to the current value of 'errno' just before the macro is called. This
177 // also preserves the value of 'errno' so it can be tested after the
178 // macro call (i.e. any error during log output does not interfere).
179 #define PLOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), PLOG_MESSAGE_STREAM_COMPACT(severity))
180 
181 // A variant of LOG_IF() that also appends the string message corresponding
182 // to the current value of 'errno' just before the macro is called. This
183 // also preserves the value of 'errno' so it can be tested after the
184 // macro call (i.e. any error during log output does not interfere).
185 #define PLOG_IF(severity, condition) \
186     LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), PLOG_MESSAGE_STREAM_COMPACT(severity))
187 
188 // Evaluate |condition|, and if it fails, log a fatal message.
189 // This is a better version of assert(), in the future, this will
190 // also break directly into the debugger for debug builds.
191 //
192 // Usage is similar to LOG(FATAL), e.g.:
193 //
194 //   CHECK(some_condition) << "Something really bad happened!";
195 //
196 #define CHECK(condition) LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
197 
198 // A variant of CHECK() that also appends the errno message string at
199 // the end of the log message before exiting the process.
200 #define PCHECK(condition) PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
201 
202 // Define ENABLE_DLOG to 1 here if DLOG() statements should be compiled
203 // as normal LOG() ones in the final binary. If 0, the statements will not
204 // be compiled.
205 #ifndef ENABLE_DLOG
206 #if defined(NDEBUG)
207 #define ENABLE_DLOG 0
208 #else
209 #define ENABLE_DLOG 1
210 #endif
211 #endif
212 
213 // ENABLE_DCHECK controls how DCHECK() statements are compiled:
214 //    0 - DCHECK() are not compiled in the binary at all.
215 //    1 - DCHECK() are compiled, but are not performed at runtime, unless
216 //        the DCHECK level has been increased explicitely.
217 //    2 - DCHECK() are always compiled as CHECK() in the final binary.
218 #ifndef ENABLE_DCHECK
219 #if defined(NDEBUG)
220 #define ENABLE_DCHECK 1
221 #else
222 #define ENABLE_DCHECK 2
223 #endif
224 #endif
225 
226 // DLOG_IS_ON(severity) is used to indicate whether DLOG() should print
227 // something for the current level.
228 #if ENABLE_DLOG
229 #define DLOG_IS_ON(severity) LOG_IS_ON(severity)
230 #else
231 // NOTE: The compile-time constant ensures that the DLOG() statements are
232 //       not compiled in the final binary.
233 #define DLOG_IS_ON(severity) false
234 #endif
235 
236 // DCHECK_IS_ON() is used to indicate whether DCHECK() should do anything.
237 #if ENABLE_DCHECK == 0
238 // NOTE: Compile-time constant ensures the DCHECK() statements are
239 // not compiled in the final binary.
240 #define DCHECK_IS_ON() false
241 #elif ENABLE_DCHECK == 1
242 #define DCHECK_IS_ON() ::android::base::dcheckIsEnabled()
243 #else
244 #define DCHECK_IS_ON() true
245 #endif
246 
247 // A function that returns true iff DCHECK() should actually do any checking.
248 LOGGING_API bool dcheckIsEnabled();
249 
250 // Change the DCHECK() level to either false or true. Should only be called
251 // early, e.g. after parsing command-line arguments. Returns previous value.
252 LOGGING_API bool setDcheckLevel(bool enabled);
253 
254 // DLOG() is like LOG() for debug builds, and doesn't do anything for
255 // release one. This is useful to add log messages that you don't want
256 // to see in the final binaries, but are useful during testing.
257 #define DLOG(severity) DLOG_IF(severity, true)
258 
259 // DLOG_IF() is like DLOG() for debug builds, and doesn't do anything for
260 // release one. See DLOG() comments.
261 #define DLOG_IF(severity, condition) \
262     LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), LOG_MESSAGE_STREAM_COMPACT(severity))
263 
264 // DCHECK(condition) is used to perform CHECK() in debug builds, or if
265 // the program called setDcheckLevel(true) previously. Note that it is
266 // also possible to completely remove them from the final binary by
267 // using the compiler flag -DENABLE_DCHECK=0
268 #define DCHECK(condition) \
269     LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) << "Check failed: " #condition ". "
270 
271 // DPLOG() is like DLOG() that also appends the string message corresponding
272 // to the current value of 'errno' just before the macro is called. This
273 // also preserves the value of 'errno' so it can be tested after the
274 // macro call (i.e. any error during log output does not interfere).
275 #define DPLOG(severity) DPLOG_IF(severity, true)
276 
277 // DPLOG_IF() tests whether |condition| is true before calling
278 // DPLOG(severity)
279 #define DPLOG_IF(severity, condition) \
280     LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), PLOG_MESSAGE_STREAM_COMPACT(severity))
281 
282 // Convenience class used hold a formatted string for logging reasons.
283 // Usage example:
284 //
285 //    LOG(INFO) << LogString("There are %d items in this set", count);
286 //
287 class LOGGING_API LogString {
288    public:
289     LogString(const char* fmt, ...);
string()290     const char* string() const { return mString.data(); }
291 
292    private:
293     std::vector<char> mString;
294 };
295 
296 // Helper structure used to group the parameters of a LOG() or CHECK()
297 // statement.
298 struct LOGGING_API LogParams {
LogParamsLogParams299     LogParams() {}
300     LogParams(const char* a_file, int a_lineno, LogSeverity a_severity, bool quiet = false)
fileLogParams301         : file(a_file), lineno(a_lineno), severity(a_severity), quiet(quiet) {}
302 
303     friend bool operator==(const LogParams& s1, const LogParams& s2) {
304         return s1.lineno == s2.lineno && s1.severity == s2.severity && s1.quiet == s2.quiet &&
305                ((s1.file == nullptr && s2.file == nullptr) ||  // both null..
306                 (s1.file != nullptr && s2.file != nullptr &&
307                  (s1.file == s2.file || strcmp(s1.file, s2.file) == 0))  // or the same
308                );
309     }
310 
311     const char* file = nullptr;
312     int lineno = -1;
313     LogSeverity severity = LOG_SEVERITY_FROM(DEBUG);
314     bool quiet = false;
315 };
316 
317 class LOGGING_API LogstreamBuf : public std::streambuf {
318    public:
319     LogstreamBuf();
320 
321     size_t size();
322     char* str();
323 
324    protected:
325     int overflow(int c) override;
326 
327    private:
328     std::vector<char> mLongString;
329     char mStr[256];
330 };
331 
332 // Helper class used to implement an input stream similar to std::istream
333 // where it's possible to inject strings, integers, floats and LogString
334 // instances with the << operator.
335 //
336 // This also takes a source file, line number and severity to avoid
337 // storing these in the stack of the functions were LOG() and CHECK()
338 // statements are called.
339 class LOGGING_API LogStream {
340    public:
341     LogStream(const char* file, int lineno, LogSeverity severity, bool quiet);
342     ~LogStream() = default;
343 
344     template <typename T>
345     std::ostream& operator<<(const T& t) {
346         return mStream << t;
347     }
348 
str()349     const char* str() { return mStreamBuf.str(); }
350 
size()351     const size_t size() { return mStreamBuf.size(); }
params()352     const LogParams& params() const { return mParams; }
353 
354    private:
355     LogParams mParams;
356     LogstreamBuf mStreamBuf;
357     std::ostream mStream;
358 };
359 
360 // Add your own types when needed:
361 LOGGING_API std::ostream& operator<<(std::ostream& stream, const android::base::LogString& str);
362 LOGGING_API std::ostream& operator<<(std::ostream& stream, const std::string_view& str);
363 
364 // Helper class used to avoid compiler errors, see LOG_LAZY_EVAL for
365 // more information.
366 class LOGGING_API LogStreamVoidify {
367    public:
LogStreamVoidify()368     LogStreamVoidify() {}
369     // This has to be an operator with a precedence lower than << but
370     // higher than ?:
371     void operator&(std::ostream&) {}
372 };
373 
374 // This represents an log message. At creation time, provide the name of
375 // the current file, the source line number and a severity.
376 // You can them stream stuff into it with <<. For example:
377 //
378 //   LogMessage(__FILE__, __LINE__, LOG_INFO) << "Hello World!\n";
379 //
380 // When destroyed, the message sends the final output to the appropriate
381 // log (e.g. stderr by default).
382 class LOGGING_API LogMessage {
383    public:
384     // To suppress printing file/line, set quiet = true.
385     LogMessage(const char* file, int line, LogSeverity severity, bool quiet = false);
386     ~LogMessage();
387 
stream()388     LogStream& stream() const { return *mStream; }
389 
390    protected:
391     // Avoid that each LOG() statement
392     LogStream* mStream;
393 };
394 
395 // Helper macros to avoid too much typing. This creates a new LogMessage
396 // instance with the appropriate file source path, file source line and
397 // severity.
398 #define LOG_MESSAGE_COMPACT(severity) \
399     ::android::base::LogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity))
400 
401 #define LOG_MESSAGE_STREAM_COMPACT(severity) LOG_MESSAGE_COMPACT(severity).stream()
402 
403 // A variant of LogMessage for outputting user-visible messages to the console,
404 // without debug information.
405 #define QLOG_MESSAGE_COMPACT(severity) \
406     ::android::base::LogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity), true)
407 
408 #define QLOG_MESSAGE_STREAM_COMPACT(severity) QLOG_MESSAGE_COMPACT(severity).stream()
409 
410 // A variant of LogMessage that saves the errno value on creation,
411 // then restores it on destruction, as well as append a strerror()
412 // error message to the log before sending it for output. Used by
413 // the PLOG() implementation(s).
414 //
415 // This cannot be a sub-class of LogMessage because the destructor needs
416 // to restore the saved errno message after sending the message to the
417 // LogOutput and deleting the stream.
418 class LOGGING_API ErrnoLogMessage {
419    public:
420     ErrnoLogMessage(const char* file, int line, LogSeverity severity, int errnoCode);
421     ~ErrnoLogMessage();
422 
stream()423     LogStream& stream() const { return *mStream; }
424 
425    private:
426     LogStream* mStream;
427     int mErrno;
428 };
429 
430 // Helper macros to avoid too much typing.
431 #define PLOG_MESSAGE_COMPACT(severity) \
432     ::android::base::ErrnoLogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity), errno)
433 
434 #define PLOG_MESSAGE_STREAM_COMPACT(severity) PLOG_MESSAGE_COMPACT(severity).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