1e9297d28Sopenharmony_ci/*
2e9297d28Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3e9297d28Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e9297d28Sopenharmony_ci * you may not use this file except in compliance with the License.
5e9297d28Sopenharmony_ci * You may obtain a copy of the License at
6e9297d28Sopenharmony_ci *
7e9297d28Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e9297d28Sopenharmony_ci *
9e9297d28Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e9297d28Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e9297d28Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e9297d28Sopenharmony_ci * See the License for the specific language governing permissions and
13e9297d28Sopenharmony_ci * limitations under the License.
14e9297d28Sopenharmony_ci */
15e9297d28Sopenharmony_ci
16e9297d28Sopenharmony_ci#include "texgine/utils/logger.h"
17e9297d28Sopenharmony_ci
18e9297d28Sopenharmony_ci#include <fstream>
19e9297d28Sopenharmony_ci#include <iomanip>
20e9297d28Sopenharmony_ci#include <iostream>
21e9297d28Sopenharmony_ci#include <unistd.h>
22e9297d28Sopenharmony_ci
23e9297d28Sopenharmony_ci#ifdef BUILD_NON_SDK_VER
24e9297d28Sopenharmony_ci#include <sys/syscall.h>
25e9297d28Sopenharmony_ci#define GET_TID() syscall(__NR_gettid)
26e9297d28Sopenharmony_ci#else
27e9297d28Sopenharmony_ci#ifdef _WIN32
28e9297d28Sopenharmony_ci#include <windows.h>
29e9297d28Sopenharmony_ci#define GET_TID GetCurrentThreadId
30e9297d28Sopenharmony_ci#endif
31e9297d28Sopenharmony_ci
32e9297d28Sopenharmony_ci#if defined(BUILD_SDK_MAC) || defined(BUILD_SDK_IOS)
33e9297d28Sopenharmony_ci#include <stdlib.h>
34e9297d28Sopenharmony_ci#include <sys/syscall.h>
35e9297d28Sopenharmony_ci#define GET_TID() syscall(SYS_thread_selfid)
36e9297d28Sopenharmony_ci#elif defined(BUILD_SDK_ANDROID)
37e9297d28Sopenharmony_ci#define GET_TID() gettid()
38e9297d28Sopenharmony_ci#else
39e9297d28Sopenharmony_ci#ifdef __gnu_linux__
40e9297d28Sopenharmony_ci#include <sys/types.h>
41e9297d28Sopenharmony_ci#include <sys/syscall.h>
42e9297d28Sopenharmony_ci#define GET_TID() syscall(SYS_gettid)
43e9297d28Sopenharmony_ci#endif
44e9297d28Sopenharmony_ci#endif
45e9297d28Sopenharmony_ci
46e9297d28Sopenharmony_ci#ifdef __APPLE__
47e9297d28Sopenharmony_ci#define getpid getpid
48e9297d28Sopenharmony_ci#endif
49e9297d28Sopenharmony_ci
50e9297d28Sopenharmony_ci#ifdef ERROR
51e9297d28Sopenharmony_ci#undef ERROR
52e9297d28Sopenharmony_ci#endif
53e9297d28Sopenharmony_ci#endif
54e9297d28Sopenharmony_ci
55e9297d28Sopenharmony_ci#ifdef LOGGER_NO_COLOR
56e9297d28Sopenharmony_ci#define IF_COLOR(x)
57e9297d28Sopenharmony_ci#else
58e9297d28Sopenharmony_ci#define IF_COLOR(x) x
59e9297d28Sopenharmony_ci#endif
60e9297d28Sopenharmony_ci
61e9297d28Sopenharmony_cinamespace OHOS {
62e9297d28Sopenharmony_cinamespace Rosen {
63e9297d28Sopenharmony_cinamespace TextEngine {
64e9297d28Sopenharmony_cinamespace {
65e9297d28Sopenharmony_ciconst char *GetLevelStr(enum Logger::LOG_LEVEL level)
66e9297d28Sopenharmony_ci{
67e9297d28Sopenharmony_ci    switch (level) {
68e9297d28Sopenharmony_ci        case Logger::LOG_LEVEL::DEBUG:
69e9297d28Sopenharmony_ci            return IF_COLOR("\033[37m") "D" IF_COLOR("\033[0m");
70e9297d28Sopenharmony_ci        case Logger::LOG_LEVEL::INFO:
71e9297d28Sopenharmony_ci            return IF_COLOR("\033[36m") "I" IF_COLOR("\033[0m");
72e9297d28Sopenharmony_ci        case Logger::LOG_LEVEL::WARN:
73e9297d28Sopenharmony_ci            return IF_COLOR("\033[33m") "W" IF_COLOR("\033[0m");
74e9297d28Sopenharmony_ci        case Logger::LOG_LEVEL::ERROR:
75e9297d28Sopenharmony_ci            return IF_COLOR("\033[31m") "E" IF_COLOR("\033[0m");
76e9297d28Sopenharmony_ci        case Logger::LOG_LEVEL::FATAL:
77e9297d28Sopenharmony_ci            return IF_COLOR("\033[4;31m") "F" IF_COLOR("\033[0m");
78e9297d28Sopenharmony_ci    }
79e9297d28Sopenharmony_ci    return "?";
80e9297d28Sopenharmony_ci}
81e9297d28Sopenharmony_ci} // namespace
82e9297d28Sopenharmony_ci
83e9297d28Sopenharmony_civoid Logger::SetToNoReturn(Logger &logger, enum LOG_PHASE phase)
84e9297d28Sopenharmony_ci{
85e9297d28Sopenharmony_ci    logger.return_ = false;
86e9297d28Sopenharmony_ci}
87e9297d28Sopenharmony_ci
88e9297d28Sopenharmony_civoid Logger::SetToContinue(Logger &logger, enum LOG_PHASE phase)
89e9297d28Sopenharmony_ci{
90e9297d28Sopenharmony_ci    logger.continue_ = true;
91e9297d28Sopenharmony_ci}
92e9297d28Sopenharmony_ci
93e9297d28Sopenharmony_civoid Logger::OutputByStdout(Logger &logger, enum LOG_PHASE phase)
94e9297d28Sopenharmony_ci{
95e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
96e9297d28Sopenharmony_ci        return;
97e9297d28Sopenharmony_ci    }
98e9297d28Sopenharmony_ci
99e9297d28Sopenharmony_ci    // LOG_PHASE::END
100e9297d28Sopenharmony_ci    if (logger.continue_ == false) {
101e9297d28Sopenharmony_ci        std::cout << GetLevelStr(logger.GetLevel()) << " ";
102e9297d28Sopenharmony_ci    }
103e9297d28Sopenharmony_ci
104e9297d28Sopenharmony_ci    std::cout << logger.str();
105e9297d28Sopenharmony_ci    if (logger.return_) {
106e9297d28Sopenharmony_ci        std::cout << std::endl;
107e9297d28Sopenharmony_ci    }
108e9297d28Sopenharmony_ci}
109e9297d28Sopenharmony_ci
110e9297d28Sopenharmony_civoid Logger::OutputByStderr(Logger &logger, enum LOG_PHASE phase)
111e9297d28Sopenharmony_ci{
112e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
113e9297d28Sopenharmony_ci        return;
114e9297d28Sopenharmony_ci    }
115e9297d28Sopenharmony_ci
116e9297d28Sopenharmony_ci    // LOG_PHASE::END
117e9297d28Sopenharmony_ci    if (logger.continue_ == false) {
118e9297d28Sopenharmony_ci        std::cerr << GetLevelStr(logger.GetLevel()) << " ";
119e9297d28Sopenharmony_ci    }
120e9297d28Sopenharmony_ci
121e9297d28Sopenharmony_ci    std::cerr << logger.str();
122e9297d28Sopenharmony_ci    if (logger.return_) {
123e9297d28Sopenharmony_ci        std::cerr << std::endl;
124e9297d28Sopenharmony_ci    }
125e9297d28Sopenharmony_ci}
126e9297d28Sopenharmony_ci
127e9297d28Sopenharmony_civoid Logger::OutputByFileLog(Logger &logger, enum LOG_PHASE phase)
128e9297d28Sopenharmony_ci{
129e9297d28Sopenharmony_ci    struct FileLogData {
130e9297d28Sopenharmony_ci        const char *filename;
131e9297d28Sopenharmony_ci    };
132e9297d28Sopenharmony_ci    auto data = logger.GetData<struct FileLogData>();
133e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
134e9297d28Sopenharmony_ci        auto filename = va_arg(logger.GetVariousArgument(), const char *);
135e9297d28Sopenharmony_ci        data->filename = filename;
136e9297d28Sopenharmony_ci        return;
137e9297d28Sopenharmony_ci    }
138e9297d28Sopenharmony_ci
139e9297d28Sopenharmony_ci    // LOG_PHASE::END
140e9297d28Sopenharmony_ci    std::ofstream ofs(data->filename, std::ofstream::out | std::ofstream::app);
141e9297d28Sopenharmony_ci    if (!ofs) {
142e9297d28Sopenharmony_ci        // open failed, errno
143e9297d28Sopenharmony_ci        return;
144e9297d28Sopenharmony_ci    }
145e9297d28Sopenharmony_ci
146e9297d28Sopenharmony_ci    if (logger.continue_ == false) {
147e9297d28Sopenharmony_ci        ofs << GetLevelStr(logger.GetLevel()) << " ";
148e9297d28Sopenharmony_ci    }
149e9297d28Sopenharmony_ci
150e9297d28Sopenharmony_ci    ofs << logger.str();
151e9297d28Sopenharmony_ci    if (logger.return_) {
152e9297d28Sopenharmony_ci        ofs << std::endl;
153e9297d28Sopenharmony_ci    }
154e9297d28Sopenharmony_ci    ofs.close();
155e9297d28Sopenharmony_ci}
156e9297d28Sopenharmony_ci
157e9297d28Sopenharmony_civoid Logger::AppendFunc(Logger &logger, enum LOG_PHASE phase)
158e9297d28Sopenharmony_ci{
159e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
160e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[34m");
161e9297d28Sopenharmony_ci        logger.AlignFunc();
162e9297d28Sopenharmony_ci        logger << logger.GetFunc() << IF_COLOR("\033[0m") " ";
163e9297d28Sopenharmony_ci    }
164e9297d28Sopenharmony_ci}
165e9297d28Sopenharmony_ci
166e9297d28Sopenharmony_civoid Logger::AppendFuncLine(Logger &logger, enum LOG_PHASE phase)
167e9297d28Sopenharmony_ci{
168e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
169e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[34m");
170e9297d28Sopenharmony_ci        logger.AlignFunc();
171e9297d28Sopenharmony_ci        logger << logger.GetFunc() << " ";
172e9297d28Sopenharmony_ci        logger.AlignLine();
173e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[35m") "+" << logger.GetLine() << IF_COLOR("\033[0m") " ";
174e9297d28Sopenharmony_ci    }
175e9297d28Sopenharmony_ci}
176e9297d28Sopenharmony_ci
177e9297d28Sopenharmony_civoid Logger::AppendFileLine(Logger &logger, enum LOG_PHASE phase)
178e9297d28Sopenharmony_ci{
179e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
180e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[34m") << logger.GetFile() << " ";
181e9297d28Sopenharmony_ci        logger.AlignLine();
182e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[35m") "+" << logger.GetLine() << IF_COLOR("\033[0m") " ";
183e9297d28Sopenharmony_ci    }
184e9297d28Sopenharmony_ci}
185e9297d28Sopenharmony_ci
186e9297d28Sopenharmony_civoid Logger::AppendFileFuncLine(Logger &logger, enum LOG_PHASE phase)
187e9297d28Sopenharmony_ci{
188e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
189e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[34m") << logger.GetFile() << " ";
190e9297d28Sopenharmony_ci        logger.AlignLine();
191e9297d28Sopenharmony_ci        logger << IF_COLOR("\033[35m") "+" << logger.GetLine() << " ";
192e9297d28Sopenharmony_ci        logger.AlignFunc();
193e9297d28Sopenharmony_ci        logger << logger.GetFunc() << IF_COLOR("\033[0m") " ";
194e9297d28Sopenharmony_ci    }
195e9297d28Sopenharmony_ci}
196e9297d28Sopenharmony_ci
197e9297d28Sopenharmony_civoid Logger::AppendPidTid(Logger &logger, enum LOG_PHASE phase)
198e9297d28Sopenharmony_ci{
199e9297d28Sopenharmony_ci    if (phase == LOG_PHASE::BEGIN) {
200e9297d28Sopenharmony_ci        logger << getpid() << ":" << GET_TID() << " ";
201e9297d28Sopenharmony_ci    }
202e9297d28Sopenharmony_ci}
203e9297d28Sopenharmony_ci
204e9297d28Sopenharmony_civoid Logger::SetScopeParam(int func, int line)
205e9297d28Sopenharmony_ci{
206e9297d28Sopenharmony_ci    alignFunc = func;
207e9297d28Sopenharmony_ci    alignLine = line;
208e9297d28Sopenharmony_ci}
209e9297d28Sopenharmony_ci
210e9297d28Sopenharmony_civoid Logger::EnterScope()
211e9297d28Sopenharmony_ci{
212e9297d28Sopenharmony_ci    std::lock_guard<std::mutex> lock(scopeMutex_);
213e9297d28Sopenharmony_ci    scope_++;
214e9297d28Sopenharmony_ci}
215e9297d28Sopenharmony_ci
216e9297d28Sopenharmony_civoid Logger::ExitScope()
217e9297d28Sopenharmony_ci{
218e9297d28Sopenharmony_ci    std::lock_guard<std::mutex> lock(scopeMutex_);
219e9297d28Sopenharmony_ci    scope_--;
220e9297d28Sopenharmony_ci}
221e9297d28Sopenharmony_ci
222e9297d28Sopenharmony_ciLogger::Logger(const std::string &file, const std::string &func, int line, enum LOG_LEVEL level, ...)
223e9297d28Sopenharmony_ci{
224e9297d28Sopenharmony_ci    *this << std::boolalpha;
225e9297d28Sopenharmony_ci    file_ = file;
226e9297d28Sopenharmony_ci    func_ = func;
227e9297d28Sopenharmony_ci    line_ = line;
228e9297d28Sopenharmony_ci    level_ = level;
229e9297d28Sopenharmony_ci    va_start(vl_, level);
230e9297d28Sopenharmony_ci
231e9297d28Sopenharmony_ci    while (true) {
232e9297d28Sopenharmony_ci        LoggerWrapperFunc f = va_arg(vl_, LoggerWrapperFunc);
233e9297d28Sopenharmony_ci        if (f == nullptr) {
234e9297d28Sopenharmony_ci            break;
235e9297d28Sopenharmony_ci        }
236e9297d28Sopenharmony_ci
237e9297d28Sopenharmony_ci        f(*this, LOG_PHASE::BEGIN);
238e9297d28Sopenharmony_ci        wrappers_.push_back(f);
239e9297d28Sopenharmony_ci    }
240e9297d28Sopenharmony_ci
241e9297d28Sopenharmony_ci#ifdef LOGGER_ENABLE_SCOPE
242e9297d28Sopenharmony_ci    {
243e9297d28Sopenharmony_ci        std::lock_guard<std::mutex> lock(scopeMutex_);
244e9297d28Sopenharmony_ci        // The number of space if enable scope
245e9297d28Sopenharmony_ci        Align(scope_ * 2);  // 2 means multiple
246e9297d28Sopenharmony_ci    }
247e9297d28Sopenharmony_ci#endif
248e9297d28Sopenharmony_ci}
249e9297d28Sopenharmony_ci
250e9297d28Sopenharmony_ciLogger::Logger(const Logger &logger)
251e9297d28Sopenharmony_ci{
252e9297d28Sopenharmony_ci    file_ = logger.file_;
253e9297d28Sopenharmony_ci    func_ = logger.func_;
254e9297d28Sopenharmony_ci    line_ = logger.line_;
255e9297d28Sopenharmony_ci    level_ = logger.level_;
256e9297d28Sopenharmony_ci    data_ = logger.data_;
257e9297d28Sopenharmony_ci    wrappers_ = logger.wrappers_;
258e9297d28Sopenharmony_ci    *this << logger.str();
259e9297d28Sopenharmony_ci}
260e9297d28Sopenharmony_ci
261e9297d28Sopenharmony_ciLogger::Logger(Logger &&logger)
262e9297d28Sopenharmony_ci{
263e9297d28Sopenharmony_ci    file_ = logger.file_;
264e9297d28Sopenharmony_ci    func_ = logger.func_;
265e9297d28Sopenharmony_ci    line_ = logger.line_;
266e9297d28Sopenharmony_ci    level_ = logger.level_;
267e9297d28Sopenharmony_ci    data_ = logger.data_;
268e9297d28Sopenharmony_ci    wrappers_ = logger.wrappers_;
269e9297d28Sopenharmony_ci    *this << logger.str();
270e9297d28Sopenharmony_ci
271e9297d28Sopenharmony_ci    logger.wrappers_.clear();
272e9297d28Sopenharmony_ci}
273e9297d28Sopenharmony_ci
274e9297d28Sopenharmony_ciLogger::~Logger()
275e9297d28Sopenharmony_ci{
276e9297d28Sopenharmony_ci    for (const auto &wrapper : wrappers_) {
277e9297d28Sopenharmony_ci        wrapper(*this, LOG_PHASE::END);
278e9297d28Sopenharmony_ci    }
279e9297d28Sopenharmony_ci}
280e9297d28Sopenharmony_ci
281e9297d28Sopenharmony_ciconst std::string &Logger::GetFile() const
282e9297d28Sopenharmony_ci{
283e9297d28Sopenharmony_ci    return file_;
284e9297d28Sopenharmony_ci}
285e9297d28Sopenharmony_ci
286e9297d28Sopenharmony_ciconst std::string &Logger::GetFunc() const
287e9297d28Sopenharmony_ci{
288e9297d28Sopenharmony_ci    return func_;
289e9297d28Sopenharmony_ci}
290e9297d28Sopenharmony_ci
291e9297d28Sopenharmony_ciint Logger::GetLine() const
292e9297d28Sopenharmony_ci{
293e9297d28Sopenharmony_ci    return line_;
294e9297d28Sopenharmony_ci}
295e9297d28Sopenharmony_ci
296e9297d28Sopenharmony_cienum Logger::LOG_LEVEL Logger::GetLevel() const
297e9297d28Sopenharmony_ci{
298e9297d28Sopenharmony_ci    return level_;
299e9297d28Sopenharmony_ci}
300e9297d28Sopenharmony_ci
301e9297d28Sopenharmony_civa_list &Logger::GetVariousArgument()
302e9297d28Sopenharmony_ci{
303e9297d28Sopenharmony_ci    return vl_;
304e9297d28Sopenharmony_ci}
305e9297d28Sopenharmony_ci
306e9297d28Sopenharmony_civoid Logger::Align(int num)
307e9297d28Sopenharmony_ci{
308e9297d28Sopenharmony_ci    if (continue_) {
309e9297d28Sopenharmony_ci        return;
310e9297d28Sopenharmony_ci    }
311e9297d28Sopenharmony_ci
312e9297d28Sopenharmony_ci    for (int32_t i = 0; i < num; i++) {
313e9297d28Sopenharmony_ci        *this << " ";
314e9297d28Sopenharmony_ci    }
315e9297d28Sopenharmony_ci}
316e9297d28Sopenharmony_ci
317e9297d28Sopenharmony_civoid Logger::AlignLine()
318e9297d28Sopenharmony_ci{
319e9297d28Sopenharmony_ci    if (alignLine) {
320e9297d28Sopenharmony_ci        auto line = GetLine();
321e9297d28Sopenharmony_ci        auto num = line == 0 ? 1 : 0;
322e9297d28Sopenharmony_ci        while (line) {
323e9297d28Sopenharmony_ci            // 10 is to calculate the number of bits in the row where the function is located
324e9297d28Sopenharmony_ci            line /= 10;
325e9297d28Sopenharmony_ci            num++;
326e9297d28Sopenharmony_ci        }
327e9297d28Sopenharmony_ci        Align(alignLine - num);
328e9297d28Sopenharmony_ci    }
329e9297d28Sopenharmony_ci}
330e9297d28Sopenharmony_ci
331e9297d28Sopenharmony_civoid Logger::AlignFunc()
332e9297d28Sopenharmony_ci{
333e9297d28Sopenharmony_ci    if (alignFunc) {
334e9297d28Sopenharmony_ci        Align(alignFunc - GetFunc().size());
335e9297d28Sopenharmony_ci    }
336e9297d28Sopenharmony_ci}
337e9297d28Sopenharmony_ci
338e9297d28Sopenharmony_ciScopedLogger::ScopedLogger(NoLogger &&logger)
339e9297d28Sopenharmony_ci{
340e9297d28Sopenharmony_ci}
341e9297d28Sopenharmony_ci
342e9297d28Sopenharmony_ciScopedLogger::ScopedLogger(NoLogger &&logger, const std::string &name)
343e9297d28Sopenharmony_ci{
344e9297d28Sopenharmony_ci}
345e9297d28Sopenharmony_ci
346e9297d28Sopenharmony_ciScopedLogger::ScopedLogger(Logger &&logger)
347e9297d28Sopenharmony_ci    : ScopedLogger(std::move(logger), "")
348e9297d28Sopenharmony_ci{
349e9297d28Sopenharmony_ci}
350e9297d28Sopenharmony_ci
351e9297d28Sopenharmony_ciScopedLogger::ScopedLogger(Logger &&logger, const std::string &name)
352e9297d28Sopenharmony_ci{
353e9297d28Sopenharmony_ci#ifdef LOGGER_ENABLE_SCOPE
354e9297d28Sopenharmony_ci    logger_ = new Logger(logger);
355e9297d28Sopenharmony_ci    *logger_ << "} " << name;
356e9297d28Sopenharmony_ci    logger << "{ ";
357e9297d28Sopenharmony_ci#endif
358e9297d28Sopenharmony_ci    logger << name;
359e9297d28Sopenharmony_ci    Logger::EnterScope();
360e9297d28Sopenharmony_ci}
361e9297d28Sopenharmony_ci
362e9297d28Sopenharmony_ciScopedLogger::~ScopedLogger()
363e9297d28Sopenharmony_ci{
364e9297d28Sopenharmony_ci    Finish();
365e9297d28Sopenharmony_ci}
366e9297d28Sopenharmony_ci
367e9297d28Sopenharmony_civoid ScopedLogger::Finish()
368e9297d28Sopenharmony_ci{
369e9297d28Sopenharmony_ci    if (logger_) {
370e9297d28Sopenharmony_ci        Logger::ExitScope();
371e9297d28Sopenharmony_ci        delete logger_;
372e9297d28Sopenharmony_ci        logger_ = nullptr;
373e9297d28Sopenharmony_ci    }
374e9297d28Sopenharmony_ci}
375e9297d28Sopenharmony_ci} // namespace TextEngine
376e9297d28Sopenharmony_ci} // namespace Rosen
377e9297d28Sopenharmony_ci} // namespace OHOS
378