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 #include "update_log.h"
17 
18 namespace OHOS {
19 namespace UpdateEngine {
20 UpdateLogLevel UpdateLog::level_ = UpdateLogLevel::UPDATE_INFO;
21 constexpr int32_t COUNT_ONE = 1;
22 constexpr int32_t LONG_LOG_LEN = 900;
23 
JudgeLevel(const UpdateLogLevel & level)24 bool UpdateLog::JudgeLevel(const UpdateLogLevel &level)
25 {
26     const UpdateLogLevel &curLevel = GetLogLevel();
27     if (level <= curLevel) {
28         return true;
29     }
30     return true;
31 }
32 
SetLogLevel(const UpdateLogLevel & level)33 void UpdateLog::SetLogLevel(const UpdateLogLevel &level)
34 {
35     level_ = level;
36 }
37 
GetLogLevel()38 const UpdateLogLevel &UpdateLog::GetLogLevel()
39 {
40     return level_;
41 }
42 
GetBriefFileName(const std::string & file)43 std::string UpdateLog::GetBriefFileName(const std::string &file)
44 {
45     auto pos = file.find_last_of("/");
46     if (pos != std::string::npos) {
47         return file.substr(pos + 1);
48     }
49     pos = file.find_last_of("\\");
50     if (pos != std::string::npos) {
51         return file.substr(pos + 1);
52     }
53     return file;
54 }
55 
PrintLongLog(const uint32_t subModuleTag,const UpdateLogContent & logContent)56 void UpdateLog::PrintLongLog(const uint32_t subModuleTag, const UpdateLogContent &logContent)
57 {
58     std::string fmtLabel = GetFmtLabel(logContent.log);
59     std::pair<std::string, std::string> splitLogPair = SplitLogByFmtLabel(logContent.log, fmtLabel);
60 
61     PrintLog(subModuleTag, logContent.BuildWithFmtAndArgs(PUBLIC_FMT_LABEL, splitLogPair.first));     // log前缀不做打印控制
62     PrintLog(subModuleTag, logContent.BuildWithFmtAndArgs(fmtLabel, logContent.args));                // args采用fmt进行控制
63     PrintLog(subModuleTag, logContent.BuildWithFmtAndArgs(PUBLIC_FMT_LABEL, splitLogPair.second));    // log后缀不做打印控制
64 }
65 
PrintLog(const uint32_t subModuleTag,const UpdateLogContent & logContent)66 void UpdateLog::PrintLog(const uint32_t subModuleTag, const UpdateLogContent &logContent)
67 {
68     int32_t printPos = 0;
69     int32_t len = static_cast<int32_t>(logContent.args.length());
70     while (printPos < len) {
71         int32_t printLen = std::min(len - printPos, LONG_LOG_LEN);
72         PrintSingleLine(subModuleTag, logContent.BuildWithArgs(logContent.args.substr(printPos, printLen)));
73         printPos += printLen;
74     }
75 }
76 
PrintSingleLine(const uint32_t subModuleTag,const UpdateLogContent & logContent)77 void UpdateLog::PrintSingleLine(const uint32_t subModuleTag, const UpdateLogContent &logContent)
78 {
79     // BASE_PRINT_LOG的第三个参数是hilog方法名,即hilogMethod
80     std::string fmtLabel = GetFmtLabel(logContent.log);
81     switch (logContent.level) {
82         case UpdateLogLevel::UPDATE_DEBUG:
83             LONG_PRINT_HILOG(LOG_DEBUG, subModuleTag, logContent.log,
84                 UpdateLog::GetBriefFileName(logContent.fileName).c_str(), logContent.line, logContent.args.c_str());
85             break;
86         case UpdateLogLevel::UPDATE_INFO:
87             LONG_PRINT_HILOG(LOG_INFO, subModuleTag, logContent.log,
88                 UpdateLog::GetBriefFileName(logContent.fileName).c_str(), logContent.line, logContent.args.c_str());
89             break;
90         case UpdateLogLevel::UPDATE_ERROR:
91             LONG_PRINT_HILOG(LOG_ERROR, subModuleTag, logContent.log,
92                 UpdateLog::GetBriefFileName(logContent.fileName).c_str(), logContent.line, logContent.args.c_str());
93             break;
94         default:
95             break;
96     }
97 }
98 
SplitLogByFmtLabel(const std::string & log,const std::string & fmtLabel)99 std::pair<std::string, std::string> UpdateLog::SplitLogByFmtLabel(const std::string &log, const std::string &fmtLabel)
100 {
101     if (fmtLabel.empty()) {
102         // 如果log中没有%{public|private}s,则把log全部内容作为前缀字符串,后缀字符串为空
103         return std::make_pair(log, "");
104     }
105     return std::make_pair(log.substr(0, log.find(fmtLabel, 0)), log.substr(log.find(fmtLabel, 0) +
106         fmtLabel.length()));
107 }
108 
GetFmtLabel(const std::string & log)109 std::string UpdateLog::GetFmtLabel(const std::string &log)
110 {
111     if (FindSubStrCount(log, DEFAULT_LABEL) != COUNT_ONE) {
112         // 如果log中%字符出现次数不为一个,说明log格式有误,返回空的fmtLabel
113         return "";
114     }
115     if (FindSubStrCount(log, DEFAULT_FMT_LABEL) == COUNT_ONE) {
116         return DEFAULT_FMT_LABEL;
117     }
118     if (FindSubStrCount(log, PRIVATE_FMT_LABEL) == COUNT_ONE) {
119         return PRIVATE_FMT_LABEL;
120     }
121     if (FindSubStrCount(log, PUBLIC_FMT_LABEL) == COUNT_ONE) {
122         return PUBLIC_FMT_LABEL;
123     }
124     return "";
125 }
126 
FindSubStrCount(const std::string & str,const std::string & subStr)127 int32_t UpdateLog::FindSubStrCount(const std::string &str, const std::string &subStr)
128 {
129     int32_t count = 0;
130     for (size_t pos = 0; (pos = str.find(subStr, pos)) != std::string::npos; pos++) {
131         count++;
132     }
133     return count;
134 }
135 } // namespace UpdateEngine
136 } // namespace OHOS
137