1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 "ptreader_hilog_parser.h"
17 #include "process_filter.h"
18 #include "stat_filter.h"
19
20 namespace SysTuning {
21 namespace TraceStreamer {
PtreaderHilogParser(TraceDataCache * dataCache,const TraceStreamerFilters * filters)22 PtreaderHilogParser::PtreaderHilogParser(TraceDataCache *dataCache, const TraceStreamerFilters *filters)
23 : EventParserBase(dataCache, filters)
24 {
25 }
26
27 PtreaderHilogParser::~PtreaderHilogParser() = default;
28
HilogTimeStrToTimestamp(std::string & timeStr,uint64_t & timeStamp) const29 bool PtreaderHilogParser::HilogTimeStrToTimestamp(std::string &timeStr, uint64_t &timeStamp) const
30 {
31 uint64_t sec;
32 uint64_t nsec;
33 std::string usecStr;
34 std::smatch matcheLine;
35 if (std::regex_search(timeStr, matcheLine, std::regex(R"(^\d+\.(\d+)$)"))) {
36 size_t index = 0;
37 usecStr = matcheLine[++index].str();
38 sscanf_s(timeStr.c_str(), "%" PRIu64 ".%" PRIu64 "", &sec, &nsec);
39 } else if (std::regex_search(timeStr, matcheLine,
40 std::regex(R"(^(\d{4})?\-?(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\.(\d+)$)"))) {
41 size_t index = 0;
42 std::string yearStr = matcheLine[++index].str();
43 std::string monthStr = matcheLine[++index].str();
44 std::string dayStr = matcheLine[++index].str();
45 std::string hourStr = matcheLine[++index].str();
46 std::string minStr = matcheLine[++index].str();
47 std::string secStr = matcheLine[++index].str();
48 usecStr = matcheLine[++index].str();
49 tm timeInfo = {0};
50 std::optional<uint32_t> optionalYear = base::StrToInt<uint32_t>(yearStr);
51 if (optionalYear.has_value()) {
52 timeInfo.tm_year = optionalYear.value() - TM_YEAR_FROM;
53 } else {
54 auto tmNow = time(nullptr);
55 tm *ptmNow = localtime(&tmNow);
56 timeInfo.tm_year = ptmNow->tm_year;
57 }
58 timeInfo.tm_mon = base::StrToInt<uint32_t>(monthStr).value() - 1;
59 timeInfo.tm_mday = base::StrToInt<uint32_t>(dayStr).value();
60 timeInfo.tm_hour = base::StrToInt<uint32_t>(hourStr).value();
61 timeInfo.tm_min = base::StrToInt<uint32_t>(minStr).value();
62 timeInfo.tm_sec = base::StrToInt<uint32_t>(secStr).value();
63 sec = std::mktime(&timeInfo);
64 nsec = base::StrToInt<uint64_t>(usecStr).value();
65 } else {
66 return false;
67 }
68
69 if (usecStr.length() == MS_FORMAT_LEN) {
70 nsec *= MS_TO_NS;
71 } else if (usecStr.length() == US_FORMAT_LEN) {
72 nsec *= US_TO_NS;
73 }
74
75 timeStamp = nsec + sec * SEC_TO_NS;
76 return true;
77 }
78
ParseHilogDataItem(const std::string & buffer,const uint64_t lineSeq,bool & haveSplitSeg)79 void PtreaderHilogParser::ParseHilogDataItem(const std::string &buffer, const uint64_t lineSeq, bool &haveSplitSeg)
80 {
81 std::smatch matcheLine;
82 if (!std::regex_search(buffer, matcheLine, hilogMatcher_)) {
83 TS_LOGD("Not support this hilog format (line: %s)", buffer.c_str());
84 return;
85 }
86
87 auto bufLine = std::make_unique<HilogLine>();
88 bufLine->lineSeq = lineSeq;
89
90 std::string timeStr = matcheLine[HILOG_MATCH_SEQ_TIME].str();
91 HilogTimeStrToTimestamp(timeStr, bufLine->timeStamp);
92 if (traceDataCache_->isSplitFile_) {
93 if (traceDataCache_->SplitFileMinTime() <= bufLine->timeStamp &&
94 traceDataCache_->SplitFileMaxTime() >= bufLine->timeStamp) {
95 haveSplitSeg = true;
96 }
97 return;
98 }
99
100 std::string pidStr = matcheLine[HILOG_MATCH_SEQ_PID].str();
101 std::optional<uint32_t> optionalPid = base::StrToInt<uint32_t>(pidStr);
102 if (!optionalPid.has_value()) {
103 TS_LOGD("Illegal pid: %s", pidStr.c_str());
104 return;
105 }
106 bufLine->pid = optionalPid.value();
107
108 std::string tidStr = matcheLine[HILOG_MATCH_SEQ_TID].str();
109 std::optional<uint32_t> optionalTid = base::StrToInt<uint32_t>(tidStr);
110 if (!optionalTid.has_value()) {
111 TS_LOGD("Illegal tid: %s", tidStr.c_str());
112 return;
113 }
114 bufLine->tid = optionalTid.value();
115
116 streamFilters_->processFilter_->GetOrCreateThreadWithPid(bufLine->tid, bufLine->pid);
117
118 bufLine->level = matcheLine[HILOG_MATCH_SEQ_LEVEL].str();
119 bufLine->tag = matcheLine[HILOG_MATCH_SEQ_TAG].str();
120 bufLine->context = matcheLine[HILOG_MATCH_SEQ_CONTENT].str();
121
122 FilterHilogData(std::move(bufLine));
123 return;
124 }
125
FilterHilogData(std::unique_ptr<HilogLine> bufLine)126 void PtreaderHilogParser::FilterHilogData(std::unique_ptr<HilogLine> bufLine)
127 {
128 hilogList_.push_back(std::move(bufLine));
129 return;
130 }
131
FilterAllHilogData()132 void PtreaderHilogParser::FilterAllHilogData()
133 {
134 auto cmp = [](const std::unique_ptr<HilogLine> &a, const std::unique_ptr<HilogLine> &b) {
135 return a->timeStamp < b->timeStamp;
136 };
137 std::sort(hilogList_.begin(), hilogList_.end(), cmp);
138 for (auto &item : hilogList_) {
139 HilogLine *hilogData = item.get();
140 BeginFilterHilogData(hilogData);
141 }
142
143 hilogList_.clear();
144 }
145
BeginFilterHilogData(HilogLine * hilogData)146 void PtreaderHilogParser::BeginFilterHilogData(HilogLine *hilogData)
147 {
148 streamFilters_->statFilter_->IncreaseStat(TRACE_HILOG, STAT_EVENT_RECEIVED);
149 traceDataCache_->UpdateTraceTime(hilogData->timeStamp);
150 auto curLineSeq = hilogData->lineSeq;
151 auto newTimeStamp = hilogData->timeStamp;
152 auto levelData = traceDataCache_->dataDict_.GetStringIndex(hilogData->level);
153 auto logTag = traceDataCache_->dataDict_.GetStringIndex(hilogData->tag);
154 auto logData = traceDataCache_->dataDict_.GetStringIndex(hilogData->context);
155 LogInfoRow logInfoRow = {curLineSeq, newTimeStamp, hilogData->pid, hilogData->tid,
156 levelData, logTag, logData, hilogData->timeStamp};
157 traceDataCache_->GetHilogData()->AppendNewLogInfo(logInfoRow);
158 return;
159 }
160 } // namespace TraceStreamer
161 } // namespace SysTuning
162