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 == "pgo") {
163 components_ |= Component::PGO;
164 continue;
165 }
166 if (component == "interpreter") {
167 components_ |= Component::INTERPRETER;
168 continue;
169 }
170 if (component == "debugger") {
171 components_ |= Component::DEBUGGER;
172 continue;
173 }
174 if (component == "compiler") {
175 components_ |= Component::COMPILER;
176 continue;
177 }
178 if (component == "builtins") {
179 components_ |= Component::BUILTINS;
180 continue;
181 }
182 if (component == "jit") {
183 components_ |= Component::JIT;
184 continue;
185 }
186 if (component == "baselinejit") {
187 components_ |= Component::BASELINEJIT;
188 continue;
189 }
190 if (component == "trace") {
191 components_ |= Component::TRACE;
192 continue;
193 }
194 if (component == "sa") {
195 components_ |= Component::SA;
196 continue;
197 }
198 }
199 }
200
PrintLogger(int32_t,int32_t level,const char *,const char *,const char * message)201 int32_t Log::PrintLogger(int32_t, int32_t level, const char *, const char *, const char *message)
202 {
203 switch (level) {
204 case Logger::PandaLog2MobileLog::VERBOSE:
205 LOG_ECMA(VERBOSE) << message;
206 break;
207 case Logger::PandaLog2MobileLog::DEBUG:
208 LOG_ECMA(DEBUG) << message;
209 break;
210 case Logger::PandaLog2MobileLog::INFO:
211 LOG_ECMA(INFO) << message;
212 break;
213 case Logger::PandaLog2MobileLog::WARN:
214 LOG_ECMA(WARN) << message;
215 break;
216 case Logger::PandaLog2MobileLog::ERROR:
217 LOG_ECMA(ERROR) << message;
218 break;
219 case Logger::PandaLog2MobileLog::FATAL:
220 LOG_ECMA(FATAL) << message;
221 break;
222 default:
223 LOG_ECMA(DEBUG) << message;
224 break;
225 }
226 return 0;
227 }
228
Initialize(const JSRuntimeOptions & options)229 void Log::Initialize(const JSRuntimeOptions &options)
230 {
231 // For ArkTS runtime log
232 if (options.WasSetLogFatal()) {
233 level_ = FATAL;
234 SetLogComponentFromString(options.GetLogFatal());
235 } else if (options.WasSetLogError()) {
236 level_ = ERROR;
237 SetLogComponentFromString(options.GetLogError());
238 } else if (options.WasSetLogWarning()) {
239 level_ = WARN;
240 SetLogComponentFromString(options.GetLogWarning());
241 } else if (options.WasSetLogInfo()) {
242 level_ = INFO;
243 SetLogComponentFromString(options.GetLogInfo());
244 } else if (options.WasSetLogDebug()) {
245 level_ = DEBUG;
246 SetLogComponentFromString(options.GetLogDebug());
247 } else {
248 SetLogLevelFromString(options.GetLogLevel());
249 SetLogComponentFromString(options.GetLogComponents());
250 }
251
252 // For runtime core log
253 base_options::Options baseOptions("");
254 baseOptions.SetLogLevel(options.GetLogLevel());
255 baseOptions.SetLogComponents({ "all" });
256 Logger::Initialize(baseOptions);
257 Logger::SetMobileLogPrintEntryPointByPtr(reinterpret_cast<void *>(Log::PrintLogger));
258 }
259
260 #ifdef ENABLE_ANLOG
261 const char *tag = "ArkCompiler";
262 template<>
~AndroidLog()263 PUBLIC_API AndroidLog<VERBOSE>::~AndroidLog()
264 {
265 __android_log_write(ANDROID_LOG_VERBOSE, tag, stream_.str().c_str());
266 }
267
268 template<>
~AndroidLog()269 PUBLIC_API AndroidLog<DEBUG>::~AndroidLog()
270 {
271 __android_log_write(ANDROID_LOG_DEBUG, tag, stream_.str().c_str());
272 }
273
274 template<>
~AndroidLog()275 PUBLIC_API AndroidLog<INFO>::~AndroidLog()
276 {
277 __android_log_write(ANDROID_LOG_INFO, tag, stream_.str().c_str());
278 }
279
280 template<>
~AndroidLog()281 PUBLIC_API AndroidLog<WARN>::~AndroidLog()
282 {
283 __android_log_write(ANDROID_LOG_WARN, tag, stream_.str().c_str());
284 }
285
286 template<>
~AndroidLog()287 PUBLIC_API AndroidLog<ERROR>::~AndroidLog()
288 {
289 __android_log_write(ANDROID_LOG_ERROR, tag, stream_.str().c_str());
290 }
291
292 template<>
~AndroidLog()293 PUBLIC_API AndroidLog<FATAL>::~AndroidLog()
294 {
295 __android_log_write(ANDROID_LOG_FATAL, tag, stream_.str().c_str());
296 std::abort();
297 }
298 #endif
299 } // namespace panda::ecmascript