• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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