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