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