106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci
1606f6ba60Sopenharmony_ci#ifndef OHOS_PROFILER_LOGGING_H
1706f6ba60Sopenharmony_ci#define OHOS_PROFILER_LOGGING_H
1806f6ba60Sopenharmony_ci
1906f6ba60Sopenharmony_ci#define EXPORT_API __attribute__((visibility("default")))
2006f6ba60Sopenharmony_ci
2106f6ba60Sopenharmony_ci#undef NDEBUG
2206f6ba60Sopenharmony_ci
2306f6ba60Sopenharmony_ci#ifndef LOG_TAG
2406f6ba60Sopenharmony_ci#define LOG_TAG "Hiprofiler"
2506f6ba60Sopenharmony_ci#endif
2606f6ba60Sopenharmony_ci
2706f6ba60Sopenharmony_ci#define PROFILER_SUBSYSTEM 0xD002D0C
2806f6ba60Sopenharmony_ci#ifndef LOG_DOMAIN
2906f6ba60Sopenharmony_ci#define LOG_DOMAIN PROFILER_SUBSYSTEM
3006f6ba60Sopenharmony_ci#endif
3106f6ba60Sopenharmony_ci
3206f6ba60Sopenharmony_ci#ifndef UNUSED_PARAMETER
3306f6ba60Sopenharmony_ci#define UNUSED_PARAMETER(x) ((void)(x))
3406f6ba60Sopenharmony_ci#endif
3506f6ba60Sopenharmony_ci
3606f6ba60Sopenharmony_ci#ifdef HAVE_HILOG
3706f6ba60Sopenharmony_ci#include "hilog_base/log_base.h"
3806f6ba60Sopenharmony_ci#include <string>
3906f6ba60Sopenharmony_ci#else // HAVE_HILOG
4006f6ba60Sopenharmony_ci#include <mutex>
4106f6ba60Sopenharmony_ci#include <string>
4206f6ba60Sopenharmony_ci#include <securec.h>
4306f6ba60Sopenharmony_ci#include <stdarg.h>
4406f6ba60Sopenharmony_ci#if !is_mingw
4506f6ba60Sopenharmony_ci#include <sys/syscall.h>
4606f6ba60Sopenharmony_ci#undef getsystid
4706f6ba60Sopenharmony_ci#define getsystid() syscall(SYS_gettid)
4806f6ba60Sopenharmony_ci#else
4906f6ba60Sopenharmony_ci#include "windows.h"
5006f6ba60Sopenharmony_ciinline long getsystid()
5106f6ba60Sopenharmony_ci{
5206f6ba60Sopenharmony_ci    return GetCurrentThreadId();
5306f6ba60Sopenharmony_ci}
5406f6ba60Sopenharmony_ci#endif
5506f6ba60Sopenharmony_ci
5606f6ba60Sopenharmony_ci#include <ctime>
5706f6ba60Sopenharmony_ci#include <vector>
5806f6ba60Sopenharmony_ci#include <unistd.h>
5906f6ba60Sopenharmony_ci
6006f6ba60Sopenharmony_cienum {
6106f6ba60Sopenharmony_ci    LOG_UNKNOWN = 0,
6206f6ba60Sopenharmony_ci    LOG_DEFAULT,
6306f6ba60Sopenharmony_ci    LOG_VERBOSE,
6406f6ba60Sopenharmony_ci    LOG_DEBUG,
6506f6ba60Sopenharmony_ci    LOG_INFO,
6606f6ba60Sopenharmony_ci    LOG_WARN,
6706f6ba60Sopenharmony_ci    LOG_ERROR,
6806f6ba60Sopenharmony_ci    LOG_FATAL,
6906f6ba60Sopenharmony_ci    LOG_SILENT,
7006f6ba60Sopenharmony_ci};
7106f6ba60Sopenharmony_ci
7206f6ba60Sopenharmony_cinamespace {
7306f6ba60Sopenharmony_ciconstexpr int NS_PER_MS_LOG = 1000 * 1000;
7406f6ba60Sopenharmony_ciconstexpr int TIME_STRING_MAX_LENGTH = 64;
7506f6ba60Sopenharmony_ci}
7606f6ba60Sopenharmony_ci
7706f6ba60Sopenharmony_cistatic inline std::string GetTimeString();
7806f6ba60Sopenharmony_ci
7906f6ba60Sopenharmony_citypedef const char* ConstCharPtr;
8006f6ba60Sopenharmony_ci
8106f6ba60Sopenharmony_cistatic inline int HiLogPrintArgs(int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs)
8206f6ba60Sopenharmony_ci{
8306f6ba60Sopenharmony_ci    static std::mutex mtx;
8406f6ba60Sopenharmony_ci    static std::vector<std::string> prioNames = {"U", " ", "V", "D", "I", "W", "E", "F", "S"};
8506f6ba60Sopenharmony_ci    std::unique_lock<std::mutex> lock(mtx);
8606f6ba60Sopenharmony_ci    int count = fprintf(stderr, "%04x %s %7d %7ld %5s %s ", domain, GetTimeString().c_str(), getpid(), getsystid(),
8706f6ba60Sopenharmony_ci                        prioNames[prio].c_str(), tag);
8806f6ba60Sopenharmony_ci    if (count < 0) {
8906f6ba60Sopenharmony_ci        return 0;
9006f6ba60Sopenharmony_ci    }
9106f6ba60Sopenharmony_ci    count = count + vfprintf(stderr, fmt, vargs) + fprintf(stderr, "\n");
9206f6ba60Sopenharmony_ci    fflush(stderr);
9306f6ba60Sopenharmony_ci    return count;
9406f6ba60Sopenharmony_ci}
9506f6ba60Sopenharmony_ci
9606f6ba60Sopenharmony_cistatic inline int HiLogPrint(int type, int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, ...)
9706f6ba60Sopenharmony_ci{
9806f6ba60Sopenharmony_ci    va_list vargs;
9906f6ba60Sopenharmony_ci    UNUSED_PARAMETER(type);
10006f6ba60Sopenharmony_ci    va_start(vargs, fmt);
10106f6ba60Sopenharmony_ci    int count = HiLogPrintArgs(prio, domain, tag, fmt, vargs);
10206f6ba60Sopenharmony_ci    va_end(vargs);
10306f6ba60Sopenharmony_ci    return count;
10406f6ba60Sopenharmony_ci}
10506f6ba60Sopenharmony_ci
10606f6ba60Sopenharmony_ci#ifndef LOG_CORE
10706f6ba60Sopenharmony_ci#define LOG_CORE 0
10806f6ba60Sopenharmony_ci#endif
10906f6ba60Sopenharmony_ci
11006f6ba60Sopenharmony_ci#define HILOG_BASE_DEBUG(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
11106f6ba60Sopenharmony_ci#define HILOG_BASE_INFO(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
11206f6ba60Sopenharmony_ci#define HILOG_BASE_WARN(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
11306f6ba60Sopenharmony_ci#define HILOG_BASE_ERROR(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
11406f6ba60Sopenharmony_ci
11506f6ba60Sopenharmony_ci#endif // HAVE_HILOG
11606f6ba60Sopenharmony_ci
11706f6ba60Sopenharmony_ci#ifndef NDEBUG
11806f6ba60Sopenharmony_ci#include <securec.h>
11906f6ba60Sopenharmony_cinamespace logging {
12006f6ba60Sopenharmony_ciinline void StringReplace(std::string& str, const std::string& oldStr, const std::string& newStr)
12106f6ba60Sopenharmony_ci{
12206f6ba60Sopenharmony_ci    std::string::size_type pos = 0u;
12306f6ba60Sopenharmony_ci    while ((pos = str.find(oldStr, pos)) != std::string::npos) {
12406f6ba60Sopenharmony_ci        str.replace(pos, oldStr.length(), newStr);
12506f6ba60Sopenharmony_ci        pos += newStr.length();
12606f6ba60Sopenharmony_ci    }
12706f6ba60Sopenharmony_ci}
12806f6ba60Sopenharmony_ci
12906f6ba60Sopenharmony_ci// let compiler check format string and variable arguments
13006f6ba60Sopenharmony_cistatic inline std::string StringFormat(const char* fmt, ...)  __attribute__((format(printf, 1, 2)));
13106f6ba60Sopenharmony_ci
13206f6ba60Sopenharmony_cistatic inline std::string StringFormat(const char* fmt, ...)
13306f6ba60Sopenharmony_ci{
13406f6ba60Sopenharmony_ci    va_list vargs;
13506f6ba60Sopenharmony_ci    char buf[1024] = {0};
13606f6ba60Sopenharmony_ci
13706f6ba60Sopenharmony_ci    if (fmt == nullptr) {
13806f6ba60Sopenharmony_ci        return "";
13906f6ba60Sopenharmony_ci    }
14006f6ba60Sopenharmony_ci    std::string format(fmt);
14106f6ba60Sopenharmony_ci    StringReplace(format, "%{public}", "%");
14206f6ba60Sopenharmony_ci
14306f6ba60Sopenharmony_ci    va_start(vargs, fmt);
14406f6ba60Sopenharmony_ci    if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) {
14506f6ba60Sopenharmony_ci        va_end(vargs);
14606f6ba60Sopenharmony_ci        return "";
14706f6ba60Sopenharmony_ci    }
14806f6ba60Sopenharmony_ci
14906f6ba60Sopenharmony_ci    va_end(vargs);
15006f6ba60Sopenharmony_ci    return buf;
15106f6ba60Sopenharmony_ci}
15206f6ba60Sopenharmony_ci}  // logging
15306f6ba60Sopenharmony_ci
15406f6ba60Sopenharmony_ci#ifdef HAVE_HILOG
15506f6ba60Sopenharmony_ci#define HILOG_PRINT_DEBUG(type, fmt, ...) \
15606f6ba60Sopenharmony_ci    HILOG_BASE_DEBUG(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
15706f6ba60Sopenharmony_ci#define HILOG_PRINT_INFO(type, fmt, ...) \
15806f6ba60Sopenharmony_ci    HILOG_BASE_INFO(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
15906f6ba60Sopenharmony_ci#define HILOG_PRINT_WARN(type, fmt, ...) \
16006f6ba60Sopenharmony_ci    HILOG_BASE_WARN(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
16106f6ba60Sopenharmony_ci#define HILOG_PRINT_ERROR(type, fmt, ...) \
16206f6ba60Sopenharmony_ci    HILOG_BASE_ERROR(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
16306f6ba60Sopenharmony_ci#else
16406f6ba60Sopenharmony_ci#define HILOG_PRINT_DEBUG(type, fmt, ...) \
16506f6ba60Sopenharmony_ci    HiLogPrint(type, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
16606f6ba60Sopenharmony_ci#define HILOG_PRINT_INFO(type, fmt, ...) \
16706f6ba60Sopenharmony_ci    HiLogPrint(type, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
16806f6ba60Sopenharmony_ci#define HILOG_PRINT_WARN(type, fmt, ...) \
16906f6ba60Sopenharmony_ci    HiLogPrint(type, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
17006f6ba60Sopenharmony_ci#define HILOG_PRINT_ERROR(type, fmt, ...) \
17106f6ba60Sopenharmony_ci    HiLogPrint(type, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
17206f6ba60Sopenharmony_ci#endif
17306f6ba60Sopenharmony_ci
17406f6ba60Sopenharmony_ci#define PROFILER_LOG_DEBUG(type, fmt, ...) HILOG_PRINT_DEBUG(type, fmt, ##__VA_ARGS__)
17506f6ba60Sopenharmony_ci#define PROFILER_LOG_INFO(type, fmt, ...) HILOG_PRINT_INFO(type, fmt, ##__VA_ARGS__)
17606f6ba60Sopenharmony_ci#define PROFILER_LOG_WARN(type, fmt, ...) HILOG_PRINT_WARN(type, fmt, ##__VA_ARGS__)
17706f6ba60Sopenharmony_ci#define PROFILER_LOG_ERROR(type, fmt, ...) HILOG_PRINT_ERROR(type, fmt, ##__VA_ARGS__)
17806f6ba60Sopenharmony_ci#endif  // NDEBUG
17906f6ba60Sopenharmony_ci
18006f6ba60Sopenharmony_ci#define STD_PTR(K, T) std::K##_ptr<T>
18106f6ba60Sopenharmony_ci
18206f6ba60Sopenharmony_ci#define NO_RETVAL /* retval */
18306f6ba60Sopenharmony_ci
18406f6ba60Sopenharmony_ci#define CHECK_NOTNULL(ptr, retval, fmt, ...)                                                                        \
18506f6ba60Sopenharmony_ci    do {                                                                                                            \
18606f6ba60Sopenharmony_ci        if (ptr == nullptr) {                                                                                       \
18706f6ba60Sopenharmony_ci            std::string str = std::string("CHECK_NOTNULL(") + logging::StringFormat(fmt, ##__VA_ARGS__) +           \
18806f6ba60Sopenharmony_ci                              ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED";                       \
18906f6ba60Sopenharmony_ci            HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str());                                                   \
19006f6ba60Sopenharmony_ci            return retval;                                                                                          \
19106f6ba60Sopenharmony_ci        }                                                                                                           \
19206f6ba60Sopenharmony_ci    } while (0)
19306f6ba60Sopenharmony_ci
19406f6ba60Sopenharmony_ci#ifndef FUZZ_TEST
19506f6ba60Sopenharmony_ci#define CHECK_TRUE(expr, retval, fmt, ...)                                                                          \
19606f6ba60Sopenharmony_ci    do {                                                                                                            \
19706f6ba60Sopenharmony_ci        if (!(expr)) {                                                                                              \
19806f6ba60Sopenharmony_ci            std::string str = std::string("CHECK_TRUE(") + logging::StringFormat(fmt, ##__VA_ARGS__) +              \
19906f6ba60Sopenharmony_ci                              ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED";                       \
20006f6ba60Sopenharmony_ci            HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str());                                                   \
20106f6ba60Sopenharmony_ci            return retval;                                                                                          \
20206f6ba60Sopenharmony_ci        }                                                                                                           \
20306f6ba60Sopenharmony_ci    } while (0)
20406f6ba60Sopenharmony_ci#else
20506f6ba60Sopenharmony_ci#define CHECK_TRUE(expr, retval, fmt, ...) \
20606f6ba60Sopenharmony_ci    do {                                   \
20706f6ba60Sopenharmony_ci        if (!(expr)) {                     \
20806f6ba60Sopenharmony_ci            return retval;                 \
20906f6ba60Sopenharmony_ci        }                                  \
21006f6ba60Sopenharmony_ci    } while (0)
21106f6ba60Sopenharmony_ci#endif  // FUZZ_TEST
21206f6ba60Sopenharmony_ci
21306f6ba60Sopenharmony_ci#define RETURN_IF(expr, retval, fmt, ...)             \
21406f6ba60Sopenharmony_ci    do {                                              \
21506f6ba60Sopenharmony_ci        if ((expr)) {                                 \
21606f6ba60Sopenharmony_ci            HILOG_BASE_WARN(LOG_CORE, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()); \
21706f6ba60Sopenharmony_ci            return retval;                            \
21806f6ba60Sopenharmony_ci        }                                             \
21906f6ba60Sopenharmony_ci    } while (0)
22006f6ba60Sopenharmony_ci
22106f6ba60Sopenharmony_ci#ifndef HAVE_HILOG
22206f6ba60Sopenharmony_cistatic std::string GetTimeString()
22306f6ba60Sopenharmony_ci{
22406f6ba60Sopenharmony_ci    char timeStr[TIME_STRING_MAX_LENGTH];
22506f6ba60Sopenharmony_ci    struct timespec ts;
22606f6ba60Sopenharmony_ci    struct tm tmStruct;
22706f6ba60Sopenharmony_ci    clock_gettime(CLOCK_REALTIME, &ts);
22806f6ba60Sopenharmony_ci#if !is_mingw
22906f6ba60Sopenharmony_ci    localtime_r(&ts.tv_sec, &tmStruct);
23006f6ba60Sopenharmony_ci#else
23106f6ba60Sopenharmony_ci    CHECK_TRUE(localtime_s(&tmStruct, &ts.tv_sec) == 0, "", "localtime_s FAILED!");
23206f6ba60Sopenharmony_ci#endif
23306f6ba60Sopenharmony_ci    size_t used = strftime(timeStr, sizeof(timeStr), "%m-%d %H:%M:%S", &tmStruct);
23406f6ba60Sopenharmony_ci    if (used >= TIME_STRING_MAX_LENGTH) {
23506f6ba60Sopenharmony_ci        return "";
23606f6ba60Sopenharmony_ci    }
23706f6ba60Sopenharmony_ci    (void)snprintf_s(&timeStr[used], sizeof(timeStr) - used, sizeof(timeStr) - used - 1, ".%03ld",
23806f6ba60Sopenharmony_ci        ts.tv_nsec / NS_PER_MS_LOG);
23906f6ba60Sopenharmony_ci    return timeStr;
24006f6ba60Sopenharmony_ci}
24106f6ba60Sopenharmony_ci#endif // !HAVE_HILOG
24206f6ba60Sopenharmony_ci#endif // OHOS_PROFILER_LOGGING_H
243