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