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