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