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