1 /*
2 * Copyright (c) 2022-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 "net_stats_cached.h"
17
18 #include <initializer_list>
19 #include <list>
20 #include <pthread.h>
21
22 #include "net_stats_constants.h"
23 #include "net_stats_data_handler.h"
24 #include "net_stats_database_defines.h"
25 #include "net_stats_database_helper.h"
26 #include "netsys_controller.h"
27 #include "bpf_stats.h"
28
29 namespace OHOS {
30 namespace NetManagerStandard {
31 using namespace NetStatsDatabaseDefines;
32 namespace {
33 constexpr const char *IFACE_LO = "lo";
34 } // namespace
35
StartCached()36 int32_t NetStatsCached::StartCached()
37 {
38 auto helper = std::make_unique<NetStatsDatabaseHelper>(NET_STATS_DATABASE_PATH);
39 auto ret = helper->CreateTable(UID_TABLE, UID_TABLE_CREATE_PARAM);
40 if (ret != NETMANAGER_SUCCESS) {
41 NETMGR_LOG_E("Create uid table failed");
42 return STATS_ERR_CREATE_TABLE_FAIL;
43 }
44 ret = helper->CreateTable(IFACE_TABLE, IFACE_TABLE_CREATE_PARAM);
45 if (ret != 0) {
46 NETMGR_LOG_E("Create iface table failed");
47 return STATS_ERR_CREATE_TABLE_FAIL;
48 }
49 cacheTimer_ = std::make_unique<Timer>();
50 writeTimer_ = std::make_unique<Timer>();
51 cacheTimer_->Start(cycleThreshold_, [this]() { CacheStats(); });
52 writeTimer_->Start(STATS_PACKET_CYCLE_MS, [this]() { WriteStats(); });
53 return ret;
54 }
55
GetUidStatsCached(std::vector<NetStatsInfo> & uidStatsInfo)56 void NetStatsCached::GetUidStatsCached(std::vector<NetStatsInfo> &uidStatsInfo)
57 {
58 uidStatsInfo.insert(uidStatsInfo.end(), stats_.GetUidStatsInfo().begin(), stats_.GetUidStatsInfo().end());
59 }
60
GetIfaceStatsCached(std::vector<NetStatsInfo> & ifaceStatsInfo)61 void NetStatsCached::GetIfaceStatsCached(std::vector<NetStatsInfo> &ifaceStatsInfo)
62 {
63 ifaceStatsInfo.insert(ifaceStatsInfo.end(), stats_.GetIfaceStatsInfo().begin(), stats_.GetIfaceStatsInfo().end());
64 }
65
CacheUidStats()66 void NetStatsCached::CacheUidStats()
67 {
68 std::vector<NetStatsInfo> statsInfos;
69 NetsysController::GetInstance().GetAllStatsInfo(statsInfos);
70 if (statsInfos.empty()) {
71 NETMGR_LOG_W("No stats need to save");
72 return;
73 }
74
75 std::for_each(statsInfos.begin(), statsInfos.end(), [this](NetStatsInfo &info) {
76 if (info.iface_ == IFACE_LO) {
77 return;
78 }
79 auto findRet = std::find_if(lastUidStatsInfo_.begin(), lastUidStatsInfo_.end(),
80 [this, &info](const NetStatsInfo &lastInfo) { return info.Equals(lastInfo); });
81 if (findRet == lastUidStatsInfo_.end()) {
82 stats_.PushUidStats(info);
83 return;
84 }
85 auto currentStats = info - *findRet;
86 stats_.PushUidStats(currentStats);
87 });
88 lastUidStatsInfo_.clear();
89 lastUidStatsInfo_ = std::move(statsInfos);
90 }
91
CacheIfaceStats()92 void NetStatsCached::CacheIfaceStats()
93 {
94 std::vector<std::string> ifNameList = NetsysController::GetInstance().InterfaceGetList();
95 std::for_each(ifNameList.begin(), ifNameList.end(), [this](const auto &ifName) {
96 if (ifName == IFACE_LO) {
97 return;
98 }
99 NetStatsInfo statsInfo;
100 statsInfo.iface_ = ifName;
101 NetsysController::GetInstance().GetIfaceStats(statsInfo.rxBytes_,
102 static_cast<uint32_t>(StatsType::STATS_TYPE_RX_BYTES), ifName);
103 NetsysController::GetInstance().GetIfaceStats(statsInfo.rxPackets_,
104 static_cast<uint32_t>(StatsType::STATS_TYPE_RX_PACKETS), ifName);
105 NetsysController::GetInstance().GetIfaceStats(statsInfo.txBytes_,
106 static_cast<uint32_t>(StatsType::STATS_TYPE_TX_BYTES), ifName);
107 NetsysController::GetInstance().GetIfaceStats(statsInfo.txPackets_,
108 static_cast<uint32_t>(StatsType::STATS_TYPE_TX_PACKETS), ifName);
109 auto findRet = lastIfaceStatsMap_.find(ifName);
110 if (findRet == lastIfaceStatsMap_.end()) {
111 stats_.PushIfaceStats(statsInfo);
112 lastIfaceStatsMap_[ifName] = statsInfo;
113 return;
114 }
115 auto currentStats = statsInfo - findRet->second;
116 stats_.PushIfaceStats(currentStats);
117 lastIfaceStatsMap_[ifName] = statsInfo;
118 });
119 }
120
CacheStats()121 void NetStatsCached::CacheStats()
122 {
123 std::unique_lock<std::mutex> lock(lock_);
124 CacheUidStats();
125 CacheIfaceStats();
126 }
127
WriteStats()128 void NetStatsCached::WriteStats()
129 {
130 std::unique_lock<std::mutex> lock(lock_);
131 WriteUidStats();
132 WriteIfaceStats();
133 }
WriteIfaceStats()134 void NetStatsCached::WriteIfaceStats()
135 {
136 if (!(CheckIfaceStor() || isForce_)) {
137 return;
138 }
139 auto handler = std::make_unique<NetStatsDataHandler>();
140 handler->WriteStatsData(stats_.GetIfaceStatsInfo(), NetStatsDatabaseDefines::IFACE_TABLE);
141 handler->DeleteByDate(NetStatsDatabaseDefines::IFACE_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
142 stats_.ResetIfaceStats();
143 }
144
WriteUidStats()145 void NetStatsCached::WriteUidStats()
146 {
147 if (!(CheckUidStor() || isForce_)) {
148 return;
149 }
150 auto handler = std::make_unique<NetStatsDataHandler>();
151 handler->WriteStatsData(stats_.GetUidStatsInfo(), NetStatsDatabaseDefines::UID_TABLE);
152 handler->DeleteByDate(NetStatsDatabaseDefines::UID_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
153 stats_.ResetUidStats();
154 }
155
SetCycleThreshold(uint32_t threshold)156 void NetStatsCached::SetCycleThreshold(uint32_t threshold)
157 {
158 NETMGR_LOG_D("Current cycle threshold has changed current is : %{public}d", threshold);
159 cycleThreshold_ = threshold;
160 cacheTimer_ = std::make_unique<Timer>();
161 cacheTimer_->Start(cycleThreshold_, [this]() { CacheStats(); });
162 }
163
ForceUpdateStats()164 void NetStatsCached::ForceUpdateStats()
165 {
166 isForce_ = true;
167 std::thread t([this]() {
168 CacheStats();
169 WriteStats();
170 isForce_ = false;
171 });
172 std::string threadName = "NetCachedStats";
173 pthread_setname_np(t.native_handle(), threadName.c_str());
174 t.detach();
175 }
176
Reset()177 void NetStatsCached::Reset() {}
178
179 } // namespace NetManagerStandard
180 } // namespace OHOS
181