• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "napi_hitrace_init.h"
17 
18 #include "hilog/log.h"
19 #include "napi_hitrace_param.h"
20 #include "napi_hitrace_util.h"
21 
22 using namespace OHOS::HiviewDFX;
23 
24 namespace {
25 constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D03, "HITRACE_JS_NAPI" };
26 constexpr uint32_t BUF_SIZE_64 = 64;
27 
ParseInt32Param(const napi_env & env,const napi_value & origin,int & dest)28 bool ParseInt32Param(const napi_env& env, const napi_value& origin, int& dest)
29 {
30     if (!NapiHitraceUtil::CheckValueTypeValidity(env, origin, napi_valuetype::napi_number)) {
31         return false;
32     }
33     napi_get_value_int32(env, origin, &dest);
34     return true;
35 }
36 
ParseStringParam(const napi_env & env,const napi_value & origin,std::string & dest)37 bool ParseStringParam(const napi_env& env, const napi_value& origin, std::string& dest)
38 {
39     if (!NapiHitraceUtil::CheckValueTypeValidity(env, origin, napi_valuetype::napi_string)) {
40         return false;
41     }
42     char buf[BUF_SIZE_64] = {0};
43     size_t bufLength = 0;
44     napi_get_value_string_utf8(env, origin, buf, BUF_SIZE_64, &bufLength);
45     dest = std::string {buf};
46     return true;
47 }
48 
ParseTraceIdObject(const napi_env & env,const napi_value & origin,HiTraceId & traceId)49 bool ParseTraceIdObject(const napi_env& env, const napi_value& origin, HiTraceId& traceId)
50 {
51     if (!NapiHitraceUtil::CheckValueTypeValidity(env, origin, napi_valuetype::napi_object)) {
52         return false;
53     }
54     NapiHitraceUtil::TransHiTraceIdJsObjectToNative(env, traceId, origin);
55     return true;
56 }
57 }
58 
Begin(napi_env env,napi_callback_info info)59 static napi_value Begin(napi_env env, napi_callback_info info)
60 {
61     size_t paramNum = ParamNum::TOTAL_TWO;
62     napi_value params[ParamNum::TOTAL_TWO] = {0};
63     napi_value thisArg = nullptr;
64     void* data = nullptr;
65     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
66     HiTraceId traceId;
67     napi_value val = nullptr;
68     NapiHitraceUtil::CreateHiTraceIdJsObject(env, traceId, val);
69     if (paramNum != ParamNum::TOTAL_ONE && paramNum != ParamNum::TOTAL_TWO) {
70         HiLog::Error(LABEL,
71             "failed to begin a new trace, count of parameters is not equal to 1 or 2");
72         return val;
73     }
74     std::string name;
75     if (!ParseStringParam(env, params[ParamIndex::PARAM_FIRST], name)) {
76         HiLog::Error(LABEL, "name type must be string.");
77         return val;
78     }
79     int flag = HiTraceFlag::HITRACE_FLAG_DEFAULT;
80     if (paramNum == ParamNum::TOTAL_TWO &&
81             !ParseInt32Param(env, params[ParamIndex::PARAM_SECOND], flag)) {
82         HiLog::Error(LABEL, "flag type must be number.");
83         return val;
84     }
85     traceId = HiTraceChain::Begin(name, flag);
86     NapiHitraceUtil::CreateHiTraceIdJsObject(env, traceId, val);
87     return val;
88 }
89 
End(napi_env env,napi_callback_info info)90 static napi_value End(napi_env env, napi_callback_info info)
91 {
92     size_t paramNum = ParamNum::TOTAL_ONE;
93     napi_value params[ParamNum::TOTAL_ONE] = {0};
94     napi_value thisArg = nullptr;
95     void* data = nullptr;
96     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
97     if (paramNum != ParamNum::TOTAL_ONE) {
98         HiLog::Error(LABEL,
99             "failed to end trace by trace id, count of parameters is not equal to 1.");
100         return nullptr;
101     }
102     HiTraceId traceId;
103     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_FIRST], traceId)) {
104         HiLog::Error(LABEL, "hitarce id type must be object.");
105         return nullptr;
106     }
107     HiTraceChain::End(traceId);
108     return nullptr;
109 }
110 
GetId(napi_env env,napi_callback_info info)111 static napi_value GetId(napi_env env, napi_callback_info info)
112 {
113     HiTraceId traceId = HiTraceChain::GetId();
114     napi_value val = nullptr;
115     NapiHitraceUtil::CreateHiTraceIdJsObject(env, traceId, val);
116     return val;
117 }
118 
SetId(napi_env env,napi_callback_info info)119 static napi_value SetId(napi_env env, napi_callback_info info)
120 {
121     size_t paramNum = ParamNum::TOTAL_ONE;
122     napi_value params[ParamNum::TOTAL_ONE] = {0};
123     napi_value thisArg = nullptr;
124     void* data = nullptr;
125     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
126     if (paramNum != ParamNum::TOTAL_ONE) {
127         HiLog::Error(LABEL,
128             "failed to set a new id for a trace, count of parameters is not equal to 1.");
129         return nullptr;
130     }
131     HiTraceId traceId;
132     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_FIRST], traceId)) {
133         HiLog::Error(LABEL, "hitarce id type must be object.");
134         return nullptr;
135     }
136     HiTraceChain::SetId(traceId);
137     return nullptr;
138 }
139 
ClearId(napi_env env,napi_callback_info info)140 static napi_value ClearId(napi_env env, napi_callback_info info)
141 {
142     HiTraceChain::ClearId();
143     return nullptr;
144 }
145 
CreateSpan(napi_env env,napi_callback_info info)146 static napi_value CreateSpan(napi_env env, napi_callback_info info)
147 {
148     HiTraceId traceId = HiTraceChain::CreateSpan();
149     napi_value val = nullptr;
150     NapiHitraceUtil::CreateHiTraceIdJsObject(env, traceId, val);
151     return val;
152 }
153 
Tracepoint(napi_env env,napi_callback_info info)154 static napi_value Tracepoint(napi_env env, napi_callback_info info)
155 {
156     size_t paramNum = ParamNum::TOTAL_FOUR;
157     napi_value params[ParamNum::TOTAL_FOUR] = {0};
158     napi_value thisArg = nullptr;
159     void* data = nullptr;
160     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
161     if (paramNum != ParamNum::TOTAL_FOUR) {
162         HiLog::Error(LABEL,
163             "failed to trace point, count of parameters is not equal to 4.");
164         return nullptr;
165     }
166     int communicationModeInt = 0;
167     if (!ParseInt32Param(env, params[ParamIndex::PARAM_FIRST], communicationModeInt)) {
168         HiLog::Error(LABEL, "HiTraceCommunicationMode type must be number.");
169         return nullptr;
170     }
171     HiTraceCommunicationMode communicationMode = HiTraceCommunicationMode(communicationModeInt);
172     int tracePointTypeInt = 0;
173     if (!ParseInt32Param(env, params[ParamIndex::PARAM_SECOND], tracePointTypeInt)) {
174         HiLog::Error(LABEL, "HiTraceTracePointType type must be number.");
175         return nullptr;
176     }
177     HiTraceTracepointType tracePointType = HiTraceTracepointType(tracePointTypeInt);
178     HiTraceId traceId;
179     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_THIRD], traceId)) {
180         HiLog::Error(LABEL, "hitarce id type must be object.");
181         return nullptr;
182     }
183     std::string description;
184     if (!ParseStringParam(env, params[ParamIndex::PARAM_FORTH], description)) {
185         HiLog::Error(LABEL, "descriptione type must be string.");
186         return nullptr;
187     }
188     HiTraceChain::Tracepoint(communicationMode, tracePointType, traceId, "%s", description.c_str());
189     return nullptr;
190 }
191 
IsValid(napi_env env,napi_callback_info info)192 static napi_value IsValid(napi_env env, napi_callback_info info)
193 {
194     size_t paramNum = ParamNum::TOTAL_ONE;
195     napi_value params[ParamNum::TOTAL_ONE] = {0};
196     napi_value thisArg = nullptr;
197     void* data = nullptr;
198     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
199     bool isValid = false;
200     napi_value val = nullptr;
201     napi_get_boolean(env, isValid, &val);
202     if (paramNum != ParamNum::TOTAL_ONE) {
203         HiLog::Error(LABEL,
204             "failed to check whether a id is valid or not, count of parameters is not equal to 1.");
205         return val;
206     }
207     HiTraceId traceId;
208     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_FIRST], traceId)) {
209         HiLog::Error(LABEL, "hitarce id type must be object.");
210         return val;
211     }
212     isValid = traceId.IsValid();
213     napi_get_boolean(env, isValid, &val);
214     return val;
215 }
216 
IsFlagEnabled(napi_env env,napi_callback_info info)217 static napi_value IsFlagEnabled(napi_env env, napi_callback_info info)
218 {
219     size_t paramNum = ParamNum::TOTAL_TWO;
220     napi_value params[ParamNum::TOTAL_TWO] = {0};
221     napi_value thisArg = nullptr;
222     void* data = nullptr;
223     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
224     bool isFalgEnabled = false;
225     napi_value val = nullptr;
226     napi_get_boolean(env, isFalgEnabled, &val);
227     if (paramNum != ParamNum::TOTAL_TWO) {
228         HiLog::Error(LABEL,
229             "failed to check whether a flag is enabled in a trace id, count of parameters is not equal to 2.");
230         return val;
231     }
232     HiTraceId traceId;
233     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_FIRST], traceId)) {
234         HiLog::Error(LABEL, "hitarce id type must be object.");
235         return val;
236     }
237     int traceFlagInt = 0;
238     if (!ParseInt32Param(env, params[ParamIndex::PARAM_SECOND], traceFlagInt)) {
239         HiLog::Error(LABEL, "HiTraceFlag type must be number.");
240         return val;
241     }
242     HiTraceFlag traceFlag = HiTraceFlag(traceFlagInt);
243     isFalgEnabled = traceId.IsFlagEnabled(traceFlag);
244     napi_get_boolean(env, isFalgEnabled, &val);
245     return val;
246 }
247 
EnableFlag(napi_env env,napi_callback_info info)248 static napi_value EnableFlag(napi_env env, napi_callback_info info)
249 {
250     size_t paramNum = ParamNum::TOTAL_TWO;
251     napi_value params[ParamNum::TOTAL_TWO] = {0};
252     napi_value thisArg = nullptr;
253     void* data = nullptr;
254     NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, &thisArg, &data));
255     if (paramNum != ParamNum::TOTAL_TWO) {
256         HiLog::Error(LABEL,
257             "failed to enable a flag for a trace id, count of parameters is not equal to 2.");
258         return nullptr;
259     }
260     HiTraceId traceId;
261     if (!ParseTraceIdObject(env, params[ParamIndex::PARAM_FIRST], traceId)) {
262         HiLog::Error(LABEL, "hitarce id type must be object.");
263         return nullptr;
264     }
265     int traceFlagInt = 0;
266     if (!ParseInt32Param(env, params[ParamIndex::PARAM_SECOND], traceFlagInt)) {
267         HiLog::Error(LABEL, "HiTraceFlag type must be number.");
268         return nullptr;
269     }
270     HiTraceFlag traceFlag = HiTraceFlag(traceFlagInt);
271     traceId.EnableFlag(traceFlag);
272     NapiHitraceUtil::EnableTraceIdObjectFlag(env, traceId, params[ParamIndex::PARAM_FIRST]);
273     return nullptr;
274 }
275 
276 EXTERN_C_START
TraceNapiInit(napi_env env,napi_value exports)277 static napi_value TraceNapiInit(napi_env env, napi_value exports)
278 {
279     napi_property_descriptor desc[] = {
280         DECLARE_NAPI_FUNCTION("begin", Begin),
281         DECLARE_NAPI_FUNCTION("end", End),
282         DECLARE_NAPI_FUNCTION("getId", GetId),
283         DECLARE_NAPI_FUNCTION("setId", SetId),
284         DECLARE_NAPI_FUNCTION("clearId", ClearId),
285         DECLARE_NAPI_FUNCTION("createSpan", CreateSpan),
286         DECLARE_NAPI_FUNCTION("tracepoint", Tracepoint),
287         DECLARE_NAPI_FUNCTION("isValid", IsValid),
288         DECLARE_NAPI_FUNCTION("isFlagEnabled", IsFlagEnabled),
289         DECLARE_NAPI_FUNCTION("enableFlag", EnableFlag),
290     };
291     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
292 
293     // init HiTraceFlag class, HiTraceTracePointType class and HiTraceCommunicationMode class
294     InitNapiClass(env, exports);
295     return exports;
296 }
297 EXTERN_C_END
298 
299 static napi_module hitrace_module = {
300     .nm_version = 1,
301     .nm_flags = 0,
302     .nm_filename = nullptr,
303     .nm_register_func = TraceNapiInit,
304     .nm_modname = "hiTraceChain",
305     .nm_priv = (reinterpret_cast<void *>(0)),
306     .reserved = {0}
307 };
308 
RegisterModule(void)309 extern "C" __attribute__((constructor)) void RegisterModule(void)
310 {
311     napi_module_register(&hitrace_module);
312 }
313