• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(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 
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 == "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 
PrintLogger(int32_t,int32_t level,const char *,const char *,const char * message)197 int32_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 
Initialize(const JSRuntimeOptions & options)225 void 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
257 const char *tag = "ArkCompiler";
258 template<>
~AndroidLog()259 PUBLIC_API AndroidLog<VERBOSE>::~AndroidLog()
260 {
261     __android_log_write(ANDROID_LOG_VERBOSE, tag, stream_.str().c_str());
262 }
263 
264 template<>
~AndroidLog()265 PUBLIC_API AndroidLog<DEBUG>::~AndroidLog()
266 {
267     __android_log_write(ANDROID_LOG_DEBUG, tag, stream_.str().c_str());
268 }
269 
270 template<>
~AndroidLog()271 PUBLIC_API AndroidLog<INFO>::~AndroidLog()
272 {
273     __android_log_write(ANDROID_LOG_INFO, tag, stream_.str().c_str());
274 }
275 
276 template<>
~AndroidLog()277 PUBLIC_API AndroidLog<WARN>::~AndroidLog()
278 {
279     __android_log_write(ANDROID_LOG_WARN, tag, stream_.str().c_str());
280 }
281 
282 template<>
~AndroidLog()283 PUBLIC_API AndroidLog<ERROR>::~AndroidLog()
284 {
285     __android_log_write(ANDROID_LOG_ERROR, tag, stream_.str().c_str());
286 }
287 
288 template<>
~AndroidLog()289 PUBLIC_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