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