• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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