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