• 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(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