xref: /aosp_15_r20/art/libartbase/base/logging.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBARTBASE_BASE_LOGGING_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBARTBASE_BASE_LOGGING_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <sstream>
21*795d594fSAndroid Build Coastguard Worker #include <variant>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
24*795d594fSAndroid Build Coastguard Worker #include "macros.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker // Make libbase's LogSeverity more easily available.
29*795d594fSAndroid Build Coastguard Worker using ::android::base::LogSeverity;
30*795d594fSAndroid Build Coastguard Worker using ::android::base::ScopedLogSeverity;
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker // Abort function.
33*795d594fSAndroid Build Coastguard Worker using AbortFunction = void(const char*);
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker // The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
36*795d594fSAndroid Build Coastguard Worker // and the "-verbose:" command line argument.
37*795d594fSAndroid Build Coastguard Worker struct LogVerbosity {
38*795d594fSAndroid Build Coastguard Worker   bool class_linker;  // Enabled with "-verbose:class".
39*795d594fSAndroid Build Coastguard Worker   bool collector;
40*795d594fSAndroid Build Coastguard Worker   bool compiler;
41*795d594fSAndroid Build Coastguard Worker   bool deopt;
42*795d594fSAndroid Build Coastguard Worker   bool gc;
43*795d594fSAndroid Build Coastguard Worker   bool heap;
44*795d594fSAndroid Build Coastguard Worker   bool interpreter;  // Enabled with "-verbose:interpreter".
45*795d594fSAndroid Build Coastguard Worker   bool jdwp;
46*795d594fSAndroid Build Coastguard Worker   bool jit;
47*795d594fSAndroid Build Coastguard Worker   bool jni;
48*795d594fSAndroid Build Coastguard Worker   bool monitor;
49*795d594fSAndroid Build Coastguard Worker   bool oat;
50*795d594fSAndroid Build Coastguard Worker   bool profiler;
51*795d594fSAndroid Build Coastguard Worker   bool signals;
52*795d594fSAndroid Build Coastguard Worker   bool simulator;
53*795d594fSAndroid Build Coastguard Worker   bool startup;
54*795d594fSAndroid Build Coastguard Worker   bool third_party_jni;  // Enabled with "-verbose:third-party-jni".
55*795d594fSAndroid Build Coastguard Worker   bool threads;
56*795d594fSAndroid Build Coastguard Worker   bool verifier;
57*795d594fSAndroid Build Coastguard Worker   bool verifier_debug;   // Only works in debug builds.
58*795d594fSAndroid Build Coastguard Worker   bool image;
59*795d594fSAndroid Build Coastguard Worker   bool systrace_lock_logging;  // Enabled with "-verbose:systrace-locks".
60*795d594fSAndroid Build Coastguard Worker   bool agents;
61*795d594fSAndroid Build Coastguard Worker   bool dex;  // Some dex access output etc.
62*795d594fSAndroid Build Coastguard Worker   bool plugin;  // Used by some plugins.
63*795d594fSAndroid Build Coastguard Worker };
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker // Global log verbosity setting, initialized by InitLogging.
66*795d594fSAndroid Build Coastguard Worker extern LogVerbosity gLogVerbosity;
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker // Configure logging based on ANDROID_LOG_TAGS environment variable.
69*795d594fSAndroid Build Coastguard Worker // We need to parse a string that looks like
70*795d594fSAndroid Build Coastguard Worker //
71*795d594fSAndroid Build Coastguard Worker //      *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
72*795d594fSAndroid Build Coastguard Worker //
73*795d594fSAndroid Build Coastguard Worker // The tag (or '*' for the global level) comes first, followed by a colon
74*795d594fSAndroid Build Coastguard Worker // and a letter indicating the minimum priority level we're expected to log.
75*795d594fSAndroid Build Coastguard Worker // This can be used to reveal or conceal logs with specific tags.
76*795d594fSAndroid Build Coastguard Worker extern void InitLogging(char* argv[], AbortFunction& default_aborter);
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker // Returns the command line used to invoke the current tool or null if InitLogging hasn't been
79*795d594fSAndroid Build Coastguard Worker // performed.
80*795d594fSAndroid Build Coastguard Worker extern const char* GetCmdLine();
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker // The command used to start the ART runtime, such as "/apex/com.android.art/bin/dalvikvm". If
83*795d594fSAndroid Build Coastguard Worker // InitLogging hasn't been performed then just returns "art".
84*795d594fSAndroid Build Coastguard Worker extern const char* ProgramInvocationName();
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker // A short version of the command used to start the ART runtime, such as "dalvikvm". If InitLogging
87*795d594fSAndroid Build Coastguard Worker // hasn't been performed then just returns "art".
88*795d594fSAndroid Build Coastguard Worker extern const char* ProgramInvocationShortName();
89*795d594fSAndroid Build Coastguard Worker 
90*795d594fSAndroid Build Coastguard Worker class LogHelper {
91*795d594fSAndroid Build Coastguard Worker  public:
92*795d594fSAndroid Build Coastguard Worker   // A logging helper for logging a single line. Can be used with little stack.
93*795d594fSAndroid Build Coastguard Worker   static void LogLineLowStack(const char* file,
94*795d594fSAndroid Build Coastguard Worker                               unsigned int line,
95*795d594fSAndroid Build Coastguard Worker                               android::base::LogSeverity severity,
96*795d594fSAndroid Build Coastguard Worker                               const char* msg);
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker  private:
99*795d594fSAndroid Build Coastguard Worker   DISALLOW_ALLOCATION();
100*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(LogHelper);
101*795d594fSAndroid Build Coastguard Worker };
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker // Copy the contents of file_name to the log stream for level.
104*795d594fSAndroid Build Coastguard Worker bool PrintFileToLog(const std::string& file_name, android::base::LogSeverity level);
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker // Is verbose logging enabled for the given module? Where the module is defined in LogVerbosity.
107*795d594fSAndroid Build Coastguard Worker #define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker // Variant of LOG that logs when verbose logging is enabled for a module. For example,
110*795d594fSAndroid Build Coastguard Worker // VLOG(jni) << "A JNI operation was performed";
111*795d594fSAndroid Build Coastguard Worker #define VLOG(module) if (VLOG_IS_ON(module)) LOG(INFO)
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker // Holder to implement VLOG_STREAM.
114*795d594fSAndroid Build Coastguard Worker class VlogMessage {
115*795d594fSAndroid Build Coastguard Worker  public:
116*795d594fSAndroid Build Coastguard Worker   // TODO Taken from android_base.
VlogMessage(bool enable,const char * file,unsigned int line,::android::base::LogSeverity severity,const char * tag,int error)117*795d594fSAndroid Build Coastguard Worker   VlogMessage(bool enable,
118*795d594fSAndroid Build Coastguard Worker               const char* file,
119*795d594fSAndroid Build Coastguard Worker               unsigned int line,
120*795d594fSAndroid Build Coastguard Worker               ::android::base::LogSeverity severity,
121*795d594fSAndroid Build Coastguard Worker               const char* tag,
122*795d594fSAndroid Build Coastguard Worker               int error)
123*795d594fSAndroid Build Coastguard Worker       : msg_(std::in_place_type<std::ostringstream>) {
124*795d594fSAndroid Build Coastguard Worker     if (enable) {
125*795d594fSAndroid Build Coastguard Worker       msg_.emplace<::android::base::LogMessage>(file, line, severity, tag, error);
126*795d594fSAndroid Build Coastguard Worker     }
127*795d594fSAndroid Build Coastguard Worker   }
128*795d594fSAndroid Build Coastguard Worker 
stream()129*795d594fSAndroid Build Coastguard Worker   std::ostream& stream() {
130*795d594fSAndroid Build Coastguard Worker     if (std::holds_alternative<std::ostringstream>(msg_)) {
131*795d594fSAndroid Build Coastguard Worker       return std::get<std::ostringstream>(msg_);
132*795d594fSAndroid Build Coastguard Worker     } else {
133*795d594fSAndroid Build Coastguard Worker       return std::get<::android::base::LogMessage>(msg_).stream();
134*795d594fSAndroid Build Coastguard Worker     }
135*795d594fSAndroid Build Coastguard Worker   }
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker  private:
138*795d594fSAndroid Build Coastguard Worker   std::variant<::android::base::LogMessage, std::ostringstream> msg_;
139*795d594fSAndroid Build Coastguard Worker };
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker // Return the stream associated with logging for the given module. NB Unlike VLOG function calls
142*795d594fSAndroid Build Coastguard Worker // will still be performed. Output will be suppressed if the module is not on.
143*795d594fSAndroid Build Coastguard Worker #define VLOG_STREAM(module)                    \
144*795d594fSAndroid Build Coastguard Worker   ::art::VlogMessage(VLOG_IS_ON(module),       \
145*795d594fSAndroid Build Coastguard Worker                      __FILE__,                 \
146*795d594fSAndroid Build Coastguard Worker                      __LINE__,                 \
147*795d594fSAndroid Build Coastguard Worker                      ::android::base::INFO,    \
148*795d594fSAndroid Build Coastguard Worker                      _LOG_TAG_INTERNAL,        \
149*795d594fSAndroid Build Coastguard Worker                      -1)                       \
150*795d594fSAndroid Build Coastguard Worker       .stream()
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker // Check whether an implication holds between x and y, LOG(FATAL) if not. The value
153*795d594fSAndroid Build Coastguard Worker // of the expressions x and y is evaluated once. Extra logging can be appended
154*795d594fSAndroid Build Coastguard Worker // using << after. For example:
155*795d594fSAndroid Build Coastguard Worker //
156*795d594fSAndroid Build Coastguard Worker //     CHECK_IMPLIES(1==1, 0==1) results in
157*795d594fSAndroid Build Coastguard Worker //       "Check failed: 1==1 (true) implies 0==1 (false) ".
158*795d594fSAndroid Build Coastguard Worker // clang-format off
159*795d594fSAndroid Build Coastguard Worker #define CHECK_IMPLIES(LHS, RHS)                                                                  \
160*795d594fSAndroid Build Coastguard Worker   LIKELY(!(LHS) || (RHS)) || ABORT_AFTER_LOG_FATAL_EXPR(false) ||                                \
161*795d594fSAndroid Build Coastguard Worker       ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, \
162*795d594fSAndroid Build Coastguard Worker                                   -1)                                                            \
163*795d594fSAndroid Build Coastguard Worker               .stream()                                                                          \
164*795d594fSAndroid Build Coastguard Worker       << "Check failed: " #LHS << " (true) implies " #RHS << " (false)"
165*795d594fSAndroid Build Coastguard Worker // clang-format on
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker #define DCHECK_IMPLIES(a, b) \
168*795d594fSAndroid Build Coastguard Worker   if (::android::base::kEnableDChecks) CHECK_IMPLIES(a, b)
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker }  // namespace art
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker #endif  // ART_LIBARTBASE_BASE_LOGGING_H_
173