• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <chrono>
17 #include <cstdint>
18 #include <ctime>
19 #include <iomanip>
20 #include <iostream>
21 #include <map>
22 #include <string>
23 
24 #include "transaction/rs_transaction_metric_collector.h"
25 #include "hilog/log.h"
26 #include "platform/common/rs_log.h"
27 #include "platform/common/rs_system_properties.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32     const uint64_t PRECISION = 2;
33 
34     const uint64_t COLLECT_INTERVAL = 5000;
35 
36     const uint64_t MS_UNIT = 1000;
37 
NowInMs()38     uint64_t NowInMs()
39     {
40         auto now = std::chrono::system_clock::now();
41         auto nowCastMs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
42         uint64_t msNow = (uint64_t) (nowCastMs.time_since_epoch().count());
43         return msNow;
44     }
45 
MsToString(uint64_t ms)46     std::string MsToString(uint64_t ms)
47     {
48         std::chrono::duration<uint64_t, std::milli> dur(ms);
49         auto tp = std::chrono::system_clock::time_point(
50             std::chrono::duration_cast<std::chrono::system_clock::duration>(dur));
51         std::time_t t = std::chrono::system_clock::to_time_t(tp);
52         std::stringstream ss;
53         ss << std::put_time(std::localtime(&t), "%Y-%m-%d %H.%M.%S") << "." << ms % MS_UNIT;
54         return ss.str();
55     }
56 }
57 
RSTransactionMetricPid()58 RSTransactionMetricPid::RSTransactionMetricPid() : prevTxTimestamp_(0)
59 {
60 }
61 
Initiate(uint64_t rsTxSize,uint64_t currentTimestamp)62 void RSTransactionMetricPid::Initiate(uint64_t rsTxSize, uint64_t currentTimestamp)
63 {
64     prevTxTimestamp_ = currentTimestamp;
65     rsTxCount_ = 1;
66     rsTxIntervalSum_ = 0;
67     minRsTxInterval_ = std::numeric_limits<uint64_t>::max();
68     maxRsTxInterval_ = std::numeric_limits<uint64_t>::min();
69     rsTxSizeSum_ = rsTxSize;
70     minRsTxSize_ = rsTxSize;
71     maxRsTxSize_ = rsTxSize;
72 }
73 
Update(uint64_t rsTxSize,uint64_t currentTimestamp)74 void RSTransactionMetricPid::Update(uint64_t rsTxSize, uint64_t currentTimestamp)
75 {
76     if (prevTxTimestamp_ == 0) {
77         Initiate(rsTxSize, currentTimestamp);
78         return;
79     }
80     uint64_t currentInterval = currentTimestamp - prevTxTimestamp_;
81     rsTxCount_++;
82     rsTxIntervalSum_ += currentInterval;
83     minRsTxInterval_ = minRsTxInterval_ < currentInterval ? minRsTxInterval_ : currentInterval;
84     maxRsTxInterval_ = maxRsTxInterval_ < currentInterval ? currentInterval : maxRsTxInterval_;
85 
86     rsTxSizeSum_ += rsTxSize;
87     minRsTxSize_ = minRsTxSize_ < rsTxSize ? minRsTxSize_ : rsTxSize;
88     maxRsTxSize_ = maxRsTxSize_ < rsTxSize ? rsTxSize : maxRsTxSize_;
89     prevTxTimestamp_ = currentTimestamp;
90 }
91 
ToString() const92 std::string RSTransactionMetricPid::ToString() const
93 {
94     double avgCmd = 0;
95     if (rsTxCount_ > 0) {
96         avgCmd = static_cast<double>(rsTxSizeSum_) / static_cast<double>(rsTxCount_);
97     }
98     uint64_t minRsTxInterval = 0;
99     uint64_t maxRsTxInterval = 0;
100     if (rsTxCount_ > 1) {
101         minRsTxInterval = minRsTxInterval_;
102         maxRsTxInterval = maxRsTxInterval_;
103     }
104 
105     std::stringstream stream;
106     stream << "count:" << rsTxCount_ << ", ";
107     stream << "minInterval:" << minRsTxInterval << ", ";
108     stream << "maxInterval:" << maxRsTxInterval << ", ";
109     stream << "minCmd:" << minRsTxSize_ << ", ";
110     stream << "maxCmd:" << maxRsTxSize_ << ", ";
111     stream << "totalCmd:" << rsTxSizeSum_ << ", ";
112     stream << "avgCmd:" << std::fixed << std::setprecision(PRECISION) << avgCmd;
113     return stream.str();
114 }
115 
GetInstance()116 RSTransactionMetricCollector &RSTransactionMetricCollector::GetInstance()
117 {
118     static RSTransactionMetricCollector instance;
119     return instance;
120 }
121 
RSTransactionMetricCollector()122 RSTransactionMetricCollector::RSTransactionMetricCollector() : collectStartTimestamp_(0)
123 {
124 }
125 
Reset(uint64_t ms)126 void RSTransactionMetricCollector::Reset(uint64_t ms)
127 {
128     collectStartTimestamp_ = ms;
129     collectEndTimestamp_ = ms;
130     pidMetrics_.clear();
131 }
132 
Collect(std::unique_ptr<RSTransactionData> & rsTransactionData)133 void RSTransactionMetricCollector::Collect(std::unique_ptr<RSTransactionData> &rsTransactionData)
134 {
135     if (!RSSystemProperties::IsBetaRelease()) {
136         return;
137     }
138     uint64_t currentTimestamp = NowInMs();
139     if (collectStartTimestamp_ == 0) {
140         Reset(currentTimestamp);
141     }
142 
143     uint64_t sinceStart = currentTimestamp - collectStartTimestamp_;
144     pid_t sendingPid = rsTransactionData->GetSendingPid();
145     uint64_t rsTxSize = rsTransactionData->GetCommandCount();
146     pid_t fakePidAsAll = -1;
147     for (const pid_t &pid: {fakePidAsAll, sendingPid}) {
148         pidMetrics_[pid].Update(rsTxSize, currentTimestamp);
149     }
150 
151     if (sinceStart > COLLECT_INTERVAL) {
152         collectEndTimestamp_ = currentTimestamp;
153         Log();
154         Reset(currentTimestamp);
155         return;
156     }
157 }
158 
Log()159 void RSTransactionMetricCollector::Log()
160 {
161     std::string collectStartTimestamp = MsToString(collectStartTimestamp_);
162     std::string collectEndTimestamp = MsToString(collectEndTimestamp_);
163 
164     std::map<pid_t, RSTransactionMetricPid> ordered(pidMetrics_.begin(), pidMetrics_.end());
165     for (auto it = ordered.begin(); it != ordered.end(); ++it) {
166         RS_LOGI("[%{public}s - %{public}s], %{public}d %{public}s",
167             collectStartTimestamp.c_str(), collectEndTimestamp.c_str(),
168                 (std::int32_t)(it->first), it->second.ToString().c_str());
169     }
170 }
171 
172 } // namespace Rosen
173 } // namespace OHOS