1 /*
2 * Copyright (c) 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 #ifdef FFRT_SEND_EVENT
16 #include "sysevent.h"
17 #include <dlfcn.h>
18 #include <mutex>
19 #include "hisysevent.h"
20 #include "tm/task_base.h"
21 #include "dfx/log/ffrt_log_api.h"
22 #include "internal_inc/osal.h"
23 #include "util/ffrt_facade.h"
24
25 namespace {
26 constexpr long long lONG_TASK_TIME_LIMIT = 1; // 1s
27 constexpr long long lONG_TASK_REPORT_FRE = 30 * 60; // 30min == 30 * 60s
28 constexpr uint64_t FISRT_CALL_TIME_LIMIT = 5 * 60; // 5min == 5 * 60s
29 constexpr const char* BEGETUTIL_LIB_PATH = "libbegetutil.z.so";
30 }
31
32 namespace ffrt {
33 std::mutex mtx;
34 class LibbegetutilAdapter {
35 public:
LibbegetutilAdapter()36 LibbegetutilAdapter()
37 {
38 if (!Load()) {
39 FFRT_LOGD("Failed to load the library in constructor.");
40 }
41 }
42
~LibbegetutilAdapter()43 ~LibbegetutilAdapter()
44 {
45 if (!UnLoad()) {
46 FFRT_LOGD("Failed to unload the library in destructor.");
47 }
48 }
49
Instance()50 static LibbegetutilAdapter* Instance()
51 {
52 static LibbegetutilAdapter instance;
53 return &instance;
54 }
55
56 using GetParameterType = int (*)(const char *, const char *, char *, uint32_t);
57 GetParameterType GetParameter = nullptr;
58
59 private:
Load()60 bool Load()
61 {
62 if (handle != nullptr) {
63 FFRT_LOGD("handle exits");
64 return true;
65 }
66
67 handle = dlopen(BEGETUTIL_LIB_PATH, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
68 if (handle == nullptr) {
69 FFRT_LOGE("load so[%s] fail", BEGETUTIL_LIB_PATH);
70 return false;
71 }
72
73 GetParameter = reinterpret_cast<GetParameterType>(dlsym(handle, "GetParameter"));
74 if (GetParameter == nullptr) {
75 FFRT_LOGE("load func from %s failed", BEGETUTIL_LIB_PATH);
76 return false;
77 }
78 return true;
79 }
80
UnLoad()81 bool UnLoad()
82 {
83 if (handle != nullptr) {
84 if (dlclose(handle) != 0) {
85 FFRT_LOGE("Failed to close the handle.");
86 return false;
87 }
88 handle = nullptr;
89 return true;
90 }
91 return true;
92 }
93
94 void* handle = nullptr;
95 };
96
IsBeta()97 bool IsBeta()
98 {
99 LibbegetutilAdapter* adapter = LibbegetutilAdapter::Instance();
100 constexpr int versionTypeLen = 32;
101 char retValue[versionTypeLen] = {0};
102 if (adapter->GetParameter != nullptr) {
103 int ret = adapter->GetParameter("const.logsystem.versiontype", "false", retValue, versionTypeLen);
104 if (ret > 0) {
105 int result = strcmp(retValue, "beta");
106 if (result == 0) {
107 return true;
108 }
109 }
110 }
111 return false;
112 }
113
TaskBlockInfoReport(const long long passed,const std::string & task_label,int qos,uint64_t freq)114 void TaskBlockInfoReport(const long long passed, const std::string& task_label, int qos, uint64_t freq)
115 {
116 static std::once_flag firstCallFlag;
117 if (unlikely(passed > lONG_TASK_TIME_LIMIT)) {
118 uint64_t now = TimeStamp();
119 {
120 std::lock_guard<std::mutex> lock(mtx);
121 static uint64_t firstCallTime = 0;
122 static uint64_t lastEventTime = 0;
123 std::call_once(firstCallFlag, [&]() {
124 firstCallTime = now;
125 lastEventTime = now;
126 });
127 uint64_t diff = now - firstCallTime;
128 if ((diff / freq) > FISRT_CALL_TIME_LIMIT) {
129 if (now >= lastEventTime && unlikely(((now - lastEventTime) / freq) > lONG_TASK_REPORT_FRE)) {
130 std::string eventName = "TASK_TIMEOUT";
131 std::string buffer = "task:" + task_label + ", passed: "
132 + std::to_string(passed) + " s, qos:" + std::to_string(qos);
133 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::FFRT,
134 eventName, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
135 "SENARIO", "Long_Task", "PROCESS_NAME", std::string(GetCurrentProcessName()),
136 "MSG", buffer);
137 lastEventTime = now;
138 }
139 }
140 }
141 }
142 }
143
TaskTimeoutReport(std::stringstream & ss,const std::string & processName,const std::string & senarioName)144 void TaskTimeoutReport(std::stringstream& ss, const std::string& processName, const std::string& senarioName)
145 {
146 std::string msg = ss.str();
147 std::string eventName = "TASK_TIMEOUT";
148 time_t cur_time = time(nullptr);
149 std::string sendMsg = std::string((ctime(&cur_time) == nullptr) ? "" : ctime(&cur_time)) + "\n" + msg + "\n";
150 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::FFRT, eventName,
151 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, "SENARIO", senarioName,
152 "PROCESS_NAME", processName, "MSG", sendMsg);
153 }
154
TrafficOverloadReport(std::stringstream & ss,const std::string & senarioName)155 void TrafficOverloadReport(std::stringstream& ss, const std::string& senarioName)
156 {
157 std::string msg = ss.str();
158 std::string eventName = "TASK_TIMEOUT";
159 time_t cur_time = time(nullptr);
160 std::string sendMsg = std::string((ctime(&cur_time) == nullptr) ? "" : ctime(&cur_time)) + "\n" + msg + "\n";
161 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::FFRT, eventName,
162 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, "SENARIO", senarioName,
163 "PROCESS_NAME", GetCurrentProcessName(), "MSG", sendMsg);
164 }
165
WorkerEscapeReport(const std::string & processName,int qos,size_t totalNum)166 void WorkerEscapeReport(const std::string& processName, int qos, size_t totalNum)
167 {
168 time_t cur_time = time(nullptr);
169 size_t near_gid = TaskBase::GetLastGid();
170 std::string msg = "report time: " + std::string((ctime(&cur_time) == nullptr) ? "" : ctime(&cur_time)) + "\n"
171 + ", qos: " + std::to_string(qos)
172 + ", worker num: " + std::to_string(totalNum)
173 + ", near gid:" + std::to_string((near_gid > 0) ? near_gid - 1 : 0);
174 std::string eventName = "TASK_TIMEOUT";
175 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::FFRT, eventName,
176 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, "SENARIO", "Trigger_Escape",
177 "PROCESS_NAME", processName, "MSG", msg);
178 FFRT_LOGW("Process: %s trigger escape. %s", processName.c_str(), msg.c_str());
179 }
180 }
181 #endif