• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 #include <charconv>
16 #include <sys/stat.h>
17 #include <set>
18 
19 #include "app_caller_event.h"
20 #include "app_event_task_storage.h"
21 #include "file_util.h"
22 #include "hiview_logger.h"
23 #include "time_util.h"
24 #include "trace_common.h"
25 #include "trace_flow_controller.h"
26 #include "trace_db_callback.h"
27 
28 using namespace OHOS::HiviewDFX;
29 
30 namespace OHOS {
31 namespace HiviewDFX {
32 namespace {
33 DEFINE_LOG_TAG("TraceFlowController");
34 constexpr int32_t DB_VERSION = 4;
35 const std::string UNIFIED_SHARE_PATH = "/data/log/hiview/unified_collection/trace/share/";
36 const std::string UNIFIED_SPECIAL_PATH = "/data/log/hiview/unified_collection/trace/special/";
37 const std::string DB_NAME = "trace_flow_control.db";
38 constexpr int32_t HITRACE_CACHE_DURATION_LIMIT_DAILY_TOTAL = 10 * 60; // 10 minutes
39 const std::set<std::string> DB_CALLER {
40     CallerName::XPERF, CallerName::XPOWER, CallerName::RELIABILITY, CallerName::HIVIEW
41 };
42 }
43 
InitTraceDb(const std::string & dbPath)44 void TraceFlowController::InitTraceDb(const std::string& dbPath)
45 {
46     NativeRdb::RdbStoreConfig config(dbPath + DB_NAME);
47     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
48     TraceDbStoreCallback callback;
49     auto ret = NativeRdb::E_OK;
50     dbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
51     if (ret != NativeRdb::E_OK) {
52         HIVIEW_LOGE("failed to init db store, db store path=%{public}s", dbPath.c_str());
53         dbStore_ = nullptr;
54         return;
55     }
56 }
57 
InitTraceStorage(const std::string & caller)58 void TraceFlowController::InitTraceStorage(const std::string& caller)
59 {
60     if (dbStore_ == nullptr) {
61         HIVIEW_LOGE("dbStore fail init");
62         return;
63     }
64     if (DB_CALLER.find(caller) != DB_CALLER.end()) {
65         HIVIEW_LOGD("is db caller, init TraceStorage");
66         traceStorage_ = std::make_shared<TraceStorage>(dbStore_, caller);
67     }
68     if (caller == ClientName::APP) {
69         appTaskStore_ = std::make_shared<AppEventTaskStorage>(dbStore_);
70     }
71     if (caller == BusinessName::BEHAVIOR) {
72         behaviorTaskStore_ = std::make_shared<TraceBehaviorStorage>(dbStore_);
73     }
74     if (caller == BusinessName::TELEMETRY) {
75         teleMetryStorage_ = std::make_shared<TeleMetryStorage>(dbStore_);
76     }
77 }
78 
TraceFlowController(const std::string & caller,const std::string & dbPath)79 TraceFlowController::TraceFlowController(const std::string& caller, const std::string& dbPath)
80 {
81     InitTraceDb(dbPath);
82     InitTraceStorage(caller);
83 }
84 
NeedDump()85 bool TraceFlowController::NeedDump()
86 {
87     if (traceStorage_ == nullptr) {
88         return false;
89     }
90     return traceStorage_->NeedDump();
91 }
92 
NeedUpload(int64_t traceSize)93 bool TraceFlowController::NeedUpload(int64_t traceSize)
94 {
95     if (traceStorage_ == nullptr) {
96         return false;
97     }
98     return traceStorage_->NeedUpload(traceSize);
99 }
100 
StoreDb()101 void TraceFlowController::StoreDb()
102 {
103     if (traceStorage_ == nullptr) {
104         return;
105     }
106     traceStorage_->StoreDb();
107 }
108 
HasCallOnceToday(int32_t uid,uint64_t happenTime)109 bool TraceFlowController::HasCallOnceToday(int32_t uid, uint64_t happenTime)
110 {
111     if (appTaskStore_ == nullptr) {
112         return true;
113     }
114     uint64_t happenTimeInSecond = happenTime / TimeUtil::SEC_TO_MILLISEC;
115     std::string date = TimeUtil::TimestampFormatToDate(happenTimeInSecond, "%Y%m%d");
116 
117     AppEventTask appEventTask;
118     appEventTask.id_ = 0;
119     int32_t dateNum = 0;
120     auto result = std::from_chars(date.c_str(), date.c_str() + date.size(), dateNum);
121     if (result.ec != std::errc()) {
122         HIVIEW_LOGW("convert error, dateStr: %{public}s", date.c_str());
123         return true;
124     }
125     HIVIEW_LOGD("Query appEventTask where uid:%{public}d, dateNum:%{public}d", uid, dateNum);
126     appTaskStore_->GetAppEventTask(uid, dateNum, appEventTask);
127     return appEventTask.id_ > 0;
128 }
129 
RecordCaller(std::shared_ptr<AppCallerEvent> appEvent)130 bool TraceFlowController::RecordCaller(std::shared_ptr<AppCallerEvent> appEvent)
131 {
132     if (appTaskStore_ == nullptr) {
133         return false;
134     }
135     uint64_t happenTimeInSecond = appEvent->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
136     std::string date = TimeUtil::TimestampFormatToDate(happenTimeInSecond, "%Y%m%d");
137     int64_t dateNum = 0;
138     auto result = std::from_chars(date.c_str(), date.c_str() + date.size(), dateNum);
139     if (result.ec != std::errc()) {
140         HIVIEW_LOGW("convert error, dateStr: %{public}s", date.c_str());
141         return false;
142     }
143     AppEventTask appEventTask;
144     appEventTask.taskDate_ = dateNum;
145     appEventTask.taskType_ = APP_EVENT_TASK_TYPE_JANK_EVENT;
146     appEventTask.uid_ = appEvent->uid_;
147     appEventTask.pid_ = appEvent->pid_;
148     appEventTask.bundleName_ = appEvent->bundleName_;
149     appEventTask.bundleVersion_ = appEvent->bundleVersion_;
150     appEventTask.startTime_ = appEvent->taskBeginTime_;
151     appEventTask.finishTime_ = appEvent->taskEndTime_;
152     appEventTask.resourePath_ = appEvent->externalLog_;
153     appEventTask.resourceSize_ = static_cast<int32_t>(FileUtil::GetFileSize(appEventTask.resourePath_));
154     appEventTask.state_ = APP_EVENT_TASK_STATE_FINISH;
155     return appTaskStore_->InsertAppEventTask(appEventTask);
156 }
157 
CleanOldAppTrace(int32_t dateNum)158 void TraceFlowController::CleanOldAppTrace(int32_t dateNum)
159 {
160     if (appTaskStore_ == nullptr) {
161         return;
162     }
163     appTaskStore_->RemoveAppEventTask(dateNum);
164 }
165 
UseCacheTimeQuota(int32_t interval)166 CacheFlow TraceFlowController::UseCacheTimeQuota(int32_t interval)
167 {
168     if (behaviorTaskStore_ == nullptr) {
169         return CacheFlow::EXIT;
170     }
171     BehaviorRecord record;
172     record.behaviorId = CACHE_LOW_MEM;
173     record.dateNum = TimeUtil::TimestampFormatToDate(TimeUtil::GetSeconds(), "%Y%m%d");
174     if (!behaviorTaskStore_->GetRecord(record) && !behaviorTaskStore_->InsertRecord(record)) {
175         HIVIEW_LOGE("failed to get and insert record, close task");
176         return CacheFlow::EXIT;
177     }
178     HIVIEW_LOGD("get used quota:%{public}d", record.usedQuota);
179     if (record.usedQuota >= HITRACE_CACHE_DURATION_LIMIT_DAILY_TOTAL) {
180         HIVIEW_LOGW("usedQuota exceeds daily limit. usedQuota:%{public}d", record.usedQuota);
181         return CacheFlow::OVER_FLOW;
182     }
183     record.usedQuota += interval;
184     behaviorTaskStore_->UpdateRecord(record);
185     return CacheFlow::SUCCESS;
186 }
187 
InitTelemetryData(const std::string & telemetryId,int64_t & beginTime,const std::map<std::string,int64_t> & flowControlQuotas)188 TelemetryRet TraceFlowController::InitTelemetryData(const std::string &telemetryId, int64_t &beginTime,
189     const std::map<std::string, int64_t>& flowControlQuotas)
190 {
191     if (teleMetryStorage_ == nullptr) {
192         HIVIEW_LOGE("failed to init teleMetryStorage");
193         return TelemetryRet::EXIT;
194     }
195     return teleMetryStorage_->InitTelemetryControl(telemetryId, beginTime, flowControlQuotas);
196 }
197 
NeedTelemetryDump(const std::string & module,int64_t traceSize)198 TelemetryRet TraceFlowController::NeedTelemetryDump(const std::string &module, int64_t traceSize)
199 {
200     if (teleMetryStorage_ == nullptr) {
201         HIVIEW_LOGE("failed to init teleMetryStorage, close task");
202         return TelemetryRet::EXIT;
203     }
204     return teleMetryStorage_->NeedTelemetryDump(module, traceSize);
205 }
206 
ClearTelemetryData()207 void TraceFlowController::ClearTelemetryData()
208 {
209     if (teleMetryStorage_ == nullptr) {
210         HIVIEW_LOGE("failed to init teleMetryStorage, return");
211         return;
212     }
213     return teleMetryStorage_->ClearTelemetryData();
214 }
215 } // HiViewDFX
216 } // OHOS
217