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