1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 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 16 #ifndef COMMON_COMPONENTS_LOG_LOG_H 17 #define COMMON_COMPONENTS_LOG_LOG_H 18 19 #include <cstdint> 20 #include <string> 21 22 #include "common_components/log/log_base.h" 23 #include "common_components/base/time_utils.h" 24 #include "securec.h" 25 26 #ifdef ENABLE_HILOG 27 #if defined(__clang__) 28 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 29 #elif defined(__GNUC__) 30 #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 31 #endif 32 #include "hilog/log.h" 33 #endif 34 #undef LOG_DOMAIN 35 #define LOG_DOMAIN 0xD003F00 36 #undef LOG_TAG 37 #define LOG_TAG "ArkCompiler" 38 39 #if defined(ENABLE_HITRACE) 40 #include "hitrace_meter.h" 41 42 #define OHOS_HITRACE(level, name, customArgs) HITRACE_METER_NAME_EX(level, HITRACE_TAG_ARK, name, customArgs) 43 #define OHOS_HITRACE_START(level, name, customArgs) StartTraceEx(level, HITRACE_TAG_ARK, name, customArgs) 44 #define OHOS_HITRACE_FINISH(level) FinishTraceEx(level, HITRACE_TAG_ARK) 45 #define OHOS_HITRACE_COUNT(level, name, count) CountTraceEx(level, HITRACE_TAG_ARK, name, count) 46 #else 47 #define OHOS_HITRACE(level, name, customArgs) 48 #define OHOS_HITRACE_START(level, name, customArgs) 49 #define OHOS_HITRACE_FINISH(level) 50 #define OHOS_HITRACE_COUNT(level, name, count) 51 #endif 52 53 namespace common { 54 class PUBLIC_API Log { 55 public: 56 static void Initialize(const LogOptions &options); LogIsLoggable(Level level,Component component)57 static inline bool LogIsLoggable(Level level, Component component) 58 { 59 switch (component) //LCOV_EXCL_BR_LINE 60 { 61 case Component::SA: //LCOV_EXCL_BR_LINE 62 return ((components_ & static_cast<ComponentMark>(component)) != 0ULL); 63 default: //LCOV_EXCL_BR_LINE 64 return (level >= level_) && ((components_ & static_cast<ComponentMark>(component)) != 0ULL); 65 } 66 } GetComponentStr(Component component)67 static inline std::string GetComponentStr(Component component) 68 { 69 switch (component) //LCOV_EXCL_BR_LINE 70 { 71 case Component::NO_TAG: //LCOV_EXCL_BR_LINE 72 return ""; 73 case Component::GC: //LCOV_EXCL_BR_LINE 74 return "[gc] "; 75 case Component::ECMASCRIPT: //LCOV_EXCL_BR_LINE 76 return "[ecmascript] "; 77 case Component::PGO: //LCOV_EXCL_BR_LINE 78 return "[pgo] "; 79 case Component::INTERPRETER: //LCOV_EXCL_BR_LINE 80 return "[interpreter] "; 81 case Component::DEBUGGER: //LCOV_EXCL_BR_LINE 82 return "[debugger] "; 83 case Component::COMPILER: //LCOV_EXCL_BR_LINE 84 return "[compiler] "; 85 case Component::BUILTINS: //LCOV_EXCL_BR_LINE 86 return "[builtins] "; 87 case Component::TRACE: //LCOV_EXCL_BR_LINE 88 return "[trace] "; 89 case Component::JIT: //LCOV_EXCL_BR_LINE 90 return "[jit] "; 91 case Component::BASELINEJIT: //LCOV_EXCL_BR_LINE 92 return "[baselinejit] "; 93 case Component::SA: //LCOV_EXCL_BR_LINE 94 return "[sa] "; 95 case Component::COMMON: //LCOV_EXCL_BR_LINE 96 return "[common] "; 97 case Component::ALL: //LCOV_EXCL_BR_LINE 98 return "[default] "; 99 default: //LCOV_EXCL_BR_LINE 100 return "[unknown] "; 101 } 102 } 103 static std::string LevelToString(Level level); 104 static Level ConvertFromRuntime(LOG_LEVEL level); 105 106 private: 107 static int32_t PrintLogger(int32_t, int32_t level, const char *, const char *, const char *message); 108 109 static Level level_; 110 static ComponentMark components_; 111 }; 112 113 #if defined(ENABLE_HILOG) 114 template<LogLevel level, Component component> 115 class HiLog { 116 public: HiLog()117 HiLog() 118 { 119 std::string str = Log::GetComponentStr(component); 120 stream_ << str; 121 } ~HiLog()122 ~HiLog() 123 { 124 if constexpr (level == LOG_LEVEL_MIN) { //LCOV_EXCL_BR_LINE 125 // print nothing 126 } else if constexpr (level == LOG_DEBUG) { //LCOV_EXCL_BR_LINE 127 HILOG_DEBUG(LOG_CORE, "%{public}s", stream_.str().c_str()); 128 } else if constexpr (level == LOG_INFO) { //LCOV_EXCL_BR_LINE 129 HILOG_INFO(LOG_CORE, "%{public}s", stream_.str().c_str()); 130 } else if constexpr (level == LOG_WARN) { //LCOV_EXCL_BR_LINE 131 HILOG_WARN(LOG_CORE, "%{public}s", stream_.str().c_str()); 132 } else if constexpr (level == LOG_ERROR) { //LCOV_EXCL_BR_LINE 133 HILOG_ERROR(LOG_CORE, "%{public}s", stream_.str().c_str()); 134 } else { //LCOV_EXCL_BR_LINE 135 HILOG_FATAL(LOG_CORE, "%{public}s", stream_.str().c_str()); 136 if (level == LOG_FATAL) { //LCOV_EXCL_BR_LINE 137 std::abort(); 138 } 139 } 140 } 141 template<class type> 142 std::ostream &operator <<(type input) 143 { 144 stream_ << input; 145 return stream_; 146 } 147 148 private: 149 std::ostringstream stream_; 150 }; 151 #elif defined(ENABLE_ANLOG) // ENABLE_ANLOG 152 template<Level level> 153 class PUBLIC_API AndroidLog { 154 public: AndroidLog()155 AndroidLog() 156 { 157 std::string str = "[default] "; 158 stream_ << str; 159 } 160 ~AndroidLog(); 161 162 template<class type> 163 std::ostream &operator <<(type input) 164 { 165 stream_ << input; 166 return stream_; 167 } 168 169 private: 170 std::ostringstream stream_; 171 }; 172 #else 173 template<Level level, Component component> 174 class StdLog { 175 public: StdLog()176 StdLog() 177 { 178 std::string str = Log::GetComponentStr(component); 179 stream_ << str; 180 } ~StdLog()181 ~StdLog() 182 { 183 if constexpr (level >= Level::ERROR) { //LCOV_EXCL_BR_LINE 184 std::cerr << stream_.str().c_str() << std::endl; 185 } else { //LCOV_EXCL_BR_LINE 186 std::cout << stream_.str().c_str() << std::endl; 187 } 188 189 if constexpr (level == Level::FATAL) { //LCOV_EXCL_BR_LINE 190 std::abort(); 191 } 192 } 193 194 template<class type> 195 std::ostream &operator <<(type input) 196 { 197 stream_ << input; 198 return stream_; 199 } 200 201 private: 202 std::ostringstream stream_; 203 }; 204 #endif 205 206 #if defined(ENABLE_HILOG) 207 #define ARK_LOG(level, component) common::Log::LogIsLoggable(Level::level, component) && \ 208 common::HiLog<LOG_##level, (component)>() 209 #elif defined(ENABLE_ANLOG) 210 #define ARK_LOG(level, component) common::AndroidLog<(Level::level)>() 211 #else 212 #if defined(OHOS_UNIT_TEST) 213 #define ARK_LOG(level, component) ((Level::level >= Level::INFO) || \ 214 common::Log::LogIsLoggable(Level::level, component)) && \ 215 common::StdLog<(Level::level), (component)>() 216 #else 217 #define ARK_LOG(level, component) common::Log::LogIsLoggable(Level::level, component) && \ 218 common::StdLog<(Level::level), (component)>() 219 #endif 220 #endif 221 222 #define LOG_COMMON(level) ARK_LOG(level, Component::COMMON) 223 #define LOG_GC(level) ARK_LOG(level, Component::GC) 224 225 #define LOGD_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(DEBUG) 226 #define LOGI_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(INFO) 227 #define LOGW_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(WARN) 228 #define LOGE_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(ERROR) 229 #define LOGF_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(ERROR) << "Check failed: " << #cond && LOG_COMMON(FATAL) 230 231 #define CHECKF(cond) (UNLIKELY_CC(!(cond))) && LOG_COMMON(FATAL) << "Check failed: " << #cond 232 #define LOGF_CHECK(cond) LOGF_IF(!(cond)) 233 234 #ifndef NDEBUG 235 #define DLOG(type, format...) LOG_GC(DEBUG) << FormatLog(format) 236 #else // NDEBUG 237 #define DLOG(type, format...) (void)(0) 238 #endif // NDEBUG 239 #define VLOG(level, format...) LOG_GC(level) << FormatLog(format) 240 241 #define COMMON_PHASE_TIMER(...) Timer ARK_pt_##__LINE__(__VA_ARGS__) 242 243 #ifndef NDEBUG 244 #define ASSERT_LOGF(cond, msg) LOGF_IF(!(cond)) << (msg) 245 #else // NDEBUG 246 #define ASSERT_LOGF(cond, msg) 247 #endif // NDEBUG 248 249 #define CHECK_CALL(call, args, what) \ 250 do { \ 251 int rc = call args; \ 252 if (UNLIKELY_CC(rc != 0)) { \ 253 errno = rc; \ 254 /* LCOV_EXCL_BR_LINE */ \ 255 LOG_COMMON(FATAL) << #call << \ 256 " failed for " << \ 257 (what) <<" reason " << \ 258 strerror(errno) << \ 259 " return " << errno; \ 260 } \ 261 } while (false) //LCOV_EXCL_BR_LINE 262 263 std::string Pretty(uint64_t number) noexcept; 264 std::string PrettyOrderInfo(uint64_t number, const char* unit); 265 std::string PrettyOrderMathNano(uint64_t number, const char* unit); 266 std::string FormatLogMessage(const char* format, va_list agrs) noexcept; 267 std::string FormatLog(const char* format, ...) noexcept; 268 class Timer { 269 public: Timer(const std::string pName)270 explicit Timer(const std::string pName) : name_(pName) 271 { 272 if (common::Log::LogIsLoggable(Level::DEBUG, Component::GC)) { 273 startTime_ = TimeUtil::MicroSeconds(); 274 } 275 } 276 ~Timer()277 ~Timer() 278 { 279 if (common::Log::LogIsLoggable(Level::DEBUG, Component::GC)) { 280 uint64_t stopTime = TimeUtil::MicroSeconds(); 281 uint64_t diffTime = stopTime - startTime_; 282 VLOG(DEBUG, "%s time: %sus", name_.c_str(), Pretty(diffTime).c_str()); 283 } 284 } 285 286 private: 287 std::string name_; 288 uint64_t startTime_ = 0; 289 }; 290 } // namespace common 291 #endif // COMMON_COMPONENTS_LOG_LOG_H 292