micromegas_tracing/logs/
log_events.rs

1use crate::{property_set::PropertySet, static_string_ref::StaticStringRef, string_id::StringId};
2use micromegas_transit::{
3    DynString, UserDefinedType, prelude::*, read_advance_string, read_consume_pod,
4};
5use std::sync::Arc;
6
7use super::LogMetadata;
8
9// Ensure we're on a 64-bit platform since we store pointers as u64
10const _: () = assert!(std::mem::size_of::<usize>() == 8);
11
12#[derive(Debug, TransitReflect)]
13pub struct LogStaticStrEvent {
14    pub desc: &'static LogMetadata<'static>,
15    pub time: i64,
16}
17
18impl InProcSerialize for LogStaticStrEvent {}
19
20#[derive(Debug)]
21pub struct LogStringEvent {
22    pub desc: &'static LogMetadata<'static>,
23    pub time: i64,
24    pub msg: DynString,
25}
26
27impl InProcSerialize for LogStringEvent {
28    const IN_PROC_SIZE: InProcSize = InProcSize::Dynamic;
29
30    fn get_value_size(&self) -> Option<u32> {
31        Some(
32            std::mem::size_of::<usize>() as u32 //desc reference
33                + std::mem::size_of::<i64>() as u32 //time
34                + self.msg.get_value_size().unwrap(), //dyn string
35        )
36    }
37
38    fn write_value(&self, buffer: &mut Vec<u8>) {
39        let desc_id = self.desc as *const _ as usize;
40        write_any(buffer, &desc_id);
41        write_any(buffer, &self.time);
42        self.msg.write_value(buffer);
43    }
44
45    unsafe fn read_value(mut window: &[u8]) -> Self {
46        // it does no good to parse this object when looking for dependencies, we should skip this code
47        let desc_id: usize = read_consume_pod(&mut window);
48        let desc = unsafe { &*(desc_id as *const LogMetadata) };
49        let time: i64 = read_consume_pod(&mut window);
50        let msg = DynString(read_advance_string(&mut window).unwrap());
51        assert_eq!(window.len(), 0);
52        Self { desc, time, msg }
53    }
54}
55
56//todo: change this interface to make clear that there are two serialization
57// strategies: pod and custom
58impl Reflect for LogStringEvent {
59    fn reflect() -> UserDefinedType {
60        lazy_static::lazy_static! {
61            static ref TYPE_NAME: Arc<String> = Arc::new("LogStringEventV2".into());
62        }
63        UserDefinedType {
64            name: TYPE_NAME.clone(),
65            size: 0,
66            members: vec![],
67            is_reference: false,
68            secondary_udts: vec![],
69        }
70    }
71}
72
73#[derive(Debug, TransitReflect)]
74pub struct LogStaticStrInteropEvent {
75    pub time: i64,
76    pub level: u32,
77    pub target: StringId,
78    pub msg: StringId,
79}
80
81impl InProcSerialize for LogStaticStrInteropEvent {}
82
83#[derive(Debug)]
84pub struct LogStringInteropEvent {
85    pub time: i64,
86    pub level: u8,
87    pub target: StaticStringRef, //for unreal compatibility
88    pub msg: DynString,
89}
90
91impl InProcSerialize for LogStringInteropEvent {
92    const IN_PROC_SIZE: InProcSize = InProcSize::Dynamic;
93
94    fn get_value_size(&self) -> Option<u32> {
95        Some(
96            std::mem::size_of::<i64>() as u32 //time
97                + std::mem::size_of::<u8>() as u32 //level
98                + std::mem::size_of::<StringId>() as u32 //target
99                + self.msg.get_value_size().unwrap(), //message
100        )
101    }
102
103    fn write_value(&self, buffer: &mut Vec<u8>) {
104        write_any(buffer, &self.time);
105        write_any(buffer, &self.level);
106        write_any(buffer, &self.target);
107        self.msg.write_value(buffer);
108    }
109
110    unsafe fn read_value(mut window: &[u8]) -> Self {
111        let time: i64 = read_consume_pod(&mut window);
112        let level: u8 = read_consume_pod(&mut window);
113        let target: StaticStringRef = read_consume_pod(&mut window);
114        let msg = DynString(read_advance_string(&mut window).unwrap());
115        Self {
116            time,
117            level,
118            target,
119            msg,
120        }
121    }
122}
123
124//todo: change this interface to make clear that there are two serialization
125// strategies: pod and custom
126impl Reflect for LogStringInteropEvent {
127    fn reflect() -> UserDefinedType {
128        lazy_static::lazy_static! {
129            static ref TYPE_NAME: Arc<String> = Arc::new("LogStringInteropEventV3".into());
130        }
131        UserDefinedType {
132            name: TYPE_NAME.clone(),
133            size: 0,
134            members: vec![],
135            is_reference: false,
136            secondary_udts: vec![StaticStringRef::reflect()],
137        }
138    }
139}
140
141#[derive(Debug, TransitReflect)]
142pub struct LogMetadataRecord {
143    pub id: u64,
144    pub fmt_str: *const u8,
145    pub target: *const u8,
146    pub module_path: *const u8,
147    pub file: *const u8,
148    pub line: u32,
149    pub level: u32,
150}
151
152impl InProcSerialize for LogMetadataRecord {}
153
154#[derive(Debug)]
155pub struct TaggedLogString {
156    pub desc: &'static LogMetadata<'static>,
157    pub properties: &'static PropertySet,
158    pub time: i64,
159    pub msg: DynString,
160}
161
162impl Reflect for TaggedLogString {
163    fn reflect() -> UserDefinedType {
164        lazy_static::lazy_static! {
165            static ref TYPE_NAME: Arc<String> = Arc::new("TaggedLogString".into());
166        }
167        UserDefinedType {
168            name: TYPE_NAME.clone(),
169            size: 0,
170            members: vec![],
171            is_reference: false,
172            secondary_udts: vec![],
173        }
174    }
175}
176
177impl InProcSerialize for TaggedLogString {
178    const IN_PROC_SIZE: InProcSize = InProcSize::Dynamic;
179
180    fn get_value_size(&self) -> Option<u32> {
181        Some(
182            std::mem::size_of::<u64>() as u32 // desc ptr
183            + std::mem::size_of::<u64>() as u32 // properties ptr
184            + std::mem::size_of::<i64>() as u32 // time
185                + self.msg.get_value_size().unwrap(), // message
186        )
187    }
188
189    fn write_value(&self, buffer: &mut Vec<u8>) {
190        write_any(buffer, &self.desc);
191        write_any(buffer, &self.properties);
192        write_any(buffer, &self.time);
193        self.msg.write_value(buffer);
194    }
195
196    #[allow(unknown_lints)]
197    #[allow(integer_to_ptr_transmutes)] // TODO: Fix pointer provenance properly (see tasks/pointer-provenance.md)
198    unsafe fn read_value(mut window: &[u8]) -> Self {
199        let desc_id: u64 = read_consume_pod(&mut window);
200        let properties_id: u64 = read_consume_pod(&mut window);
201        let time: i64 = read_consume_pod(&mut window);
202        let msg = DynString(read_advance_string(&mut window).unwrap());
203        Self {
204            desc: unsafe { std::mem::transmute::<u64, &LogMetadata<'static>>(desc_id) },
205            properties: unsafe { std::mem::transmute::<u64, &PropertySet>(properties_id) },
206            time,
207            msg,
208        }
209    }
210}