• 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 
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 }