1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "sys_event_stat.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include <algorithm>
19020a203aSopenharmony_ci#include <cinttypes>
20020a203aSopenharmony_ci#include <cstdio>
21020a203aSopenharmony_ci#include <vector>
22020a203aSopenharmony_ci
23020a203aSopenharmony_ci#include "time_util.h"
24020a203aSopenharmony_ci
25020a203aSopenharmony_cinamespace OHOS {
26020a203aSopenharmony_cinamespace HiviewDFX {
27020a203aSopenharmony_ciconstexpr int INVALID_SIZE_LIMIT = 32;
28020a203aSopenharmony_ciconstexpr int INVALID_EVENT_SIZE_LIMIT = 512;
29020a203aSopenharmony_ci
30020a203aSopenharmony_ciSysEventStat::SysEventStat(): inValidNum_(0), validNum_(0)
31020a203aSopenharmony_ci{}
32020a203aSopenharmony_ci
33020a203aSopenharmony_ciSysEventStat::~SysEventStat()
34020a203aSopenharmony_ci{
35020a203aSopenharmony_ci    inValidNum_ = 0;
36020a203aSopenharmony_ci    validNum_ = 0;
37020a203aSopenharmony_ci}
38020a203aSopenharmony_ci
39020a203aSopenharmony_civoid SysEventStat::AccumulateEvent(bool isValid)
40020a203aSopenharmony_ci{
41020a203aSopenharmony_ci    if (isValid) {
42020a203aSopenharmony_ci        validNum_++;
43020a203aSopenharmony_ci    } else {
44020a203aSopenharmony_ci        inValidNum_++;
45020a203aSopenharmony_ci    }
46020a203aSopenharmony_ci}
47020a203aSopenharmony_ci
48020a203aSopenharmony_civoid SysEventStat::AddValidEvent(const std::string &domain, const std::string &eventName)
49020a203aSopenharmony_ci{
50020a203aSopenharmony_ci    auto it = d2es_.find(domain);
51020a203aSopenharmony_ci    if (it == d2es_.end()) {
52020a203aSopenharmony_ci        std::map<std::string, int64_t> events;
53020a203aSopenharmony_ci        events[eventName] = 1;
54020a203aSopenharmony_ci        d2es_[domain] = events;
55020a203aSopenharmony_ci        return;
56020a203aSopenharmony_ci    }
57020a203aSopenharmony_ci
58020a203aSopenharmony_ci    std::map<std::string, int64_t> &events = it->second;
59020a203aSopenharmony_ci    auto eIt = events.find(eventName);
60020a203aSopenharmony_ci    if (eIt == events.end()) {
61020a203aSopenharmony_ci        events[eventName] = 1;
62020a203aSopenharmony_ci        return;
63020a203aSopenharmony_ci    }
64020a203aSopenharmony_ci
65020a203aSopenharmony_ci    events[eventName] = events[eventName] + 1;
66020a203aSopenharmony_ci}
67020a203aSopenharmony_ci
68020a203aSopenharmony_civoid SysEventStat::AddInValidEvent(const std::string &domain, const std::string &eventName)
69020a203aSopenharmony_ci{
70020a203aSopenharmony_ci    auto it = d2ies_.find(domain);
71020a203aSopenharmony_ci    if (it == d2ies_.end()) {
72020a203aSopenharmony_ci        if (d2ies_.size() >= INVALID_SIZE_LIMIT) {
73020a203aSopenharmony_ci            return;
74020a203aSopenharmony_ci        }
75020a203aSopenharmony_ci        d2ies_[domain].append(eventName + ";");
76020a203aSopenharmony_ci        return;
77020a203aSopenharmony_ci    }
78020a203aSopenharmony_ci    if (it->second.size() >= INVALID_EVENT_SIZE_LIMIT) {
79020a203aSopenharmony_ci        return;
80020a203aSopenharmony_ci    }
81020a203aSopenharmony_ci    std::size_t pos = it->second.find(eventName + ";");
82020a203aSopenharmony_ci    if (pos == std::string::npos) {
83020a203aSopenharmony_ci        d2ies_[domain].append(eventName + ";");
84020a203aSopenharmony_ci    }
85020a203aSopenharmony_ci}
86020a203aSopenharmony_ci
87020a203aSopenharmony_civoid SysEventStat::AccumulateEvent(const std::string &domain, const std::string &eventName, bool isValid)
88020a203aSopenharmony_ci{
89020a203aSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
90020a203aSopenharmony_ci    AccumulateEvent(isValid);
91020a203aSopenharmony_ci    if (isValid) {
92020a203aSopenharmony_ci        AddValidEvent(domain, eventName);
93020a203aSopenharmony_ci    } else {
94020a203aSopenharmony_ci        AddInValidEvent(domain, eventName);
95020a203aSopenharmony_ci    }
96020a203aSopenharmony_ci}
97020a203aSopenharmony_ci
98020a203aSopenharmony_civoid SysEventStat::StatSummary(int fd)
99020a203aSopenharmony_ci{
100020a203aSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
101020a203aSopenharmony_ci    const BaseStat &stat = SysEventSummaryStat(fd, validNum_, inValidNum_, d2es_);
102020a203aSopenharmony_ci    stat.Stat();
103020a203aSopenharmony_ci}
104020a203aSopenharmony_ci
105020a203aSopenharmony_civoid SysEventStat::StatDetail(int fd)
106020a203aSopenharmony_ci{
107020a203aSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
108020a203aSopenharmony_ci    const BaseStat &stat = SysEventDetailStat(fd, validNum_, inValidNum_, d2es_);
109020a203aSopenharmony_ci    stat.Stat();
110020a203aSopenharmony_ci}
111020a203aSopenharmony_ci
112020a203aSopenharmony_civoid SysEventStat::StatInvalidDetail(int fd)
113020a203aSopenharmony_ci{
114020a203aSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
115020a203aSopenharmony_ci    const BaseStat &stat = SysEventInvalidStat(fd, validNum_, inValidNum_, d2ies_);
116020a203aSopenharmony_ci    stat.Stat();
117020a203aSopenharmony_ci}
118020a203aSopenharmony_ci
119020a203aSopenharmony_civoid SysEventStat::Clear(int fd)
120020a203aSopenharmony_ci{
121020a203aSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
122020a203aSopenharmony_ci    inValidNum_ = 0;
123020a203aSopenharmony_ci    validNum_ = 0;
124020a203aSopenharmony_ci    d2es_.clear();
125020a203aSopenharmony_ci    d2ies_.clear();
126020a203aSopenharmony_ci    dprintf(fd, "clean all stat info\n");
127020a203aSopenharmony_ci}
128020a203aSopenharmony_ci
129020a203aSopenharmony_ciBaseStat::BaseStat(int fd, int64_t validNum, int64_t inValidNum): fd_(fd), validNum_(validNum), inValidNum_(inValidNum)
130020a203aSopenharmony_ci{}
131020a203aSopenharmony_ci
132020a203aSopenharmony_ciBaseStat::~BaseStat()
133020a203aSopenharmony_ci{}
134020a203aSopenharmony_ci
135020a203aSopenharmony_civoid BaseStat::StatHead() const
136020a203aSopenharmony_ci{
137020a203aSopenharmony_ci    dprintf(fd_, "total count=%" PRId64 ", valid count=%" PRId64 ", invalid count=%" PRId64 "\n",
138020a203aSopenharmony_ci        (validNum_ + inValidNum_), validNum_, inValidNum_);
139020a203aSopenharmony_ci}
140020a203aSopenharmony_ci
141020a203aSopenharmony_civoid BaseStat::StatDetail() const
142020a203aSopenharmony_ci{
143020a203aSopenharmony_ci    dprintf(fd_, "stat from %" PRId64  " to now\n", TimeUtil::GetMilliseconds());
144020a203aSopenharmony_ci}
145020a203aSopenharmony_ci
146020a203aSopenharmony_civoid BaseStat::Stat() const
147020a203aSopenharmony_ci{
148020a203aSopenharmony_ci    StatHead();
149020a203aSopenharmony_ci    CalcStat();
150020a203aSopenharmony_ci    StatDetail();
151020a203aSopenharmony_ci}
152020a203aSopenharmony_ci
153020a203aSopenharmony_ciSysEventSummaryStat::SysEventSummaryStat(int fd, int64_t validNum, int64_t inValidNum,
154020a203aSopenharmony_ci    std::map<std::string, std::map<std::string, int64_t>> &d2es): BaseStat(fd, validNum, inValidNum), d2es_(d2es)
155020a203aSopenharmony_ci{}
156020a203aSopenharmony_ci
157020a203aSopenharmony_ciSysEventSummaryStat::~SysEventSummaryStat()
158020a203aSopenharmony_ci{}
159020a203aSopenharmony_ci
160020a203aSopenharmony_civoid SysEventSummaryStat::GetDomains(std::vector<std::string> &domains) const
161020a203aSopenharmony_ci{
162020a203aSopenharmony_ci    for (auto it = d2es_.begin(); it != d2es_.end(); it++) {
163020a203aSopenharmony_ci        domains.emplace_back(it->first);
164020a203aSopenharmony_ci    }
165020a203aSopenharmony_ci    std::sort(domains.begin(), domains.end());
166020a203aSopenharmony_ci}
167020a203aSopenharmony_ci
168020a203aSopenharmony_ciint64_t SysEventSummaryStat::GetEventCount(std::map<std::string, int64_t> &events) const
169020a203aSopenharmony_ci{
170020a203aSopenharmony_ci    int64_t total = 0;
171020a203aSopenharmony_ci    for (auto it = events.begin(); it != events.end(); it++) {
172020a203aSopenharmony_ci        total = total + it->second;
173020a203aSopenharmony_ci    }
174020a203aSopenharmony_ci    return total;
175020a203aSopenharmony_ci}
176020a203aSopenharmony_ci
177020a203aSopenharmony_civoid SysEventSummaryStat::StatDomainEvent(int fd, std::map<std::string, int64_t> &events) const
178020a203aSopenharmony_ci{}
179020a203aSopenharmony_ci
180020a203aSopenharmony_civoid SysEventSummaryStat::CalcStat() const
181020a203aSopenharmony_ci{
182020a203aSopenharmony_ci    std::vector<std::string> domains;
183020a203aSopenharmony_ci    GetDomains(domains);
184020a203aSopenharmony_ci    for (auto it = domains.begin(); it != domains.end(); it++) {
185020a203aSopenharmony_ci        auto events = d2es_.at(*it);
186020a203aSopenharmony_ci        dprintf(fd_, "*domain=%s total count=%" PRId64 "\n", it->c_str(), GetEventCount(events));
187020a203aSopenharmony_ci        StatDomainEvent(fd_, events);
188020a203aSopenharmony_ci    }
189020a203aSopenharmony_ci}
190020a203aSopenharmony_ci
191020a203aSopenharmony_ciSysEventDetailStat::SysEventDetailStat(int fd, int64_t validNum, int64_t inValidNum,
192020a203aSopenharmony_ci    std::map<std::string, std::map<std::string, int64_t>> &d2es): SysEventSummaryStat(fd, validNum, inValidNum, d2es)
193020a203aSopenharmony_ci{}
194020a203aSopenharmony_ci
195020a203aSopenharmony_ciSysEventDetailStat::~SysEventDetailStat()
196020a203aSopenharmony_ci{}
197020a203aSopenharmony_ci
198020a203aSopenharmony_civoid SysEventDetailStat::GetEventNames(std::map<std::string, int64_t> &events,
199020a203aSopenharmony_ci    std::vector<std::string> &eventNames) const
200020a203aSopenharmony_ci{
201020a203aSopenharmony_ci    for (auto it = events.begin(); it != events.end(); it++) {
202020a203aSopenharmony_ci        eventNames.emplace_back(it->first);
203020a203aSopenharmony_ci    }
204020a203aSopenharmony_ci    std::sort(eventNames.begin(), eventNames.end());
205020a203aSopenharmony_ci}
206020a203aSopenharmony_ci
207020a203aSopenharmony_civoid SysEventDetailStat::StatDomainEvent(int fd, std::map<std::string, int64_t> &events) const
208020a203aSopenharmony_ci{
209020a203aSopenharmony_ci    std::vector<std::string> eventNames;
210020a203aSopenharmony_ci    GetEventNames(events, eventNames);
211020a203aSopenharmony_ci    for (auto it = eventNames.begin(); it != eventNames.end(); it++) {
212020a203aSopenharmony_ci        auto count = events.at(*it);
213020a203aSopenharmony_ci        dprintf(fd, "    event=%s, count=%" PRId64 "\n", it->c_str(), count);
214020a203aSopenharmony_ci    }
215020a203aSopenharmony_ci}
216020a203aSopenharmony_ci
217020a203aSopenharmony_ciSysEventInvalidStat::SysEventInvalidStat(int fd, int64_t validNum, int64_t inValidNum,
218020a203aSopenharmony_ci    std::map<std::string, std::string> &d2ies): BaseStat(fd, validNum, inValidNum), d2ies_(d2ies)
219020a203aSopenharmony_ci{}
220020a203aSopenharmony_ci
221020a203aSopenharmony_ciSysEventInvalidStat::~SysEventInvalidStat()
222020a203aSopenharmony_ci{}
223020a203aSopenharmony_ci
224020a203aSopenharmony_civoid SysEventInvalidStat::CalcStat() const
225020a203aSopenharmony_ci{
226020a203aSopenharmony_ci    std::vector<std::string> domains;
227020a203aSopenharmony_ci    for (auto it = d2ies_.begin(); it != d2ies_.end(); it++) {
228020a203aSopenharmony_ci        domains.emplace_back(it->first);
229020a203aSopenharmony_ci    }
230020a203aSopenharmony_ci    std::sort(domains.begin(), domains.end());
231020a203aSopenharmony_ci    for (auto it = domains.begin(); it != domains.end(); it++) {
232020a203aSopenharmony_ci        std::string invalidEvent = d2ies_.at(*it);
233020a203aSopenharmony_ci        dprintf(fd_, "*invalid event name of domain=%s\n", it->c_str());
234020a203aSopenharmony_ci        dprintf(fd_, "%s\n", invalidEvent.c_str());
235020a203aSopenharmony_ci    }
236020a203aSopenharmony_ci}
237020a203aSopenharmony_ci} // namespace HiviewDFX
238020a203aSopenharmony_ci} // namespace OHOS