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 24 namespace panda::ecmascript { 25 #ifdef ENABLE_HILOG 26 namespace { ConvertToLevel(LogLevel hilogLevel)27 Level 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 GetHiLogLevel()54 LogLevel GetHiLogLevel() 55 { 56 for (int32_t level = LogLevel::LOG_LEVEL_MIN; level <= LogLevel::LOG_LEVEL_MAX; level++) { 57 if (HiLogIsLoggable(ARK_DOMAIN, 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 66 Level Log::level_ = Level::ERROR; 67 ComponentMark Log::components_ = Component::ALL; 68 ConvertFromRuntime(LOG_LEVEL level)69 Level 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 LevelToString(Level level)99 std::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 SetLogLevelFromString(const std::string & level)124 void 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 SetLogComponentFromString(const std::vector<std::string> & components)146 void 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 == "trace") { 179 components_ |= Component::TRACE; 180 continue; 181 } 182 } 183 } 184 PrintLogger(int32_t,int32_t level,const char *,const char *,const char * message)185 int32_t Log::PrintLogger(int32_t, int32_t level, const char *, const char *, const char *message) 186 { 187 switch (level) { 188 case Logger::PandaLog2MobileLog::VERBOSE: 189 LOG_ECMA(VERBOSE) << message; 190 break; 191 case Logger::PandaLog2MobileLog::DEBUG: 192 LOG_ECMA(DEBUG) << message; 193 break; 194 case Logger::PandaLog2MobileLog::INFO: 195 LOG_ECMA(INFO) << message; 196 break; 197 case Logger::PandaLog2MobileLog::WARN: 198 LOG_ECMA(WARN) << message; 199 break; 200 case Logger::PandaLog2MobileLog::ERROR: 201 LOG_ECMA(ERROR) << message; 202 break; 203 case Logger::PandaLog2MobileLog::FATAL: 204 LOG_ECMA(FATAL) << message; 205 break; 206 default: 207 LOG_ECMA(DEBUG) << message; 208 break; 209 } 210 return 0; 211 } 212 Initialize(const JSRuntimeOptions & options)213 void Log::Initialize(const JSRuntimeOptions &options) 214 { 215 // For ArkTS runtime log 216 if (options.WasSetLogFatal()) { 217 level_ = FATAL; 218 SetLogComponentFromString(options.GetLogFatal()); 219 } else if (options.WasSetLogError()) { 220 level_ = ERROR; 221 SetLogComponentFromString(options.GetLogError()); 222 } else if (options.WasSetLogWarning()) { 223 level_ = WARN; 224 SetLogComponentFromString(options.GetLogWarning()); 225 } else if (options.WasSetLogInfo()) { 226 level_ = INFO; 227 SetLogComponentFromString(options.GetLogInfo()); 228 } else if (options.WasSetLogDebug()) { 229 level_ = DEBUG; 230 SetLogComponentFromString(options.GetLogDebug()); 231 } else { 232 SetLogLevelFromString(options.GetLogLevel()); 233 SetLogComponentFromString(options.GetLogComponents()); 234 } 235 236 // For runtime core log 237 base_options::Options baseOptions(""); 238 baseOptions.SetLogLevel(options.GetLogLevel()); 239 baseOptions.SetLogComponents({ "all" }); 240 Logger::Initialize(baseOptions); 241 Logger::SetMobileLogPrintEntryPointByPtr(reinterpret_cast<void *>(Log::PrintLogger)); 242 } 243 244 #ifdef ENABLE_ANLOG 245 const char *tag = "ArkCompiler"; 246 template<> ~AndroidLog()247 PUBLIC_API AndroidLog<VERBOSE>::~AndroidLog() 248 { 249 __android_log_write(ANDROID_LOG_VERBOSE, tag, stream_.str().c_str()); 250 } 251 252 template<> ~AndroidLog()253 PUBLIC_API AndroidLog<DEBUG>::~AndroidLog() 254 { 255 __android_log_write(ANDROID_LOG_DEBUG, tag, stream_.str().c_str()); 256 } 257 258 template<> ~AndroidLog()259 PUBLIC_API AndroidLog<INFO>::~AndroidLog() 260 { 261 __android_log_write(ANDROID_LOG_INFO, tag, stream_.str().c_str()); 262 } 263 264 template<> ~AndroidLog()265 PUBLIC_API AndroidLog<WARN>::~AndroidLog() 266 { 267 __android_log_write(ANDROID_LOG_WARN, tag, stream_.str().c_str()); 268 } 269 270 template<> ~AndroidLog()271 PUBLIC_API AndroidLog<ERROR>::~AndroidLog() 272 { 273 __android_log_write(ANDROID_LOG_ERROR, tag, stream_.str().c_str()); 274 } 275 276 template<> ~AndroidLog()277 PUBLIC_API AndroidLog<FATAL>::~AndroidLog() 278 { 279 __android_log_write(ANDROID_LOG_FATAL, tag, stream_.str().c_str()); 280 std::abort(); 281 } 282 #endif 283 } // namespace panda::ecmascript