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