Elliott Hughes | 42ee142 | 2011-09-06 12:33:32 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
Carl Shapiro | 6c21dc1 | 2011-06-20 15:20:52 -0700 | [diff] [blame] | 16 | |
David Sehr | c431b9d | 2018-03-02 12:01:51 -0800 | [diff] [blame] | 17 | #ifndef ART_LIBARTBASE_BASE_LOGGING_H_ |
| 18 | #define ART_LIBARTBASE_BASE_LOGGING_H_ |
Carl Shapiro | 6c21dc1 | 2011-06-20 15:20:52 -0700 | [diff] [blame] | 19 | |
Alex Light | b55ef65 | 2019-09-26 15:23:28 -0700 | [diff] [blame^] | 20 | #include <sstream> |
| 21 | #include <variant> |
| 22 | |
Andreas Gampe | 3fec9ac | 2016-09-13 10:47:28 -0700 | [diff] [blame] | 23 | #include "android-base/logging.h" |
David Sehr | 1979c64 | 2018-04-26 14:41:18 -0700 | [diff] [blame] | 24 | #include "macros.h" |
Carl Shapiro | 6c21dc1 | 2011-06-20 15:20:52 -0700 | [diff] [blame] | 25 | |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 26 | namespace art { |
| 27 | |
Andreas Gampe | 3fec9ac | 2016-09-13 10:47:28 -0700 | [diff] [blame] | 28 | // Make libbase's LogSeverity more easily available. |
Andreas Gampe | d6e54bb | 2016-09-26 14:07:57 -0700 | [diff] [blame] | 29 | using ::android::base::LogSeverity; |
| 30 | using ::android::base::ScopedLogSeverity; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 31 | |
David Sehr | f57589f | 2016-10-17 10:09:33 -0700 | [diff] [blame] | 32 | // Abort function. |
| 33 | using AbortFunction = void(const char*); |
| 34 | |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 35 | // The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code, |
| 36 | // and the "-verbose:" command line argument. |
| 37 | struct LogVerbosity { |
| 38 | bool class_linker; // Enabled with "-verbose:class". |
Mathieu Chartier | 66a5539 | 2016-02-19 10:25:39 -0800 | [diff] [blame] | 39 | bool collector; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 40 | bool compiler; |
Andreas Gampe | f3d1f94 | 2015-05-18 21:41:13 -0700 | [diff] [blame] | 41 | bool deopt; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 42 | bool gc; |
| 43 | bool heap; |
Mathieu Chartier | 765b2a0 | 2019-05-02 11:04:13 -0700 | [diff] [blame] | 44 | bool interpreter; // Enabled with "-verbose:interpreter". |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 45 | bool jdwp; |
Mathieu Chartier | e5f13e5 | 2015-02-24 09:37:21 -0800 | [diff] [blame] | 46 | bool jit; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 47 | bool jni; |
| 48 | bool monitor; |
Richard Uhler | 66d874d | 2015-01-15 09:37:19 -0800 | [diff] [blame] | 49 | bool oat; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 50 | bool profiler; |
| 51 | bool signals; |
Phil Wang | 751beff | 2015-08-28 15:17:15 +0800 | [diff] [blame] | 52 | bool simulator; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 53 | bool startup; |
| 54 | bool third_party_jni; // Enabled with "-verbose:third-party-jni". |
| 55 | bool threads; |
| 56 | bool verifier; |
Andreas Gampe | 92d7720 | 2017-12-06 20:49:00 -0800 | [diff] [blame] | 57 | bool verifier_debug; // Only works in debug builds. |
Mathieu Chartier | fbc3108 | 2016-01-24 11:59:56 -0800 | [diff] [blame] | 58 | bool image; |
Andreas Gampe | c7ed09b | 2016-04-25 20:08:55 -0700 | [diff] [blame] | 59 | bool systrace_lock_logging; // Enabled with "-verbose:sys-locks". |
Alex Light | 7233c7e | 2016-07-28 10:07:45 -0700 | [diff] [blame] | 60 | bool agents; |
Andreas Gampe | bec07a0 | 2017-04-11 13:48:37 -0700 | [diff] [blame] | 61 | bool dex; // Some dex access output etc. |
Nicolas Geoffray | 4ac0e15 | 2019-09-18 06:14:50 +0000 | [diff] [blame] | 62 | bool plugin; // Used by some plugins. |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 63 | }; |
| 64 | |
| 65 | // Global log verbosity setting, initialized by InitLogging. |
| 66 | extern LogVerbosity gLogVerbosity; |
| 67 | |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 68 | // Configure logging based on ANDROID_LOG_TAGS environment variable. |
| 69 | // We need to parse a string that looks like |
| 70 | // |
| 71 | // *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i |
| 72 | // |
| 73 | // The tag (or '*' for the global level) comes first, followed by a colon |
| 74 | // and a letter indicating the minimum priority level we're expected to log. |
| 75 | // This can be used to reveal or conceal logs with specific tags. |
David Sehr | f57589f | 2016-10-17 10:09:33 -0700 | [diff] [blame] | 76 | extern void InitLogging(char* argv[], AbortFunction& default_aborter); |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 77 | |
Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 78 | // Returns the command line used to invoke the current tool or null if InitLogging hasn't been |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 79 | // performed. |
| 80 | extern const char* GetCmdLine(); |
| 81 | |
Martin Stjernholm | ad909af | 2019-07-16 17:02:44 +0100 | [diff] [blame] | 82 | // The command used to start the ART runtime, such as "/apex/com.android.art/bin/dalvikvm". If |
Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 83 | // InitLogging hasn't been performed then just returns "art". |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 84 | extern const char* ProgramInvocationName(); |
| 85 | |
| 86 | // A short version of the command used to start the ART runtime, such as "dalvikvm". If InitLogging |
Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 87 | // hasn't been performed then just returns "art". |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 88 | extern const char* ProgramInvocationShortName(); |
| 89 | |
Andreas Gampe | 3fec9ac | 2016-09-13 10:47:28 -0700 | [diff] [blame] | 90 | class LogHelper { |
| 91 | public: |
| 92 | // A logging helper for logging a single line. Can be used with little stack. |
| 93 | static void LogLineLowStack(const char* file, |
| 94 | unsigned int line, |
| 95 | android::base::LogSeverity severity, |
| 96 | const char* msg); |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 97 | |
Andreas Gampe | 3fec9ac | 2016-09-13 10:47:28 -0700 | [diff] [blame] | 98 | private: |
| 99 | DISALLOW_ALLOCATION(); |
| 100 | DISALLOW_COPY_AND_ASSIGN(LogHelper); |
| 101 | }; |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 102 | |
David Sehr | 79e2607 | 2018-04-06 17:58:50 -0700 | [diff] [blame] | 103 | // Copy the contents of file_name to the log stream for level. |
| 104 | bool PrintFileToLog(const std::string& file_name, android::base::LogSeverity level); |
| 105 | |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 106 | // Is verbose logging enabled for the given module? Where the module is defined in LogVerbosity. |
| 107 | #define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module) |
| 108 | |
| 109 | // Variant of LOG that logs when verbose logging is enabled for a module. For example, |
| 110 | // VLOG(jni) << "A JNI operation was performed"; |
Andreas Gampe | 3fec9ac | 2016-09-13 10:47:28 -0700 | [diff] [blame] | 111 | #define VLOG(module) if (VLOG_IS_ON(module)) LOG(INFO) |
Ian Rogers | c7dd295 | 2014-10-21 23:31:19 -0700 | [diff] [blame] | 112 | |
Alex Light | b55ef65 | 2019-09-26 15:23:28 -0700 | [diff] [blame^] | 113 | // Holder to implement VLOG_STREAM. |
| 114 | class VlogMessage { |
| 115 | public: |
| 116 | // TODO Taken from android_base. |
| 117 | VlogMessage(bool enable, |
| 118 | const char* file, |
| 119 | unsigned int line, |
| 120 | ::android::base::LogId id, |
| 121 | ::android::base::LogSeverity severity, |
| 122 | const char* tag, |
| 123 | int error) |
| 124 | : msg_(std::in_place_type<std::ostringstream>) { |
| 125 | if (enable) { |
| 126 | msg_.emplace<::android::base::LogMessage>(file, line, id, severity, tag, error); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | std::ostream& stream() { |
| 131 | if (std::holds_alternative<std::ostringstream>(msg_)) { |
| 132 | return std::get<std::ostringstream>(msg_); |
| 133 | } else { |
| 134 | return std::get<::android::base::LogMessage>(msg_).stream(); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | private: |
| 139 | std::variant<::android::base::LogMessage, std::ostringstream> msg_; |
| 140 | }; |
| 141 | |
| 142 | // Return the stream associated with logging for the given module. NB Unlike VLOG function calls |
| 143 | // will still be performed. Output will be suppressed if the module is not on. |
| 144 | #define VLOG_STREAM(module) \ |
| 145 | ::art::VlogMessage(VLOG_IS_ON(module), \ |
| 146 | __FILE__, \ |
| 147 | __LINE__, \ |
| 148 | ::android::base::DEFAULT, \ |
| 149 | ::android::base::INFO, \ |
| 150 | _LOG_TAG_INTERNAL, \ |
| 151 | -1) \ |
| 152 | .stream() |
Andreas Gampe | 369810a | 2015-01-14 19:53:31 -0800 | [diff] [blame] | 153 | |
Elliott Hughes | 3ea7e99 | 2011-10-11 18:48:16 -0700 | [diff] [blame] | 154 | } // namespace art |
| 155 | |
David Sehr | c431b9d | 2018-03-02 12:01:51 -0800 | [diff] [blame] | 156 | #endif // ART_LIBARTBASE_BASE_LOGGING_H_ |