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 
24 namespace OHOS {
25 namespace UpdateEngine {
26 const std::string DEFAULT_LABEL = "%";
27 const std::string DEFAULT_FMT_LABEL = "%s";
28 const std::string PRIVATE_FMT_LABEL = "%{private}s";
29 const std::string PUBLIC_FMT_LABEL = "%{public}s";
30 
31 static constexpr uint32_t  UPDATER_SA_DOMAIN_ID = 0xD002E00;
32 enum UpdaterModuleTags {
33     UPDATE_SA_TAG = 0,
34     UPDATE_KITS_TAG,
35     UPDATE_FIRMWARE_TAG,
36     UPDATE_MODULEMGR_TAG,
37     UPDATE_MODULE_MAX
38 };
39 
40 static 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 
47 enum class UpdateLogLevel {
48     UPDATE_DEBUG = 0,
49     UPDATE_INFO,
50     UPDATE_WARN,
51     UPDATE_ERROR,
52     UPDATE_FATAL
53 };
54 
55 struct 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 
BuildWithArgsUpdateLogContent63     UpdateLogContent BuildWithArgs(const std::string &argsInput) const
64     {
65         return {label, level, log, argsInput, fileName, line};
66     };
67 
BuildWithFmtAndArgsUpdateLogContent68     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
75 constexpr int32_t UPDATE_LOG_TAG_ID = UPDATE_SA_TAG;
76 #else
77 constexpr int32_t UPDATE_LOG_TAG_ID = UPDATE_KITS_TAG;
78 #endif
79 
80 class UpdateLog {
81 public:
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 
88 private:
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 
95 private:
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