• 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 #ifndef ECMASCRIPT_LOG_H
17 #define ECMASCRIPT_LOG_H
18 
19 #include <cstdint>
20 #include <iostream>
21 #include <sstream>
22 
23 #include "ecmascript/common.h"
24 #include "ecmascript/napi/include/jsnapi.h"
25 
26 #ifdef ENABLE_HILOG
27 #include "hilog/log.h"
28 #endif
29 
30 using LOG_LEVEL = panda::RuntimeOption::LOG_LEVEL;
31 enum Level {
32     VERBOSE,
33     DEBUG,
34     INFO,
35     WARN,
36     ERROR,
37     FATAL,
38 };
39 
40 using ComponentMark = uint64_t;
41 enum Component {
42     NONE = 0ULL,
43     GC = 1ULL << 0ULL,
44     INTERPRETER = 1ULL << 1ULL,
45     COMPILER = 1ULL << 2ULL,
46     DEBUGGER = 1ULL << 3ULL,
47     ECMASCRIPT = 1ULL << 4ULL,
48     BUILTINS = 1ULL << 5ULL,
49     TRACE = 1ULL << 6ULL,
50     NO_TAG = 0xFFFFFFFFULL >> 1ULL,
51     ALL = 0xFFFFFFFFULL,
52 };
53 
54 namespace panda::ecmascript {
55 #ifdef ENABLE_HILOG
56 constexpr static unsigned int ARK_DOMAIN = 0xD003F00;
57 constexpr static auto TAG = "ArkCompiler";
58 constexpr static OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, ARK_DOMAIN, TAG};
59 
60 #if ECMASCRIPT_ENABLE_VERBOSE_LEVEL_LOG
61 // print Debug level log if enable Verbose log
62 #define LOG_VERBOSE LOG_DEBUG
63 #else
64 #define LOG_VERBOSE LOG_LEVEL_MIN
65 #endif
66 #endif  // ENABLE_HILOG
67 
68 class JSRuntimeOptions;
69 class PUBLIC_API Log {
70 public:
71     static void Initialize(const JSRuntimeOptions &options);
LogIsLoggable(Level level,Component component)72     static inline bool LogIsLoggable(Level level, Component component)
73     {
74         return (level >= level_) && ((components_ & component) != 0ULL);
75     }
GetComponentStr(Component component)76     static inline std::string GetComponentStr(Component component)
77     {
78         switch (component)
79         {
80             case Component::NO_TAG:
81                 return "";
82             case Component::GC:
83                 return "[gc] ";
84             case Component::ECMASCRIPT:
85                 return "[ecmascript] ";
86             case Component::INTERPRETER:
87                 return "[interpreter] ";
88             case Component::DEBUGGER:
89                 return "[debugger] ";
90             case Component::COMPILER:
91                 return "[compiler] ";
92             case Component::BUILTINS:
93                 return "[builtins] ";
94             case Component::TRACE:
95                 return "[trace] ";
96             case Component::ALL:
97                 return "[default] ";
98             default:
99                 return "[unknown] ";
100         }
101     }
102     static std::string LevelToString(Level level);
103     static Level ConvertFromRuntime(LOG_LEVEL level);
104 
105 private:
106     static void SetLogLevelFromString(const std::string& level);
107     static void SetLogComponentFromString(const std::vector<std::string>& components);
108     static int32_t PrintLogger(int32_t, int32_t level, const char *, const char *, const char *message);
109 
110     static Level level_;
111     static ComponentMark components_;
112 };
113 
114 #if defined(ENABLE_HILOG)
115 template<LogLevel level, Component component>
116 class HiLog {
117 public:
HiLog()118     HiLog()
119     {
120         std::string str = Log::GetComponentStr(component);
121         stream_ << str;
122     }
~HiLog()123     ~HiLog()
124     {
125         if constexpr (level == LOG_LEVEL_MIN) {
126             // print nothing
127         } else if constexpr (level == LOG_DEBUG) {
128             OHOS::HiviewDFX::HiLog::Debug(LABEL, "%{public}s", stream_.str().c_str());
129         } else if constexpr (level == LOG_INFO) {
130             OHOS::HiviewDFX::HiLog::Info(LABEL, "%{public}s", stream_.str().c_str());
131         } else if constexpr (level == LOG_WARN) {
132             OHOS::HiviewDFX::HiLog::Warn(LABEL, "%{public}s", stream_.str().c_str());
133         } else if constexpr (level == LOG_ERROR) {
134             OHOS::HiviewDFX::HiLog::Error(LABEL, "%{public}s", stream_.str().c_str());
135         } else {
136             OHOS::HiviewDFX::HiLog::Fatal(LABEL, "%{public}s", stream_.str().c_str());
137             std::abort();
138         }
139     }
140     template<class type>
141     std::ostream &operator <<(type input)
142     {
143         stream_ << input;
144         return stream_;
145     }
146 
147 private:
148     std::ostringstream stream_;
149 };
150 #elif defined(ENABLE_ANLOG)  // ENABLE_ANLOG
151 template<Level level>
152 class PUBLIC_API AndroidLog {
153 public:
AndroidLog()154     AndroidLog()
155     {
156         std::string str = "[default] ";
157         stream_ << str;
158     }
159     ~AndroidLog();
160 
161     template<class type>
162     std::ostream &operator <<(type input)
163     {
164         stream_ << input;
165         return stream_;
166     }
167 
168 private:
169     std::ostringstream stream_;
170 };
171 #else
172 template<Level level, Component component>
173 class StdLog {
174 public:
StdLog()175     StdLog()
176     {
177         std::string str = Log::GetComponentStr(component);
178         stream_ << str;
179     }
~StdLog()180     ~StdLog()
181     {
182         if constexpr (level == FATAL || level == ERROR) {
183             std::cerr << stream_.str().c_str() << std::endl;
184         } else {
185             std::cout << stream_.str().c_str() << std::endl;
186         }
187 
188         if constexpr (level == FATAL) {
189             std::abort();
190         }
191     }
192 
193     template<class type>
194     std::ostream &operator <<(type input)
195     {
196         stream_ << input;
197         return stream_;
198     }
199 
200 private:
201     std::ostringstream stream_;
202 };
203 #endif
204 
205 #if defined(ENABLE_HILOG)
206 #define ARK_LOG(level, component) panda::ecmascript::Log::LogIsLoggable(level, component) && \
207                                   panda::ecmascript::HiLog<LOG_##level, (component)>()
208 #elif defined(ENABLE_ANLOG)
209 #define ARK_LOG(level, component) panda::ecmascript::AndroidLog<(level)>()
210 #else
211 #if defined(OHOS_UNIT_TEST)
212 #define ARK_LOG(level, component) ((level >= INFO) || panda::ecmascript::Log::LogIsLoggable(level, component)) && \
213                                   panda::ecmascript::StdLog<(level), (component)>()
214 #else
215 #define ARK_LOG(level, component) panda::ecmascript::Log::LogIsLoggable(level, component) && \
216                                   panda::ecmascript::StdLog<(level), (component)>()
217 #endif
218 #endif
219 }  // namespace panda::ecmascript
220 #endif  // ECMASCRIPT_LOG_H
221