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
16 //! Interface definition for rust APIs of hitracechain.
17
18 #[macro_use]
19 pub mod macros;
20
21 use std::ffi::{CString, c_char, c_int, c_ulonglong};
22 use std::ops::BitOr;
23
24 /// Enumerate trace flag
25 #[non_exhaustive]
26 pub enum HiTraceFlag {
27 /// DEFAULT: default value.
28 Default = 0,
29
30 /// trace sync and async call. default: trace sync call only.
31 IncludeAsync = 1 << 0,
32
33 /// do not create child span. default: create child span.
34 DoNotCreateSpan = 1 << 1,
35
36 /// output tracepoint info in span. default: do not output tracepoint info.
37 TpInfo = 1 << 2,
38
39 /// do not output begin and end info. default: output begin and end info.
40 NoBeInfo = 1 << 3,
41
42 /// do not add id to log. default: add id to log.
43 DoNotEnableLog = 1 << 4,
44
45 /// the trace is triggered by fault.
46 FaultTigger = 1 << 5,
47
48 /// output device-to-device tracepoint info in span only. default: do not output device-to-device tracepoint info.
49 D2dTpInfo = 1 << 6,
50 }
51
52 /// Add support for bitor operating for HiTraceFlag
53 impl BitOr for HiTraceFlag {
54 type Output = i32;
55
bitor(self, rhs: Self) -> Self::Output56 fn bitor(self, rhs: Self) -> Self::Output {
57 (self as i32) | (rhs as i32)
58 }
59 }
60
61 /// Enumerate trace point type
62 #[non_exhaustive]
63 pub enum HiTraceTracepointType {
64
65 /// client send
66 Cs = 0,
67
68 /// client receive
69 Cr = 1,
70
71 /// server send
72 Ss = 2,
73
74 /// server receive
75 Sr = 3,
76
77 /// general info
78 General = 4,
79 }
80
81 /// Enumerate trace communication mode
82 #[non_exhaustive]
83 pub enum HiTraceCommunicationMode {
84 /// unspecified communication mode
85 Default = 0,
86
87 /// thread-to-thread communication mode
88 Thread = 1,
89
90 /// process-to-process communication mode
91 Process = 2,
92
93 /// device-to-device communication mode
94 Device = 3,
95 }
96
97 /// This type represent to HiTraceIdStruct defined in C.
98 #[repr(C)]
99 pub struct HiTraceIdStruct {
100 trace_details: [u64;2],
101 }
102
103 /// Alias for HiTraceIdStruct
104 pub type HiTraceId = HiTraceIdStruct;
105
106 impl HiTraceId {
107 /// Judge whether the trace id is valid or not.
is_valid(&self) -> bool108 pub fn is_valid(&self) -> bool {
109 // Safty: call C ffi border function, all risks are under control.
110 unsafe {
111 HiTraceChainIsValidWrapper(self as *const HiTraceId)
112 }
113 }
114
115 /// Judge whether the trace id has enabled a trace flag or not.
is_flag_enabled(&self, flag: HiTraceFlag) -> bool116 pub fn is_flag_enabled(&self, flag: HiTraceFlag) -> bool {
117 // Safty: call C ffi border function, all risks are under control.
118 unsafe {
119 HiTraceChainIsFlagEnabledWrapper(self as *const HiTraceId, flag as i32)
120 }
121 }
122
123 /// Enable the designative trace flag for the trace id.
enable_flag(&mut self, flag: HiTraceFlag)124 pub fn enable_flag(&mut self, flag: HiTraceFlag) {
125 // Safty: call C ffi border function, all risks are under control.
126 unsafe {
127 HiTraceChainEnableFlagWrapper(self as *mut HiTraceId, flag as i32);
128 }
129 }
130
131 /// Set trace flags for the trace id.
set_flags(&mut self, flags: i32)132 pub fn set_flags(&mut self, flags: i32) {
133 // Safty: call C ffi border function, all risks are under control.
134 unsafe {
135 HiTraceChainSetFlagsWrapper(self as *mut HiTraceId, flags);
136 }
137 }
138
139 /// Get trace flags of the trace id.
get_flags(&self) -> i32140 pub fn get_flags(&self) -> i32 {
141 // Safty: call C ffi border function, all risks are under control.
142 unsafe {
143 HiTraceChainGetFlagsWrapper(self as *const HiTraceId)
144 }
145 }
146
147 /// Set chain id of the trace id.
set_chain_id(&mut self, chain_id: u64)148 pub fn set_chain_id(&mut self, chain_id: u64) {
149 // Safty: call C ffi border function, all risks are under control.
150 unsafe {
151 HiTraceChainSetChainIdWrapper(self as *mut HiTraceId, chain_id);
152 }
153 }
154
155 /// Get chain id of the trace id.
get_chain_id(&self) -> u64156 pub fn get_chain_id(&self) -> u64 {
157 // Safty: call C ffi border function, all risks are under control.
158 unsafe {
159 HiTraceChainGetChainIdWrapper(self as *const HiTraceId)
160 }
161 }
162
163 /// Set span id of the trace id.
set_span_id(&mut self, span_id: u64)164 pub fn set_span_id(&mut self, span_id: u64) {
165 // Safty: call C ffi border function, all risks are under control.
166 unsafe {
167 HiTraceChainSetSpanIdWrapper(self as *mut HiTraceId, span_id);
168 }
169 }
170
171 /// Get span id of the trace id.
get_span_id(&self)-> u64172 pub fn get_span_id(&self)-> u64 {
173 // Safty: call C ffi border function, all risks are under control.
174 unsafe {
175 HiTraceChainGetSpanIdWrapper(self as *const HiTraceId)
176 }
177 }
178
179 /// Set parent span id of the trace id.
set_parent_span_id(&mut self, parent_span_id: u64)180 pub fn set_parent_span_id(&mut self, parent_span_id: u64) {
181 // Safty: call C ffi border function, all risks are under control.
182 unsafe {
183 HiTraceChainSetParentSpanIdWrapper(self as *mut HiTraceId, parent_span_id);
184 }
185 }
186
187 /// Get parent span id of the trace id.
get_parent_span_id(&self) -> u64188 pub fn get_parent_span_id(&self) -> u64 {
189 // Safty: call C ffi border function, all risks are under control.
190 unsafe {
191 HiTraceChainGetParentSpanIdWrapper(self as *const HiTraceId)
192 }
193 }
194 }
195
196 /// Start tracing a process impl.
begin(name: &str, flags: i32) -> HiTraceId197 pub fn begin(name: &str, flags: i32) -> HiTraceId {
198 // Safty: call C ffi border function, all risks are under control.
199 unsafe {
200 let name = CString::new(name).unwrap();
201 HiTraceChainBegin(name.as_ptr() as *const c_char, flags)
202 }
203 }
204
205 /// Stop process tracing and clear trace id of current thread if the given trace
206 /// id is valid, otherwise do nothing.
end(id: &HiTraceId)207 pub fn end(id: &HiTraceId) {
208 // Safty: call C ffi border function, all risks are under control.
209 unsafe {
210 HiTraceChainEnd(id as *const HiTraceId);
211 }
212 }
213
214 /// Get trace id of current thread, and return a invalid trace id if no
215 /// trace id belong to current thread
get_id() -> HiTraceId216 pub fn get_id() -> HiTraceId {
217 // Safty: call C ffi border function, all risks are under control.
218 unsafe {
219 HiTraceChainGetId()
220 }
221 }
222
223 /// Set id as trace id of current thread. Do nothing if id is invalid.
set_id(id: &HiTraceId)224 pub fn set_id(id: &HiTraceId) {
225 // Safty: call C ffi border function, all risks are under control.
226 unsafe {
227 HiTraceChainSetId(id as *const HiTraceId);
228 }
229 }
230
231 /// Clear trace id of current thread and set it invalid.
clear_id()232 pub fn clear_id() {
233 // Safty: call C ffi border function, all risks are under control.
234 unsafe {
235 HiTraceChainClearId();
236 }
237 }
238
239 /// Create a new span id according to the trace id of current thread.
create_span() -> HiTraceId240 pub fn create_span() -> HiTraceId {
241 // Safty: call C ffi border function, all risks are under control.
242 unsafe {
243 HiTraceChainCreateSpan()
244 }
245 }
246
247 /// Persist a trace id into a uint8_t array
id_to_bytes(p_id: &HiTraceId, p_id_array: &mut [u8]) -> i32248 pub fn id_to_bytes(p_id: &HiTraceId, p_id_array: &mut [u8]) -> i32 {
249 let arr_len = p_id_array.len();
250 let mut id_array_wrapper: Vec<u8> = vec![];
251 for &item in p_id_array.iter().take(arr_len) {
252 id_array_wrapper.push(item);
253 }
254 // Safty: call C ffi border function, all risks are under control.
255 unsafe {
256 let ret = HiTraceChainIdToBytesWrapper(p_id as *const HiTraceId,
257 id_array_wrapper.as_mut_ptr(),
258 arr_len as c_int);
259 p_id_array[..arr_len].copy_from_slice(&id_array_wrapper[..arr_len]);
260 ret
261 }
262 }
263
264 /// Build a trace id form a uint8_t array
bytes_to_id(p_id_array: &[u8]) -> HiTraceId265 pub fn bytes_to_id(p_id_array: &[u8]) -> HiTraceId {
266 let mut id_array_wrapper: Vec<u8> = vec![];
267 for &item in p_id_array {
268 id_array_wrapper.push(item);
269 }
270 // Safty: call C ffi border function, all risks are under control.
271 unsafe {
272 HiTraceChainBytesToIdWrapper(id_array_wrapper.as_mut_ptr(), p_id_array.len() as c_int)
273 }
274 }
275
276 extern "C" {
277 /// ffi border function
HiTraceChainBegin(name: *const c_char, _flags: c_int) -> HiTraceId278 fn HiTraceChainBegin(name: *const c_char, _flags: c_int) -> HiTraceId;
279
280 /// ffi border function
HiTraceChainEnd(id: *const HiTraceId)281 fn HiTraceChainEnd(id: *const HiTraceId);
282
283 /// ffi border function
HiTraceChainGetId() -> HiTraceId284 fn HiTraceChainGetId() -> HiTraceId;
285
286 /// ffi border function
HiTraceChainSetId(id: *const HiTraceId)287 fn HiTraceChainSetId(id: *const HiTraceId);
288
289 /// ffi border function
HiTraceChainClearId()290 fn HiTraceChainClearId();
291
292 /// ffi border function
HiTraceChainCreateSpan() -> HiTraceId293 fn HiTraceChainCreateSpan() -> HiTraceId;
294
295 /// ffi border function
HiTraceChainIdToBytesWrapper(id: *const HiTraceId, p_id_array: *const c_char, len: c_int) -> c_int296 fn HiTraceChainIdToBytesWrapper(id: *const HiTraceId, p_id_array: *const c_char, len: c_int) -> c_int;
297
298 /// ffi border function
HiTraceChainBytesToIdWrapper(p_id_array: *const c_char, len: c_int) -> HiTraceId299 fn HiTraceChainBytesToIdWrapper(p_id_array: *const c_char, len: c_int) -> HiTraceId;
300
301 /// ffi border function
302 #[allow(dead_code)]
HiTraceChainTracepointExWrapper(communication_mode: c_int, trace_type: c_int, p_id: *const HiTraceId, fmt: *const c_char, ...)303 pub fn HiTraceChainTracepointExWrapper(communication_mode: c_int, trace_type: c_int,
304 p_id: *const HiTraceId, fmt: *const c_char, ...);
305
306 /// ffi border function
HiTraceChainIsValidWrapper(p_id: *const HiTraceId) -> bool307 fn HiTraceChainIsValidWrapper(p_id: *const HiTraceId) -> bool;
308
309 /// ffi border function
HiTraceChainIsFlagEnabledWrapper(p_id: *const HiTraceId, flag: c_int) -> bool310 fn HiTraceChainIsFlagEnabledWrapper(p_id: *const HiTraceId, flag: c_int) -> bool;
311
312 /// ffi border function
HiTraceChainEnableFlagWrapper(p_id: *mut HiTraceId, flag: c_int)313 fn HiTraceChainEnableFlagWrapper(p_id: *mut HiTraceId, flag: c_int);
314
315 /// ffi border function
HiTraceChainSetFlagsWrapper(p_id: *mut HiTraceId, flags: c_int)316 fn HiTraceChainSetFlagsWrapper(p_id: *mut HiTraceId, flags: c_int);
317
318 /// ffi border function
HiTraceChainGetFlagsWrapper(p_id: *const HiTraceId) -> c_int319 fn HiTraceChainGetFlagsWrapper(p_id: *const HiTraceId) -> c_int;
320
321 /// ffi border function
HiTraceChainSetChainIdWrapper(p_id: *mut HiTraceId, chain_id: c_ulonglong)322 fn HiTraceChainSetChainIdWrapper(p_id: *mut HiTraceId, chain_id: c_ulonglong);
323
324 /// ffi border function
HiTraceChainGetChainIdWrapper(p_id: *const HiTraceId) -> c_ulonglong325 fn HiTraceChainGetChainIdWrapper(p_id: *const HiTraceId) -> c_ulonglong;
326
327 /// ffi border function
HiTraceChainSetSpanIdWrapper(p_id: *mut HiTraceId, span_id: c_ulonglong)328 fn HiTraceChainSetSpanIdWrapper(p_id: *mut HiTraceId, span_id: c_ulonglong);
329
330 /// ffi border function
HiTraceChainGetSpanIdWrapper(p_id: *const HiTraceId) -> c_ulonglong331 fn HiTraceChainGetSpanIdWrapper(p_id: *const HiTraceId) -> c_ulonglong;
332
333 /// ffi border function
HiTraceChainSetParentSpanIdWrapper(p_id: *mut HiTraceId, parent_span_id: c_ulonglong)334 fn HiTraceChainSetParentSpanIdWrapper(p_id: *mut HiTraceId,
335 parent_span_id: c_ulonglong);
336
337 /// ffi border function
HiTraceChainGetParentSpanIdWrapper(p_id: *const HiTraceId) -> c_ulonglong338 fn HiTraceChainGetParentSpanIdWrapper(p_id: *const HiTraceId) -> c_ulonglong;
339 }