diff options
author | Erwin Jansen <jansene@google.com> | 2023-10-31 13:00:31 -0700 |
---|---|---|
committer | Erwin Jansen <jansene@google.com> | 2023-12-20 12:57:46 -0800 |
commit | caf5a079f321b6c60ab7b4bf6e5516378c6a7b37 (patch) | |
tree | 700028c281dcf26d2c8da8ee29bb262fd266e4c9 | |
parent | dc4b530a0db8472170feef17106c8ade5f3e1459 (diff) | |
download | aemu-caf5a079f321b6c60ab7b4bf6e5516378c6a7b37.tar.gz |
Simplify formatter interface to use std::string
This simplifies the formatter interface and adds annotations to indicate
that log functions expect format strings.
The compiler will now perform checking on the logging strings used, and
fixes a series of logging issues.
Change-Id: Icc899f4579f2ceb431d9ef81cd50ee9d0d6f07d2
-rw-r--r-- | base/include/aemu/base/EintrWrapper.h | 67 | ||||
-rw-r--r-- | base/include/aemu/base/FunctionView.h | 6 | ||||
-rw-r--r-- | base/include/aemu/base/logging/CLog.h | 35 | ||||
-rw-r--r-- | base/include/aemu/base/logging/Log.h | 190 | ||||
-rw-r--r-- | base/include/aemu/base/logging/LogFormatter.h | 48 | ||||
-rw-r--r-- | base/include/aemu/base/logging/LogSeverity.h | 26 | ||||
-rw-r--r-- | base/include/aemu/base/logging/LogTags.h | 22 | ||||
-rw-r--r-- | host-common/include/host-common/AndroidAsyncMessagePipe.h | 33 | ||||
-rw-r--r-- | host-common/include/host-common/MultiDisplay.h | 6 |
9 files changed, 227 insertions, 206 deletions
diff --git a/base/include/aemu/base/EintrWrapper.h b/base/include/aemu/base/EintrWrapper.h index f89a752..b00129b 100644 --- a/base/include/aemu/base/EintrWrapper.h +++ b/base/include/aemu/base/EintrWrapper.h @@ -15,8 +15,9 @@ #pragma once #include <errno.h> - +#ifndef dfatal #include "aemu/base/logging/CLog.h" +#endif namespace android { namespace base { @@ -27,11 +28,11 @@ namespace base { // Mostly used for unit testing. // If the macro is undefined, auto-detect the value based on NDEBUG. #if !defined(EINTR_WRAPPER_DEBUG) -# ifdef NDEBUG -# define EINTR_WRAPPER_DEBUG 0 -# else -# define EINTR_WRAPPER_DEBUG 1 -# endif +#ifdef NDEBUG +#define EINTR_WRAPPER_DEBUG 0 +#else +#define EINTR_WRAPPER_DEBUG 1 +#endif #endif // HANDLE_EINTR() is a macro used to handle EINTR return values when @@ -57,34 +58,33 @@ namespace base { // much random! It's better to leave the descriptor open than risk // closing another one by mistake :( // -#define MAX_EINTR_LOOP_COUNT 100 +#define MAX_EINTR_LOOP_COUNT 100 #ifdef _WIN32 -# define HANDLE_EINTR(x) (x) +#define HANDLE_EINTR(x) (x) #elif EINTR_WRAPPER_DEBUG == 0 -# define HANDLE_EINTR(x) \ - __extension__ ({ \ - __typeof__(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ +#define HANDLE_EINTR(x) \ + __extension__({ \ + __typeof__(x) eintr_wrapper_result; \ + do { \ + eintr_wrapper_result = (x); \ } while (eintr_wrapper_result < 0 && errno == EINTR); \ - eintr_wrapper_result; \ + eintr_wrapper_result; \ }) #else // !_WIN32 && EINTR_WRAPPER_DEBUG -# define HANDLE_EINTR(x) \ - __extension__ ({ \ - __typeof__(x) eintr_wrapper_result; \ - int eintr_wrapper_loop_count = 0; \ - for (;;) { \ - eintr_wrapper_result = (x); \ - if (eintr_wrapper_result != -1 || errno != EINTR) \ - break; \ - ++eintr_wrapper_loop_count; \ - if(eintr_wrapper_loop_count >= MAX_EINTR_LOOP_COUNT) \ - dfatal("Looping around EINTR too many times"); \ - }; \ - eintr_wrapper_result; \ +#define HANDLE_EINTR(x) \ + __extension__({ \ + __typeof__(x) eintr_wrapper_result; \ + int eintr_wrapper_loop_count = 0; \ + for (;;) { \ + eintr_wrapper_result = (x); \ + if (eintr_wrapper_result != -1 || errno != EINTR) break; \ + ++eintr_wrapper_loop_count; \ + if (eintr_wrapper_loop_count >= MAX_EINTR_LOOP_COUNT) \ + dfatal("Looping around EINTR too many times"); \ + }; \ + eintr_wrapper_result; \ }) #endif // !_WIN32 && EINTR_WRAPPER_DEBUG @@ -93,14 +93,13 @@ namespace base { // This is mostly used with the close() system call, as described // in the HANDLE_EINTR() documentation. #ifdef _WIN32 -# define IGNORE_EINTR(x) (x) +#define IGNORE_EINTR(x) (x) #else -# define IGNORE_EINTR(x) \ - __extension__ ({ \ - __typeof__(x) eintr_wrapper_result = (x); \ - if (eintr_wrapper_result == -1 && errno == EINTR) \ - eintr_wrapper_result = 0; \ - eintr_wrapper_result; \ +#define IGNORE_EINTR(x) \ + __extension__({ \ + __typeof__(x) eintr_wrapper_result = (x); \ + if (eintr_wrapper_result == -1 && errno == EINTR) eintr_wrapper_result = 0; \ + eintr_wrapper_result; \ }) #endif diff --git a/base/include/aemu/base/FunctionView.h b/base/include/aemu/base/FunctionView.h index 5fbf7ae..3ebd622 100644 --- a/base/include/aemu/base/FunctionView.h +++ b/base/include/aemu/base/FunctionView.h @@ -14,11 +14,13 @@ #pragma once -#include "aemu/base/TypeTraits.h" - +#include <cstdint> #include <string_view> #include <utility> +#include "aemu/base/TypeTraits.h" + + namespace android { namespace base { diff --git a/base/include/aemu/base/logging/CLog.h b/base/include/aemu/base/logging/CLog.h index 9a7959a..133854e 100644 --- a/base/include/aemu/base/logging/CLog.h +++ b/base/include/aemu/base/logging/CLog.h @@ -36,53 +36,42 @@ extern "C" { #endif -typedef enum { - kLogDefaultOptions = 0, - kLogEnableDuplicateFilter = 1, - kLogEnableTime = 1 << 2, - kLogEnableVerbose = 1 << 3, -} LoggingFlags; - -// Enable/disable verbose logs from the base/* family. -LOGGING_API void base_enable_verbose_logs(); -LOGGING_API void base_disable_verbose_logs(); - -LOGGING_API void verbose_enable(uint64_t tag); -LOGGING_API void verbose_disable(uint64_t tag); -LOGGING_API bool verbose_check(uint64_t tag); -LOGGING_API bool verbose_check_any(); -LOGGING_API void set_verbosity_mask(uint64_t mask); -LOGGING_API uint64_t get_verbosity_mask(); - -// Configure the logging framework. -LOGGING_API void base_configure_logs(LoggingFlags flags); -LOGGING_API void __emu_log_print(LogSeverity prio, const char* file, int line, const char* fmt, - ...); +LOGGING_API void __emu_log_print(LogSeverity prio, const char* file, int line, const char* fmt, ...) + __attribute__((format(printf, 4, 5))); #ifndef EMULOG #define EMULOG(priority, fmt, ...) \ __emu_log_print(priority, __FILE__, __LINE__, fmt, ##__VA_ARGS__); #endif +#ifndef dprint // Logging support. #define dprint(fmt, ...) \ if (EMULATOR_LOG_DEBUG >= getMinLogLevel()) { \ EMULOG(EMULATOR_LOG_DEBUG, fmt, ##__VA_ARGS__) \ } - +#endif +#ifndef dinfo #define dinfo(fmt, ...) \ if (EMULATOR_LOG_INFO >= getMinLogLevel()) { \ EMULOG(EMULATOR_LOG_INFO, fmt, ##__VA_ARGS__) \ } +#endif +#ifndef dwarning #define dwarning(fmt, ...) \ if (EMULATOR_LOG_WARNING >= getMinLogLevel()) { \ EMULOG(EMULATOR_LOG_WARNING, fmt, ##__VA_ARGS__) \ } +#endif +#ifndef derror #define derror(fmt, ...) \ if (EMULATOR_LOG_ERROR >= getMinLogLevel()) { \ EMULOG(EMULATOR_LOG_ERROR, fmt, ##__VA_ARGS__) \ } +#endif +#ifndef dfatal #define dfatal(fmt, ...) EMULOG(EMULATOR_LOG_FATAL, fmt, ##__VA_ARGS__) +#endif #ifdef __cplusplus } diff --git a/base/include/aemu/base/logging/Log.h b/base/include/aemu/base/logging/Log.h index 7a1b159..de8042f 100644 --- a/base/include/aemu/base/logging/Log.h +++ b/base/include/aemu/base/logging/Log.h @@ -14,23 +14,67 @@ #pragma once -#include <errno.h> // for errno -#include <stdio.h> // for size_t, EOF -#include <string.h> // for strcmp -#include <iostream> // for ostream, operator<< +#include <errno.h> // for errno +#include <stdio.h> // for size_t, EOF +#include <string.h> // for strcmp + +#include <iostream> // for ostream, operator<< #include <string_view> -#include <vector> // for vector +#include <vector> // for vector +#include "absl/strings/str_format.h" #include "aemu/base/logging/LogSeverity.h" // for LogSeverity, EMULATOR_... +#ifndef LOGGING_API #ifdef _MSC_VER -# ifdef LOGGING_API_SHARED -# define LOGGING_API __declspec(dllexport) -# else -# define LOGGING_API __declspec(dllimport) +#ifdef LOGGING_API_SHARED +#define LOGGING_API __declspec(dllexport) +#else +#define LOGGING_API __declspec(dllimport) #endif #else -# define LOGGING_API +#define LOGGING_API __attribute__((visibility("default"))) +#endif +#endif + +LOGGING_API void __emu_log_print_str(LogSeverity prio, const char* file, int line, const std::string& msg); + +template <typename... Args> +void __emu_log_print_cplusplus(LogSeverity prio, const char* file, int line, + const absl::FormatSpec<Args...>& format, const Args&... args) { + __emu_log_print_str(prio, file, line, std::move(absl::StrFormat(format, args...))); +} + +#define EMULOGCPLUSPLUS(priority, fmt, ...) \ + __emu_log_print_cplusplus(priority, __FILE__, __LINE__, fmt, ##__VA_ARGS__); + +// Logging support. +#ifndef dprint +#define dprint(fmt, ...) \ + if (EMULATOR_LOG_DEBUG >= getMinLogLevel()) { \ + EMULOGCPLUSPLUS(EMULATOR_LOG_DEBUG, fmt, ##__VA_ARGS__) \ + } +#endif +#ifndef dinfo +#define dinfo(fmt, ...) \ + if (EMULATOR_LOG_INFO >= getMinLogLevel()) { \ + EMULOGCPLUSPLUS(EMULATOR_LOG_INFO, fmt, ##__VA_ARGS__) \ + } +#endif +#ifndef dwarning +#define dwarning(fmt, ...) \ + if (EMULATOR_LOG_WARNING >= getMinLogLevel()) { \ + EMULOGCPLUSPLUS(EMULATOR_LOG_WARNING, fmt, ##__VA_ARGS__) \ + } +#endif +#ifndef derror +#define derror(fmt, ...) \ + if (EMULATOR_LOG_ERROR >= getMinLogLevel()) { \ + EMULOGCPLUSPLUS(EMULATOR_LOG_ERROR, fmt, ##__VA_ARGS__) \ + } +#endif +#ifndef dfatal +#define dfatal(fmt, ...) EMULOGCPLUSPLUS(EMULATOR_LOG_FATAL, fmt, ##__VA_ARGS__) #endif namespace android { @@ -52,8 +96,7 @@ LOGGING_API void setLogFormatter(LogFormatter* fmt); // ... do additionnal logging // } // -#define LOG_IS_ON(severity) \ - (LOG_SEVERITY_FROM(severity) >= getMinLogLevel()) +#define LOG_IS_ON(severity) (LOG_SEVERITY_FROM(severity) >= getMinLogLevel()) // For performance reasons, it's important to avoid constructing a // LogMessage instance every time a LOG() or CHECK() statement is @@ -93,8 +136,7 @@ LOGGING_API void setLogFormatter(LogFormatter* fmt); // if the severity level is disabled. // // It's possible to do conditional logging with LOG_IF() -#define LOG(severity) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity), LOG_MESSAGE_STREAM_COMPACT(severity)) +#define LOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), LOG_MESSAGE_STREAM_COMPACT(severity)) // A variant of LOG() that only performs logging if a specific condition // is encountered. Note that |condition| is only evaluated if |severity| @@ -106,20 +148,17 @@ LOGGING_API void setLogFormatter(LogFormatter* fmt); // LOG_IF(INFO, fuelInjector::hasOptimalLevel()) // << "Fuel injection at optimal level"; // -#define LOG_IF(severity, condition) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ - LOG_MESSAGE_STREAM_COMPACT(severity)) +#define LOG_IF(severity, condition) \ + LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), LOG_MESSAGE_STREAM_COMPACT(severity)) // A variant of LOG() that avoids printing debug information such as file/line // information, for user-visible output. -#define QLOG(severity) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity), QLOG_MESSAGE_STREAM_COMPACT(severity)) +#define QLOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), QLOG_MESSAGE_STREAM_COMPACT(severity)) // A variant of LOG_IF() that avoids printing debug information such as // file/line information, for user-visible output. -#define QLOG_IF(severity, condition) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ - QLOG_MESSAGE_STREAM_COMPACT(severity)) +#define QLOG_IF(severity, condition) \ + LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), QLOG_MESSAGE_STREAM_COMPACT(severity)) // A variant of LOG() that integrates with the utils/debug.h verbose tags, // enabling statements to only appear on the console if the "-debug-<tag>" @@ -131,23 +170,20 @@ LOGGING_API void setLogFormatter(LogFormatter* fmt); // as a command line parameter. // // When logging is enabled, VLOG statements are logged at the INFO severity. -#define VLOG(tag) \ - LOG_LAZY_EVAL(VERBOSE_CHECK(tag), LOG_MESSAGE_STREAM_COMPACT(INFO)) +#define VLOG(tag) LOG_LAZY_EVAL(VERBOSE_CHECK(tag), LOG_MESSAGE_STREAM_COMPACT(INFO)) // A variant of LOG() that also appends the string message corresponding // to the current value of 'errno' just before the macro is called. This // also preserves the value of 'errno' so it can be tested after the // macro call (i.e. any error during log output does not interfere). -#define PLOG(severity) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity), PLOG_MESSAGE_STREAM_COMPACT(severity)) +#define PLOG(severity) LOG_LAZY_EVAL(LOG_IS_ON(severity), PLOG_MESSAGE_STREAM_COMPACT(severity)) // A variant of LOG_IF() that also appends the string message corresponding // to the current value of 'errno' just before the macro is called. This // also preserves the value of 'errno' so it can be tested after the // macro call (i.e. any error during log output does not interfere). -#define PLOG_IF(severity, condition) \ - LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ - PLOG_MESSAGE_STREAM_COMPACT(severity)) +#define PLOG_IF(severity, condition) \ + LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), PLOG_MESSAGE_STREAM_COMPACT(severity)) // Evaluate |condition|, and if it fails, log a fatal message. // This is a better version of assert(), in the future, this will @@ -157,13 +193,11 @@ LOGGING_API void setLogFormatter(LogFormatter* fmt); // // CHECK(some_condition) << "Something really bad happened!"; // -#define CHECK(condition) \ - LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " +#define CHECK(condition) LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " // A variant of CHECK() that also appends the errno message string at // the end of the log message before exiting the process. -#define PCHECK(condition) \ - PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " +#define PCHECK(condition) PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " // Define ENABLE_DLOG to 1 here if DLOG() statements should be compiled // as normal LOG() ones in the final binary. If 0, the statements will not @@ -224,17 +258,15 @@ LOGGING_API bool setDcheckLevel(bool enabled); // DLOG_IF() is like DLOG() for debug builds, and doesn't do anything for // release one. See DLOG() comments. -#define DLOG_IF(severity, condition) \ - LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), \ - LOG_MESSAGE_STREAM_COMPACT(severity)) +#define DLOG_IF(severity, condition) \ + LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), LOG_MESSAGE_STREAM_COMPACT(severity)) // DCHECK(condition) is used to perform CHECK() in debug builds, or if // the program called setDcheckLevel(true) previously. Note that it is // also possible to completely remove them from the final binary by // using the compiler flag -DENABLE_DCHECK=0 -#define DCHECK(condition) \ - LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) \ - << "Check failed: " #condition ". " +#define DCHECK(condition) \ + LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) << "Check failed: " #condition ". " // DPLOG() is like DLOG() that also appends the string message corresponding // to the current value of 'errno' just before the macro is called. This @@ -244,9 +276,8 @@ LOGGING_API bool setDcheckLevel(bool enabled); // DPLOG_IF() tests whether |condition| is true before calling // DPLOG(severity) -#define DPLOG_IF(severity, condition) \ - LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), \ - PLOG_MESSAGE_STREAM_COMPACT(severity)) +#define DPLOG_IF(severity, condition) \ + LOG_LAZY_EVAL(DLOG_IS_ON(severity) && (condition), PLOG_MESSAGE_STREAM_COMPACT(severity)) // Convenience class used hold a formatted string for logging reasons. // Usage example: @@ -254,31 +285,26 @@ LOGGING_API bool setDcheckLevel(bool enabled); // LOG(INFO) << LogString("There are %d items in this set", count); // class LOGGING_API LogString { -public: + public: LogString(const char* fmt, ...); const char* string() const { return mString.data(); } -private: + private: std::vector<char> mString; }; // Helper structure used to group the parameters of a LOG() or CHECK() // statement. -struct LOGGING_API LogParams { +struct LOGGING_API LogParams { LogParams() {} - LogParams(const char* a_file, - int a_lineno, - LogSeverity a_severity, - bool quiet = false) + LogParams(const char* a_file, int a_lineno, LogSeverity a_severity, bool quiet = false) : file(a_file), lineno(a_lineno), severity(a_severity), quiet(quiet) {} friend bool operator==(const LogParams& s1, const LogParams& s2) { - return s1.lineno == s2.lineno && s1.severity == s2.severity && - s1.quiet == s2.quiet && + return s1.lineno == s2.lineno && s1.severity == s2.severity && s1.quiet == s2.quiet && ((s1.file == nullptr && s2.file == nullptr) || // both null.. (s1.file != nullptr && s2.file != nullptr && - (s1.file == s2.file || - strcmp(s1.file, s2.file) == 0)) // or the same + (s1.file == s2.file || strcmp(s1.file, s2.file) == 0)) // or the same ); } @@ -289,16 +315,16 @@ struct LOGGING_API LogParams { }; class LOGGING_API LogstreamBuf : public std::streambuf { -public: + public: LogstreamBuf(); size_t size(); char* str(); -protected: + protected: int overflow(int c) override; -private: + private: std::vector<char> mLongString; char mStr[256]; }; @@ -311,7 +337,7 @@ private: // storing these in the stack of the functions were LOG() and CHECK() // statements are called. class LOGGING_API LogStream { -public: + public: LogStream(const char* file, int lineno, LogSeverity severity, bool quiet); ~LogStream() = default; @@ -325,21 +351,20 @@ public: const size_t size() { return mStreamBuf.size(); } const LogParams& params() const { return mParams; } -private: + private: LogParams mParams; LogstreamBuf mStreamBuf; std::ostream mStream; }; // Add your own types when needed: -LOGGING_API std::ostream& operator<<(std::ostream& stream, - const android::base::LogString& str); +LOGGING_API std::ostream& operator<<(std::ostream& stream, const android::base::LogString& str); LOGGING_API std::ostream& operator<<(std::ostream& stream, const std::string_view& str); // Helper class used to avoid compiler errors, see LOG_LAZY_EVAL for // more information. class LOGGING_API LogStreamVoidify { -public: + public: LogStreamVoidify() {} // This has to be an operator with a precedence lower than << but // higher than ?: @@ -355,17 +380,14 @@ public: // When destroyed, the message sends the final output to the appropriate // log (e.g. stderr by default). class LOGGING_API LogMessage { -public: + public: // To suppress printing file/line, set quiet = true. - LogMessage(const char* file, - int line, - LogSeverity severity, - bool quiet = false); + LogMessage(const char* file, int line, LogSeverity severity, bool quiet = false); ~LogMessage(); LogStream& stream() const { return *mStream; } -protected: + protected: // Avoid that each LOG() statement LogStream* mStream; }; @@ -376,17 +398,14 @@ protected: #define LOG_MESSAGE_COMPACT(severity) \ ::android::base::LogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity)) -#define LOG_MESSAGE_STREAM_COMPACT(severity) \ - LOG_MESSAGE_COMPACT(severity).stream() +#define LOG_MESSAGE_STREAM_COMPACT(severity) LOG_MESSAGE_COMPACT(severity).stream() // A variant of LogMessage for outputting user-visible messages to the console, // without debug information. -#define QLOG_MESSAGE_COMPACT(severity) \ - ::android::base::LogMessage(__FILE__, __LINE__, \ - LOG_SEVERITY_FROM(severity), true) +#define QLOG_MESSAGE_COMPACT(severity) \ + ::android::base::LogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity), true) -#define QLOG_MESSAGE_STREAM_COMPACT(severity) \ - QLOG_MESSAGE_COMPACT(severity).stream() +#define QLOG_MESSAGE_STREAM_COMPACT(severity) QLOG_MESSAGE_COMPACT(severity).stream() // A variant of LogMessage that saves the errno value on creation, // then restores it on destruction, as well as append a strerror() @@ -397,34 +416,29 @@ protected: // to restore the saved errno message after sending the message to the // LogOutput and deleting the stream. class LOGGING_API ErrnoLogMessage { -public: - ErrnoLogMessage(const char* file, - int line, - LogSeverity severity, - int errnoCode); + public: + ErrnoLogMessage(const char* file, int line, LogSeverity severity, int errnoCode); ~ErrnoLogMessage(); LogStream& stream() const { return *mStream; } -private: + private: LogStream* mStream; int mErrno; }; // Helper macros to avoid too much typing. -#define PLOG_MESSAGE_COMPACT(severity) \ - ::android::base::ErrnoLogMessage(__FILE__, __LINE__, \ - LOG_SEVERITY_FROM(severity), errno) +#define PLOG_MESSAGE_COMPACT(severity) \ + ::android::base::ErrnoLogMessage(__FILE__, __LINE__, LOG_SEVERITY_FROM(severity), errno) -#define PLOG_MESSAGE_STREAM_COMPACT(severity) \ - PLOG_MESSAGE_COMPACT(severity).stream() +#define PLOG_MESSAGE_STREAM_COMPACT(severity) PLOG_MESSAGE_COMPACT(severity).stream() namespace testing { // Abstract interface to the output where the log messages are sent. // IMPORTANT: Only use this for unit testing the log facility. class LOGGING_API LogOutput { -public: + public: LogOutput() {} virtual ~LogOutput() {} @@ -433,9 +447,7 @@ public: // when writing the message to a file. // Note: if |severity| is LOG_FATAL, this should also terminate the // process. - virtual void logMessage(const LogParams& params, - const char* message, - size_t message_len) = 0; + virtual void logMessage(const LogParams& params, const char* message, size_t message_len) = 0; // Set a new log output, and return pointer to the previous // implementation, which will be NULL for the default one. diff --git a/base/include/aemu/base/logging/LogFormatter.h b/base/include/aemu/base/logging/LogFormatter.h index 42e40ef..74e4585 100644 --- a/base/include/aemu/base/logging/LogFormatter.h +++ b/base/include/aemu/base/logging/LogFormatter.h @@ -14,10 +14,9 @@ #include <stdarg.h> // for va_list #include <stddef.h> // for size_t -#include <iosfwd> // for string + #include <memory> #include <mutex> // for mutex -#include <mutex> // for mutex #include <string> // for string #include "aemu/base/logging/Log.h" // for LogParams @@ -27,28 +26,21 @@ namespace base { // A LogFormatter formats a log line. class LogFormatter { -public: + public: virtual ~LogFormatter() = default; - // Mainly to facilitate unit testing.. - std::string format(const LogParams& params, const char* fmt, ...); - // Formats the given line, returning the string that should be printed, or // empty in case nothing should be printed. // // The last line should not be terminated by a newline. - virtual std::string format(const LogParams& params, - const char* fmt, - va_list args) = 0; + virtual std::string format(const LogParams& params, const std::string& line) = 0; }; // This simply logs the level, and message according to the following regex: // ^(VERBOSE|DEBUG|INFO|WARNING|ERROR|FATAL|UNKWOWN)\s+\| (.*) class SimpleLogFormatter : public LogFormatter { -public: - std::string format(const LogParams& params, - const char* fmt, - va_list args) override; + public: + std::string format(const LogParams& params, const std::string& line) override; }; // This simply logs the time, level and message according to the following @@ -56,10 +48,8 @@ public: // ^(\d+:\d+:\d+\.\d+)\s+(VERBOSE|DEBUG|INFO|WARNING|ERROR|FATAL|UNKWOWN)\s+\| // (.*) class SimpleLogWithTimeFormatter : public LogFormatter { -public: - std::string format(const LogParams& params, - const char* fmt, - va_list args) override; + public: + std::string format(const LogParams& params, const std::string& line) override; }; // This is a more verbose log line, which includes all we know: @@ -76,10 +66,16 @@ public: // group 4: File:Line // group 5: Log message class VerboseLogFormatter : public LogFormatter { -public: - std::string format(const LogParams& params, - const char* fmt, - va_list args) override; + public: + std::string format(const LogParams& params, const std::string& line) override; +}; + + +// Uses Google's standard logging prefix (go/logging#prefix) +// so that the logs are correctly parsed by standard tools (e.g. Analog) +class GoogleLogFormatter : public LogFormatter { + public: + std::string format(const LogParams& params, const std::string& line) override; }; // This formatter removes all duplicate lines, replacing them with an occurrence @@ -88,18 +84,16 @@ public: // WARNING: This logger does not neccessarily produces output, and buffers the // last line if it was a duplicate. class NoDuplicateLinesFormatter : public LogFormatter { -public: + public: NoDuplicateLinesFormatter(std::shared_ptr<LogFormatter> logger); // Will return "" when the last line was a duplicate. - std::string format(const LogParams& params, - const char* fmt, - va_list args) override; + std::string format(const LogParams& params, const std::string& line) override; -private: + private: std::shared_ptr<LogFormatter> mInner; std::string kEmpty{}; - char mPrevLog[4096] = {0}; + std::string mPrevLogLine; LogParams mPrevParams; int mDuplicates{0}; std::mutex mFormatMutex; diff --git a/base/include/aemu/base/logging/LogSeverity.h b/base/include/aemu/base/logging/LogSeverity.h index 34a2747..4984537 100644 --- a/base/include/aemu/base/logging/LogSeverity.h +++ b/base/include/aemu/base/logging/LogSeverity.h @@ -13,6 +13,9 @@ // limitations under the License. #pragma once +#include <stdint.h> + +#ifndef LOGGING_API #ifdef _MSC_VER #ifdef LOGGING_API_SHARED #define LOGGING_API __declspec(dllexport) @@ -22,6 +25,7 @@ #else #define LOGGING_API #endif +#endif #ifdef __cplusplus extern "C" { @@ -50,6 +54,28 @@ typedef enum LogSeverity { LOGGING_API LogSeverity getMinLogLevel(); LOGGING_API void setMinLogLevel(LogSeverity level); + +typedef enum { + kLogDefaultOptions = 0, + kLogEnableDuplicateFilter = 1, + kLogEnableTime = 1 << 2, + kLogEnableVerbose = 1 << 3, +} LoggingFlags; + +// Enable/disable verbose logs from the base/* family. +LOGGING_API void base_enable_verbose_logs(); +LOGGING_API void base_disable_verbose_logs(); + +LOGGING_API void verbose_enable(uint64_t tag); +LOGGING_API void verbose_disable(uint64_t tag); +LOGGING_API bool verbose_check(uint64_t tag); +LOGGING_API bool verbose_check_any(); +LOGGING_API void set_verbosity_mask(uint64_t mask); +LOGGING_API uint64_t get_verbosity_mask(); + +// Configure the logging framework. +LOGGING_API void base_configure_logs(LoggingFlags flags); + #ifdef __cplusplus } #endif diff --git a/base/include/aemu/base/logging/LogTags.h b/base/include/aemu/base/logging/LogTags.h index b9c2668..c870ef7 100644 --- a/base/include/aemu/base/logging/LogTags.h +++ b/base/include/aemu/base/logging/LogTags.h @@ -17,7 +17,7 @@ extern "C" { #endif #ifndef VERBOSE_TAG_LIST - #error "_VERBOSE_TAG(xx, yy) List not defined." +#error "_VERBOSE_TAG(xx, yy) List not defined." #endif #define _VERBOSE_TAG(x, y) VERBOSE_##x, @@ -26,25 +26,23 @@ typedef enum { } VerboseTag; #undef _VERBOSE_TAG - -#define VERBOSE_ENABLE(tag) verbose_enable((int64_t) VERBOSE_##tag) +#define VERBOSE_ENABLE(tag) verbose_enable((int64_t)VERBOSE_##tag) #define VERBOSE_DISABLE(tag) verbose_disable(int64_t) VERBOSE_##tag) -#define VERBOSE_CHECK(tag) verbose_check((int64_t) VERBOSE_##tag) +#define VERBOSE_CHECK(tag) verbose_check((int64_t)VERBOSE_##tag) #define VERBOSE_CHECK_ANY() verbose_check_any(); -#define VERBOSE_PRINT(tag, ...) \ - if (VERBOSE_CHECK(tag)) { \ - EMULOG(EMULATOR_LOG_DEBUG, ##__VA_ARGS__); \ +#define VERBOSE_PRINT(tag, ...) \ + if (VERBOSE_CHECK(tag)) { \ + dprint(__VA_ARGS__); \ } -#define VERBOSE_INFO(tag, ...) \ - if (VERBOSE_CHECK(tag)) { \ - EMULOG(EMULATOR_LOG_INFO, ##__VA_ARGS__); \ +#define VERBOSE_INFO(tag, ...) \ + if (VERBOSE_CHECK(tag)) { \ + dinfo(__VA_ARGS__); \ } #define VERBOSE_DPRINT(tag, ...) VERBOSE_PRINT(tag, __VA_ARGS__) - #ifdef __cplusplus } -#endif
\ No newline at end of file +#endif diff --git a/host-common/include/host-common/AndroidAsyncMessagePipe.h b/host-common/include/host-common/AndroidAsyncMessagePipe.h index 11956c2..69e1d08 100644 --- a/host-common/include/host-common/AndroidAsyncMessagePipe.h +++ b/host-common/include/host-common/AndroidAsyncMessagePipe.h @@ -13,24 +13,25 @@ // limitations under the License. #pragma once -#include <stddef.h> // for size_t +#include <stddef.h> + #include <array> -#include <cstdint> // for uint8_t, uint32_t -#include <functional> // for function -#include <list> // for list -#include <memory> // for unique_ptr -#include <mutex> // for recursive_mutex +#include <cstdint> +#include <functional> +#include <list> +#include <memory> +#include <mutex> #include <string> -#include <unordered_map> // for operator!=, unord... -#include <utility> // for move -#include <vector> // for vector - -#include "aemu/base/Optional.h" // for Optional -#include "aemu/base/files/Stream.h" // for Stream -#include "aemu/base/logging/CLog.h" // for dprint -#include "aemu/base/synchronization/Lock.h" // for AutoLock, Lock -#include "host-common/AndroidPipe.h" // for AndroidPipe, Andr... -#include "host-common/android_pipe_common.h" // for AndroidPipeBuffer +#include <unordered_map> +#include <utility> +#include <vector> + +#include "aemu/base/Optional.h" +#include "aemu/base/files/Stream.h" +#include "aemu/base/logging/Log.h" +#include "aemu/base/synchronization/Lock.h" +#include "host-common/AndroidPipe.h" +#include "host-common/android_pipe_common.h" // This is a utility class that can help implement message-based remote calls // between the host and guest, with optional out-of-band responses. diff --git a/host-common/include/host-common/MultiDisplay.h b/host-common/include/host-common/MultiDisplay.h index 492af61..909d840 100644 --- a/host-common/include/host-common/MultiDisplay.h +++ b/host-common/include/host-common/MultiDisplay.h @@ -130,9 +130,9 @@ public: // 0 for default Android display // 1-5 for Emulator UI // 6-10 for developer from rcControl - static const uint32_t s_displayIdInternalBegin = 6; - static const uint32_t s_maxNumMultiDisplay = 11; - static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB; + static constexpr uint32_t s_displayIdInternalBegin = 6; + static constexpr uint32_t s_maxNumMultiDisplay = 11; + static constexpr uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB; private: const QAndroidEmulatorWindowAgent* mWindowAgent; |