1/*
2 * Copyright (c) 2023 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 UPDATE_LOG_H
17#define UPDATE_LOG_H
18
19#include <cstdint>
20#include <string>
21
22#include "hilog/log.h"
23
24namespace OHOS {
25namespace UpdateEngine {
26const std::string DEFAULT_LABEL = "%";
27const std::string DEFAULT_FMT_LABEL = "%s";
28const std::string PRIVATE_FMT_LABEL = "%{private}s";
29const std::string PUBLIC_FMT_LABEL = "%{public}s";
30
31static constexpr uint32_t  UPDATER_SA_DOMAIN_ID = 0xD002E00;
32enum UpdaterModuleTags {
33    UPDATE_SA_TAG = 0,
34    UPDATE_KITS_TAG,
35    UPDATE_FIRMWARE_TAG,
36    UPDATE_MODULEMGR_TAG,
37    UPDATE_MODULE_MAX
38};
39
40static constexpr OHOS::HiviewDFX::HiLogLabel UPDATE_LABEL[UPDATE_MODULE_MAX] = {
41    { LOG_CORE, UPDATER_SA_DOMAIN_ID, "UPDATE_SERVICE_SA" },
42    { LOG_CORE, UPDATER_SA_DOMAIN_ID, "UPDATE_SERVICE_KITS" },
43    { LOG_CORE, UPDATER_SA_DOMAIN_ID, "UPDATE_SERVICE_FIRMWARE" },
44    { LOG_CORE, UPDATER_SA_DOMAIN_ID, "UPDATE_SERVICE_MODULE_MGR" }
45};
46
47enum class UpdateLogLevel {
48    UPDATE_DEBUG = 0,
49    UPDATE_INFO,
50    UPDATE_WARN,
51    UPDATE_ERROR,
52    UPDATE_FATAL
53};
54
55struct UpdateLogContent {
56    HiviewDFX::HiLogLabel label;
57    UpdateLogLevel level;
58    std::string log;
59    std::string args;
60    std::string fileName;
61    int32_t line;
62
63    UpdateLogContent BuildWithArgs(const std::string &argsInput) const
64    {
65        return {label, level, log, argsInput, fileName, line};
66    };
67
68    UpdateLogContent BuildWithFmtAndArgs(const std::string &logInput, const std::string &argsInput) const
69    {
70        return {label, level, logInput, argsInput, fileName, line};
71    };
72};
73
74#ifdef UPDATE_SERVICE
75constexpr int32_t UPDATE_LOG_TAG_ID = UPDATE_SA_TAG;
76#else
77constexpr int32_t UPDATE_LOG_TAG_ID = UPDATE_KITS_TAG;
78#endif
79
80class UpdateLog {
81public:
82    static bool JudgeLevel(const UpdateLogLevel &level);
83    static void SetLogLevel(const UpdateLogLevel &level);
84    static const UpdateLogLevel &GetLogLevel();
85    static std::string GetBriefFileName(const std::string &file);
86    static void PrintLongLog(const uint32_t subModuleTag, const UpdateLogContent &logContent);
87
88private:
89    static void PrintLog(const uint32_t subModuleTag, const UpdateLogContent &logContent);
90    static void PrintSingleLine(const uint32_t subModuleTag, const UpdateLogContent &logContent);
91    static std::pair<std::string, std::string> SplitLogByFmtLabel(const std::string &log, const std::string &fmtLabel);
92    static std::string GetFmtLabel(const std::string &log);
93    static int32_t FindSubStrCount(const std::string &str, const std::string &subStr);
94
95private:
96    static UpdateLogLevel level_;
97};
98
99#define R_FILENAME    (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
100
101#define LONG_PRINT_HILOG(level, subtag, fmtlabel, fileName, line, fmt, ...) \
102    if (fmtlabel == PUBLIC_FMT_LABEL) { \
103        BASE_PRINT_LOG(level, subtag, fileName, line, "%{public}s", fmt, ##__VA_ARGS__); \
104    } else if (fmtlabel == PRIVATE_FMT_LABEL) { \
105        BASE_PRINT_LOG(level, subtag, fileName, line, "%{private}s", fmt, ##__VA_ARGS__); \
106    } else { \
107        BASE_PRINT_LOG(level, subtag, fileName, line, "%s", fmt, ##__VA_ARGS__); \
108    }
109
110#define BASE_PRINT_LOG(level, subtag, fileName, line, fmt, ...) \
111    (void)HILOG_IMPL(LOG_CORE, level, UPDATE_LABEL[subtag].domain, UPDATE_LABEL[subtag].tag, \
112    "[%{public}s(%{public}d)]" fmt, fileName, line, ##__VA_ARGS__)
113
114#define PRINT_LOGE(subtag, fmt, ...) BASE_PRINT_LOG(LOG_ERROR, subtag, R_FILENAME, __LINE__, fmt, ##__VA_ARGS__)
115#define PRINT_LOGI(subtag, fmt, ...) BASE_PRINT_LOG(LOG_INFO, subtag, R_FILENAME, __LINE__, fmt, ##__VA_ARGS__)
116#define PRINT_LOGD(subtag, fmt, ...) BASE_PRINT_LOG(LOG_DEBUG, subtag, R_FILENAME, __LINE__, fmt, ##__VA_ARGS__)
117
118#define ENGINE_LOGE(fmt, ...) PRINT_LOGE(UPDATE_LOG_TAG_ID, fmt, ##__VA_ARGS__)
119#define ENGINE_LOGI(fmt, ...) PRINT_LOGI(UPDATE_LOG_TAG_ID, fmt, ##__VA_ARGS__)
120#define ENGINE_LOGD(fmt, ...) PRINT_LOGD(UPDATE_LOG_TAG_ID, fmt, ##__VA_ARGS__)
121
122#define PRINT_LONG_LOGD(subtag, label, fmt, args) UpdateLog::PrintLongLog(subtag, {label,    \
123    UpdateLogLevel::UPDATE_DEBUG, std::string(fmt), std::string(args), std::string(__FILE__), __LINE__})
124#define PRINT_LONG_LOGI(subtag, label, fmt, args) UpdateLog::PrintLongLog(subtag, {label,    \
125    UpdateLogLevel::UPDATE_INFO, std::string(fmt), std::string(args), std::string(__FILE__), __LINE__})
126#define PRINT_LONG_LOGE(subtag, label, fmt, args) UpdateLog::PrintLongLog(subtag, {label,    \
127    UpdateLogLevel::UPDATE_ERROR, std::string(fmt), std::string(args), std::string(__FILE__), __LINE__})
128
129#define ENGINE_LONG_LOGD(fmt, args) PRINT_LONG_LOGD(UPDATE_LOG_TAG_ID, UPDATE_LABEL[UPDATE_LOG_TAG_ID], fmt, args)
130#define ENGINE_LONG_LOGI(fmt, args) PRINT_LONG_LOGI(UPDATE_LOG_TAG_ID, UPDATE_LABEL[UPDATE_LOG_TAG_ID], fmt, args)
131#define ENGINE_LONG_LOGE(fmt, args) PRINT_LONG_LOGE(UPDATE_LOG_TAG_ID, UPDATE_LABEL[UPDATE_LOG_TAG_ID], fmt, args)
132} // namespace UpdateEngine
133} // namespace OHOS
134#endif // UPDATE_LOG_H