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 ECMASCRIPT_LOG_H 17 #define ECMASCRIPT_LOG_H 18 19 #include <cstdint> 20 #include <iostream> 21 #include <sstream> 22 23 #include "ecmascript/common.h" 24 #ifdef ENABLE_HILOG 25 #include "hilog/log.h" 26 #endif 27 28 enum Level { 29 VERBOSE, 30 DEBUG, 31 INFO, 32 WARN, 33 ERROR, 34 FATAL, 35 }; 36 37 using ComponentMark = uint64_t; 38 enum Component { 39 NONE = 0ULL, 40 GC = 1ULL << 0ULL, 41 INTERPRETER = 1ULL << 1ULL, 42 COMPILER = 1ULL << 2ULL, 43 DEBUGGER = 1ULL << 3ULL, 44 ECMASCRIPT = 1ULL << 4ULL, 45 BUILTINS = 1ULL << 5ULL, 46 NO_TAG = 0xFFFFFFFFULL >> 1ULL, 47 ALL = 0xFFFFFFFFULL, 48 }; 49 50 namespace panda::ecmascript { 51 #ifdef ENABLE_HILOG 52 constexpr static unsigned int ARK_DOMAIN = 0xD003F00; 53 constexpr static auto TAG = "ArkCompiler"; 54 constexpr static OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, ARK_DOMAIN, TAG}; 55 56 #if ECMASCRIPT_ENABLE_VERBOSE_LEVEL_LOG 57 // print Debug level log if enable Verbose log 58 #define LOG_VERBOSE LOG_DEBUG 59 #else 60 #define LOG_VERBOSE LOG_LEVEL_MIN 61 #endif 62 63 static bool LOGGABLE_VERBOSE = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_VERBOSE); 64 static bool LOGGABLE_DEBUG = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_DEBUG); 65 static bool LOGGABLE_INFO = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_INFO); 66 static bool LOGGABLE_WARN = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_WARN); 67 static bool LOGGABLE_ERROR = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_ERROR); 68 static bool LOGGABLE_FATAL = HiLogIsLoggable(ARK_DOMAIN, TAG, LOG_FATAL); 69 #endif // ENABLE_HILOG 70 71 class JSRuntimeOptions; 72 class PUBLIC_API Log { 73 public: 74 static void Initialize(const JSRuntimeOptions &options); LogIsLoggable(Level level,Component component)75 static inline bool LogIsLoggable(Level level, Component component) 76 { 77 return (level >= level_) && ((components_ & component) != 0ULL); 78 } GetComponentStr(Component component)79 static inline std::string GetComponentStr(Component component) 80 { 81 switch (component) 82 { 83 case Component::NO_TAG: 84 return ""; 85 case Component::GC: 86 return "[gc] "; 87 case Component::ECMASCRIPT: 88 return "[ecmascript] "; 89 case Component::INTERPRETER: 90 return "[interpreter] "; 91 case Component::DEBUGGER: 92 return "[debugger] "; 93 case Component::COMPILER: 94 return "[compiler] "; 95 case Component::BUILTINS: 96 return "[builtins] "; 97 case Component::ALL: 98 return "[default] "; 99 default: 100 return "[unknown] "; 101 } 102 } 103 104 private: 105 static void SetLogLevelFromString(const std::string& level); 106 static void SetLogComponentFromString(const std::vector<std::string>& components); 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) { 125 // print nothing 126 } else if constexpr (level == LOG_DEBUG) { 127 OHOS::HiviewDFX::HiLog::Debug(LABEL, "%{public}s", stream_.str().c_str()); 128 } else if constexpr (level == LOG_INFO) { 129 OHOS::HiviewDFX::HiLog::Info(LABEL, "%{public}s", stream_.str().c_str()); 130 } else if constexpr (level == LOG_WARN) { 131 OHOS::HiviewDFX::HiLog::Warn(LABEL, "%{public}s", stream_.str().c_str()); 132 } else if constexpr (level == LOG_ERROR) { 133 OHOS::HiviewDFX::HiLog::Error(LABEL, "%{public}s", stream_.str().c_str()); 134 } else { 135 OHOS::HiviewDFX::HiLog::Fatal(LABEL, "%{public}s", stream_.str().c_str()); 136 std::abort(); 137 } 138 } 139 template<class type> 140 std::ostream &operator <<(type input) 141 { 142 stream_ << input; 143 return stream_; 144 } 145 146 private: 147 std::ostringstream stream_; 148 }; 149 #elif defined(PANDA_TARGET_ANDROID) // PANDA_TARGET_ANDROID 150 template<Level level> 151 class PUBLIC_API AndroidLog { 152 public: AndroidLog()153 AndroidLog() 154 { 155 std::string str = "[default] "; 156 stream_ << str; 157 } 158 ~AndroidLog(); 159 160 template<class type> 161 std::ostream &operator <<(type input) 162 { 163 stream_ << input; 164 return stream_; 165 } 166 167 private: 168 std::ostringstream stream_; 169 }; 170 #else 171 template<Level level, Component component> 172 class StdLog { 173 public: StdLog()174 StdLog() 175 { 176 std::string str = Log::GetComponentStr(component); 177 stream_ << str; 178 } ~StdLog()179 ~StdLog() 180 { 181 if constexpr (level == FATAL || level == ERROR) { 182 std::cerr << stream_.str().c_str() << std::endl; 183 } else { 184 std::cout << stream_.str().c_str() << std::endl; 185 } 186 187 if constexpr (level == FATAL) { 188 std::abort(); 189 } 190 } 191 192 template<class type> 193 std::ostream &operator <<(type input) 194 { 195 stream_ << input; 196 return stream_; 197 } 198 199 private: 200 std::ostringstream stream_; 201 }; 202 #endif 203 204 #if defined(ENABLE_HILOG) 205 #define ARK_LOG(level, component) panda::ecmascript::LOGGABLE_##level && \ 206 panda::ecmascript::HiLog<LOG_##level, (component)>() 207 #elif defined(PANDA_TARGET_ANDROID) 208 #define ARK_LOG(level, component) panda::ecmascript::AndroidLog<(level)>() 209 #else 210 #define ARK_LOG(level, component) panda::ecmascript::Log::LogIsLoggable(level, component) && \ 211 panda::ecmascript::StdLog<(level), (component)>() 212 #endif 213 } // namespace panda::ecmascript 214 #endif // ECMASCRIPT_LOG_H 215