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#include "ecmascript/js_runtime_options.h" 17#include "ecmascript/log.h" 18#include "generated/base_options.h" 19 20#ifdef ENABLE_ANLOG 21#include <android/log.h> 22#endif 23 24namespace panda::ecmascript { 25#ifdef ENABLE_HILOG 26namespace { 27Level ConvertToLevel(LogLevel hilogLevel) 28{ 29 Level level = Level::ERROR; 30 std::string logLevel; 31 switch (hilogLevel) { 32 case LogLevel::LOG_INFO: 33 level = Level::INFO; 34 break; 35 case LogLevel::LOG_WARN: 36 level = Level::WARN; 37 break; 38 case LogLevel::LOG_ERROR: 39 level = Level::ERROR; 40 break; 41 case LogLevel::LOG_FATAL: 42 case LogLevel::LOG_LEVEL_MAX: 43 level = Level::FATAL; 44 break; 45 case LogLevel::LOG_DEBUG: 46 default: 47 level = Level::DEBUG; 48 break; 49 } 50 51 return level; 52} 53 54LogLevel GetHiLogLevel() 55{ 56 for (int32_t level = LogLevel::LOG_LEVEL_MIN; level <= LogLevel::LOG_LEVEL_MAX; level++) { 57 if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, static_cast<LogLevel>(level))) { 58 return static_cast<LogLevel>(level); 59 } 60 } 61 return LogLevel::LOG_LEVEL_MAX; 62} 63} // namespace 64#endif 65 66Level Log::level_ = Level::ERROR; 67ComponentMark Log::components_ = Component::ALL; 68 69Level Log::ConvertFromRuntime(LOG_LEVEL level) 70{ 71 Level logLevel = Level::INFO; 72 switch (level) { 73 case LOG_LEVEL::FOLLOW: 74#ifdef ENABLE_HILOG 75 logLevel = ConvertToLevel(GetHiLogLevel()); 76 break; 77#endif 78 case LOG_LEVEL::INFO: 79 logLevel = Level::INFO; 80 break; 81 case LOG_LEVEL::WARN: 82 logLevel = Level::WARN; 83 break; 84 case LOG_LEVEL::ERROR: 85 logLevel = Level::ERROR; 86 break; 87 case LOG_LEVEL::FATAL: 88 logLevel = Level::FATAL; 89 break; 90 case LOG_LEVEL::DEBUG: 91 default: 92 logLevel = Level::DEBUG; 93 break; 94 } 95 96 return logLevel; 97} 98 99std::string Log::LevelToString(Level level) 100{ 101 std::string logLevel; 102 switch (level) { 103 case Level::INFO: 104 logLevel = "info"; 105 break; 106 case Level::WARN: 107 logLevel = "warning"; 108 break; 109 case Level::ERROR: 110 logLevel = "error"; 111 break; 112 case Level::FATAL: 113 logLevel = "fatal"; 114 break; 115 case Level::DEBUG: 116 default: 117 logLevel = "debug"; 118 break; 119 } 120 121 return logLevel; 122} 123 124void Log::SetLogLevelFromString(const std::string& level) 125{ 126 if (level == "fatal") { 127 level_ = FATAL; 128 } 129 if (level == "error") { 130 level_ = ERROR; 131 } 132 if (level == "warning") { 133 level_ = WARN; 134 } 135 if (level == "info") { 136 level_ = INFO; 137 } 138 if (level == "debug") { 139 level_ = DEBUG; 140 } 141 if (level == "verbose") { 142 level_ = VERBOSE; 143 } 144} 145 146void Log::SetLogComponentFromString(const std::vector<std::string>& components) 147{ 148 components_ = Component::NONE; 149 for (const auto &component : components) { 150 if (component == "all") { 151 components_ = Component::ALL; 152 return; 153 } 154 if (component == "gc") { 155 components_ |= Component::GC; 156 continue; 157 } 158 if (component == "ecmascript") { 159 components_ |= Component::ECMASCRIPT; 160 continue; 161 } 162 if (component == "interpreter") { 163 components_ |= Component::INTERPRETER; 164 continue; 165 } 166 if (component == "debugger") { 167 components_ |= Component::DEBUGGER; 168 continue; 169 } 170 if (component == "compiler") { 171 components_ |= Component::COMPILER; 172 continue; 173 } 174 if (component == "builtins") { 175 components_ |= Component::BUILTINS; 176 continue; 177 } 178 if (component == "jit") { 179 components_ |= Component::JIT; 180 continue; 181 } 182 if (component == "baselinejit") { 183 components_ |= Component::BASELINEJIT; 184 continue; 185 } 186 if (component == "trace") { 187 components_ |= Component::TRACE; 188 continue; 189 } 190 if (component == "sa") { 191 components_ |= Component::SA; 192 continue; 193 } 194 } 195} 196 197int32_t Log::PrintLogger(int32_t, int32_t level, const char *, const char *, const char *message) 198{ 199 switch (level) { 200 case Logger::PandaLog2MobileLog::VERBOSE: 201 LOG_ECMA(VERBOSE) << message; 202 break; 203 case Logger::PandaLog2MobileLog::DEBUG: 204 LOG_ECMA(DEBUG) << message; 205 break; 206 case Logger::PandaLog2MobileLog::INFO: 207 LOG_ECMA(INFO) << message; 208 break; 209 case Logger::PandaLog2MobileLog::WARN: 210 LOG_ECMA(WARN) << message; 211 break; 212 case Logger::PandaLog2MobileLog::ERROR: 213 LOG_ECMA(ERROR) << message; 214 break; 215 case Logger::PandaLog2MobileLog::FATAL: 216 LOG_ECMA(FATAL) << message; 217 break; 218 default: 219 LOG_ECMA(DEBUG) << message; 220 break; 221 } 222 return 0; 223} 224 225void Log::Initialize(const JSRuntimeOptions &options) 226{ 227 // For ArkTS runtime log 228 if (options.WasSetLogFatal()) { 229 level_ = FATAL; 230 SetLogComponentFromString(options.GetLogFatal()); 231 } else if (options.WasSetLogError()) { 232 level_ = ERROR; 233 SetLogComponentFromString(options.GetLogError()); 234 } else if (options.WasSetLogWarning()) { 235 level_ = WARN; 236 SetLogComponentFromString(options.GetLogWarning()); 237 } else if (options.WasSetLogInfo()) { 238 level_ = INFO; 239 SetLogComponentFromString(options.GetLogInfo()); 240 } else if (options.WasSetLogDebug()) { 241 level_ = DEBUG; 242 SetLogComponentFromString(options.GetLogDebug()); 243 } else { 244 SetLogLevelFromString(options.GetLogLevel()); 245 SetLogComponentFromString(options.GetLogComponents()); 246 } 247 248 // For runtime core log 249 base_options::Options baseOptions(""); 250 baseOptions.SetLogLevel(options.GetLogLevel()); 251 baseOptions.SetLogComponents({ "all" }); 252 Logger::Initialize(baseOptions); 253 Logger::SetMobileLogPrintEntryPointByPtr(reinterpret_cast<void *>(Log::PrintLogger)); 254} 255 256#ifdef ENABLE_ANLOG 257const char *tag = "ArkCompiler"; 258template<> 259PUBLIC_API AndroidLog<VERBOSE>::~AndroidLog() 260{ 261 __android_log_write(ANDROID_LOG_VERBOSE, tag, stream_.str().c_str()); 262} 263 264template<> 265PUBLIC_API AndroidLog<DEBUG>::~AndroidLog() 266{ 267 __android_log_write(ANDROID_LOG_DEBUG, tag, stream_.str().c_str()); 268} 269 270template<> 271PUBLIC_API AndroidLog<INFO>::~AndroidLog() 272{ 273 __android_log_write(ANDROID_LOG_INFO, tag, stream_.str().c_str()); 274} 275 276template<> 277PUBLIC_API AndroidLog<WARN>::~AndroidLog() 278{ 279 __android_log_write(ANDROID_LOG_WARN, tag, stream_.str().c_str()); 280} 281 282template<> 283PUBLIC_API AndroidLog<ERROR>::~AndroidLog() 284{ 285 __android_log_write(ANDROID_LOG_ERROR, tag, stream_.str().c_str()); 286} 287 288template<> 289PUBLIC_API AndroidLog<FATAL>::~AndroidLog() 290{ 291 __android_log_write(ANDROID_LOG_FATAL, tag, stream_.str().c_str()); 292 std::abort(); 293} 294#endif 295} // namespace panda::ecmascript