• 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 == "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