• 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 COMMON_COMPONENTS_LOG_LOG_H
17 #define COMMON_COMPONENTS_LOG_LOG_H
18 
19 #include <cstdint>
20 #include <string>
21 
22 #include "common_components/log/log_base.h"
23 #include "common_components/base/time_utils.h"
24 #include "securec.h"
25 
26 #ifdef ENABLE_HILOG
27 #if defined(__clang__)
28 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
29 #elif defined(__GNUC__)
30 #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
31 #endif
32 #include "hilog/log.h"
33 #endif
34 #undef LOG_DOMAIN
35 #define LOG_DOMAIN 0xD003F00
36 #undef LOG_TAG
37 #define LOG_TAG "ArkCompiler"
38 
39 #if defined(ENABLE_HITRACE)
40     #include "hitrace_meter.h"
41 
42     #define OHOS_HITRACE(level, name, customArgs)        HITRACE_METER_NAME_EX(level, HITRACE_TAG_ARK, name, customArgs)
43     #define OHOS_HITRACE_START(level, name, customArgs)  StartTraceEx(level, HITRACE_TAG_ARK, name, customArgs)
44     #define OHOS_HITRACE_FINISH(level)                   FinishTraceEx(level, HITRACE_TAG_ARK)
45     #define OHOS_HITRACE_COUNT(level, name, count)       CountTraceEx(level, HITRACE_TAG_ARK, name, count)
46 #else
47     #define OHOS_HITRACE(level, name, customArgs)
48     #define OHOS_HITRACE_START(level, name, customArgs)
49     #define OHOS_HITRACE_FINISH(level)
50     #define OHOS_HITRACE_COUNT(level, name, count)
51 #endif
52 
53 namespace common {
54 class PUBLIC_API Log {
55 public:
56     static void Initialize(const LogOptions &options);
LogIsLoggable(Level level,Component component)57     static inline bool LogIsLoggable(Level level, Component component)
58     {
59         switch (component) //LCOV_EXCL_BR_LINE
60         {
61             case Component::SA: //LCOV_EXCL_BR_LINE
62                 return ((components_ & static_cast<ComponentMark>(component)) != 0ULL);
63             default: //LCOV_EXCL_BR_LINE
64                 return (level >= level_) && ((components_ & static_cast<ComponentMark>(component)) != 0ULL);
65         }
66     }
GetComponentStr(Component component)67     static inline std::string GetComponentStr(Component component)
68     {
69         switch (component) //LCOV_EXCL_BR_LINE
70         {
71             case Component::NO_TAG: //LCOV_EXCL_BR_LINE
72                 return "";
73             case Component::GC: //LCOV_EXCL_BR_LINE
74                 return "[gc] ";
75             case Component::ECMASCRIPT: //LCOV_EXCL_BR_LINE
76                 return "[ecmascript] ";
77             case Component::PGO: //LCOV_EXCL_BR_LINE
78                 return "[pgo] ";
79             case Component::INTERPRETER: //LCOV_EXCL_BR_LINE
80                 return "[interpreter] ";
81             case Component::DEBUGGER: //LCOV_EXCL_BR_LINE
82                 return "[debugger] ";
83             case Component::COMPILER: //LCOV_EXCL_BR_LINE
84                 return "[compiler] ";
85             case Component::BUILTINS: //LCOV_EXCL_BR_LINE
86                 return "[builtins] ";
87             case Component::TRACE: //LCOV_EXCL_BR_LINE
88                 return "[trace] ";
89             case Component::JIT: //LCOV_EXCL_BR_LINE
90                 return "[jit] ";
91             case Component::BASELINEJIT: //LCOV_EXCL_BR_LINE
92                 return "[baselinejit] ";
93             case Component::SA: //LCOV_EXCL_BR_LINE
94                 return "[sa] ";
95             case Component::COMMON: //LCOV_EXCL_BR_LINE
96                 return "[common] ";
97             case Component::ALL: //LCOV_EXCL_BR_LINE
98                 return "[default] ";
99             default: //LCOV_EXCL_BR_LINE
100                 return "[unknown] ";
101         }
102     }
103     static std::string LevelToString(Level level);
104     static Level ConvertFromRuntime(LOG_LEVEL level);
105 
106 private:
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) { //LCOV_EXCL_BR_LINE
125             // print nothing
126         } else if constexpr (level == LOG_DEBUG) { //LCOV_EXCL_BR_LINE
127             HILOG_DEBUG(LOG_CORE, "%{public}s", stream_.str().c_str());
128         } else if constexpr (level == LOG_INFO) { //LCOV_EXCL_BR_LINE
129             HILOG_INFO(LOG_CORE, "%{public}s", stream_.str().c_str());
130         } else if constexpr (level == LOG_WARN) { //LCOV_EXCL_BR_LINE
131             HILOG_WARN(LOG_CORE, "%{public}s", stream_.str().c_str());
132         } else if constexpr (level == LOG_ERROR) { //LCOV_EXCL_BR_LINE
133             HILOG_ERROR(LOG_CORE, "%{public}s", stream_.str().c_str());
134         } else { //LCOV_EXCL_BR_LINE
135             HILOG_FATAL(LOG_CORE, "%{public}s", stream_.str().c_str());
136             if (level == LOG_FATAL) { //LCOV_EXCL_BR_LINE
137                 std::abort();
138             }
139         }
140     }
141     template<class type>
142     std::ostream &operator <<(type input)
143     {
144         stream_ << input;
145         return stream_;
146     }
147 
148 private:
149     std::ostringstream stream_;
150 };
151 #elif defined(ENABLE_ANLOG)  // ENABLE_ANLOG
152 template<Level level>
153 class PUBLIC_API AndroidLog {
154 public:
AndroidLog()155     AndroidLog()
156     {
157         std::string str = "[default] ";
158         stream_ << str;
159     }
160     ~AndroidLog();
161 
162     template<class type>
163     std::ostream &operator <<(type input)
164     {
165         stream_ << input;
166         return stream_;
167     }
168 
169 private:
170     std::ostringstream stream_;
171 };
172 #else
173 template<Level level, Component component>
174 class StdLog {
175 public:
StdLog()176     StdLog()
177     {
178         std::string str = Log::GetComponentStr(component);
179         stream_ << str;
180     }
~StdLog()181     ~StdLog()
182     {
183         if constexpr (level >= Level::ERROR) { //LCOV_EXCL_BR_LINE
184             std::cerr << stream_.str().c_str() << std::endl;
185         } else { //LCOV_EXCL_BR_LINE
186             std::cout << stream_.str().c_str() << std::endl;
187         }
188 
189         if constexpr (level == Level::FATAL) { //LCOV_EXCL_BR_LINE
190             std::abort();
191         }
192     }
193 
194     template<class type>
195     std::ostream &operator <<(type input)
196     {
197         stream_ << input;
198         return stream_;
199     }
200 
201 private:
202     std::ostringstream stream_;
203 };
204 #endif
205 
206 #if defined(ENABLE_HILOG)
207 #define ARK_LOG(level, component) common::Log::LogIsLoggable(Level::level, component) && \
208                                   common::HiLog<LOG_##level, (component)>()
209 #elif defined(ENABLE_ANLOG)
210 #define ARK_LOG(level, component) common::AndroidLog<(Level::level)>()
211 #else
212 #if defined(OHOS_UNIT_TEST)
213 #define ARK_LOG(level, component) ((Level::level >= Level::INFO) ||                      \
214                                   common::Log::LogIsLoggable(Level::level, component)) && \
215                                   common::StdLog<(Level::level), (component)>()
216 #else
217 #define ARK_LOG(level, component) common::Log::LogIsLoggable(Level::level, component) && \
218                                   common::StdLog<(Level::level), (component)>()
219 #endif
220 #endif
221 
222 #define LOG_COMMON(level) ARK_LOG(level, Component::COMMON)
223 #define LOG_GC(level) ARK_LOG(level, Component::GC)
224 
225 #define LOGD_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(DEBUG)
226 #define LOGI_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(INFO)
227 #define LOGW_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(WARN)
228 #define LOGE_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(ERROR)
229 #define LOGF_IF(cond) (UNLIKELY_CC(cond)) && LOG_COMMON(ERROR) << "Check failed: " << #cond && LOG_COMMON(FATAL)
230 
231 #define CHECKF(cond) (UNLIKELY_CC(!(cond))) && LOG_COMMON(FATAL) << "Check failed: " << #cond
232 #define LOGF_CHECK(cond) LOGF_IF(!(cond))
233 
234 #ifndef NDEBUG
235 #define DLOG(type, format...) LOG_GC(DEBUG) << FormatLog(format)
236 #else  // NDEBUG
237 #define DLOG(type, format...) (void)(0)
238 #endif  // NDEBUG
239 #define VLOG(level, format...) LOG_GC(level) << FormatLog(format)
240 
241 #define COMMON_PHASE_TIMER(...) Timer ARK_pt_##__LINE__(__VA_ARGS__)
242 
243 #ifndef NDEBUG
244 #define ASSERT_LOGF(cond, msg) LOGF_IF(!(cond)) << (msg)
245 #else  // NDEBUG
246 #define ASSERT_LOGF(cond, msg)
247 #endif  // NDEBUG
248 
249 #define CHECK_CALL(call, args, what)        \
250     do {                                    \
251         int rc = call args;                 \
252         if (UNLIKELY_CC(rc != 0)) {         \
253             errno = rc;                     \
254             /* LCOV_EXCL_BR_LINE */         \
255             LOG_COMMON(FATAL) << #call <<   \
256                 " failed for " <<           \
257                 (what) <<" reason " <<      \
258                  strerror(errno) <<         \
259                  " return " << errno;       \
260         }                                   \
261     } while (false) //LCOV_EXCL_BR_LINE
262 
263 std::string Pretty(uint64_t number) noexcept;
264 std::string PrettyOrderInfo(uint64_t number, const char* unit);
265 std::string PrettyOrderMathNano(uint64_t number, const char* unit);
266 std::string FormatLogMessage(const char* format, va_list agrs) noexcept;
267 std::string FormatLog(const char* format, ...) noexcept;
268 class Timer {
269 public:
Timer(const std::string pName)270     explicit Timer(const std::string pName) : name_(pName)
271     {
272         if (common::Log::LogIsLoggable(Level::DEBUG, Component::GC)) {
273             startTime_ = TimeUtil::MicroSeconds();
274         }
275     }
276 
~Timer()277     ~Timer()
278     {
279         if (common::Log::LogIsLoggable(Level::DEBUG, Component::GC)) {
280             uint64_t stopTime = TimeUtil::MicroSeconds();
281             uint64_t diffTime = stopTime - startTime_;
282             VLOG(DEBUG, "%s time: %sus", name_.c_str(), Pretty(diffTime).c_str());
283         }
284     }
285 
286 private:
287     std::string name_;
288     uint64_t startTime_ = 0;
289 };
290 }  // namespace common
291 #endif  // COMMON_COMPONENTS_LOG_LOG_H
292