Skip to content

Commit 1a16f67

Browse files
committed
feat: Modularize code for different build; Fallback to zeekstd for x86
1 parent 26e909b commit 1a16f67

File tree

6 files changed

+164
-23
lines changed

6 files changed

+164
-23
lines changed

runtime_tracing/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ schemars = "0.8.2"
2323
capnp = "0.21.1"
2424
cbor4ii = { version = "1.0.0", features = ["serde1", "use_std"] }
2525
fscommon = "0.1.1"
26+
27+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
28+
zeekstd = "0.6.0"
29+
30+
[target.'cfg(target_arch = "wasm32")'.dependencies]
2631
ruzstd = "0.8.1"
2732

2833
[build-dependencies]

runtime_tracing/src/cbor_zstd_reader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::io::{self, BufRead, BufReader, Read, Seek, Write};
22

33
use fscommon::StreamSlice;
44

5-
use ruzstd::decoding::StreamingDecoder;
5+
use zeekstd::Decoder;
66

77
use crate::{TraceLowLevelEvent, cbor_zstd_writer::HEADERV1};
88

@@ -25,7 +25,7 @@ pub fn read_trace(input: &mut (impl Read + Write + Seek)) -> Result<Vec<TraceLow
2525
input.seek(io::SeekFrom::Start(0))?;
2626
let input2 = StreamSlice::new(&mut *input, 8, end_pos)?;
2727

28-
let decoder = StreamingDecoder::new(input2)?;
28+
let decoder = Decoder::new(input2)?;
2929
let mut buf_reader = BufReader::new(decoder);
3030

3131
let mut result: Vec<TraceLowLevelEvent> = vec![];
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::io::{self, BufRead, BufReader, Read, Seek, Write};
2+
3+
use fscommon::StreamSlice;
4+
5+
use ruzstd::decoding::StreamingDecoder;
6+
7+
use crate::{TraceLowLevelEvent, cbor_zstd_writer::HEADERV1};
8+
9+
fn is_at_eof<R: BufRead>(reader: &mut R) -> io::Result<bool> {
10+
let buffer = reader.fill_buf()?;
11+
Ok(buffer.is_empty())
12+
}
13+
14+
pub fn read_trace(input: &mut (impl Read + Write + Seek)) -> Result<Vec<TraceLowLevelEvent>, Box<dyn std::error::Error>> {
15+
let end_pos = input.seek(io::SeekFrom::End(0))?;
16+
input.seek(io::SeekFrom::Start(0))?;
17+
18+
let mut header_buf = [0; 8];
19+
let mut buf_reader = BufReader::new(&mut *input);
20+
buf_reader.read_exact(&mut header_buf)?;
21+
if header_buf != HEADERV1 {
22+
panic!("Invalid file header (wrong file format or incompatible version)");
23+
}
24+
25+
input.seek(io::SeekFrom::Start(0))?;
26+
let input2 = StreamSlice::new(&mut *input, 8, end_pos)?;
27+
28+
let decoder = StreamingDecoder::new(input2)?;
29+
let mut buf_reader = BufReader::new(decoder);
30+
31+
let mut result: Vec<TraceLowLevelEvent> = vec![];
32+
33+
while !is_at_eof(&mut buf_reader)? {
34+
let obj = cbor4ii::serde::from_reader::<TraceLowLevelEvent, _>(&mut buf_reader)?;
35+
result.push(obj);
36+
}
37+
38+
Ok(result)
39+
}

runtime_tracing/src/cbor_zstd_writer.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
path::PathBuf,
55
};
66

7-
use ruzstd::encoding::{CompressionLevel, compress};
7+
use zeekstd::Encoder;
88

99
use crate::{
1010
TraceLowLevelEvent,
@@ -20,28 +20,26 @@ pub const HEADERV1: &[u8] = &[
2020
0x00, 0x00,
2121
]; // Reserved, must be zero in this version.
2222

23-
pub struct CborZstdTraceWriter {
23+
pub struct CborZstdTraceWriter<'a> {
2424
base: AbstractTraceWriterData,
2525

2626
trace_events_path: Option<PathBuf>,
27-
trace_events_file: Option<File>,
28-
uncompressed_buf: Vec<u8>,
27+
trace_events_file_zstd_encoder: Option<Encoder<'a, File>>,
2928
}
3029

31-
impl CborZstdTraceWriter {
30+
impl CborZstdTraceWriter<'_> {
3231
/// Create a new tracer instance for the given program and arguments.
3332
pub fn new(program: &str, args: &[String]) -> Self {
3433
CborZstdTraceWriter {
3534
base: AbstractTraceWriterData::new(program, args),
3635

3736
trace_events_path: None,
38-
trace_events_file: None,
39-
uncompressed_buf: Vec::new(),
37+
trace_events_file_zstd_encoder: None,
4038
}
4139
}
4240
}
4341

44-
impl AbstractTraceWriter for CborZstdTraceWriter {
42+
impl AbstractTraceWriter for CborZstdTraceWriter<'_> {
4543
fn get_data(&self) -> &AbstractTraceWriterData {
4644
&self.base
4745
}
@@ -52,37 +50,34 @@ impl AbstractTraceWriter for CborZstdTraceWriter {
5250

5351
fn add_event(&mut self, event: TraceLowLevelEvent) {
5452
let buf: Vec<u8> = Vec::new();
55-
let q = cbor4ii::serde::to_vec(buf, &event).expect("CBOR encode failed");
56-
self.uncompressed_buf.extend_from_slice(&q);
53+
let q = cbor4ii::serde::to_vec(buf, &event).unwrap();
54+
if let Some(enc) = &mut self.trace_events_file_zstd_encoder {
55+
enc.write_all(&q).unwrap();
56+
}
5757
}
5858

5959
fn append_events(&mut self, events: &mut Vec<TraceLowLevelEvent>) {
60-
for e in events.drain(..) {
61-
<Self as AbstractTraceWriter>::add_event(self, e);
60+
for e in events {
61+
AbstractTraceWriter::add_event(self, e.clone());
6262
}
6363
}
6464
}
6565

66-
impl TraceWriter for CborZstdTraceWriter {
66+
impl TraceWriter for CborZstdTraceWriter<'_> {
6767
fn begin_writing_trace_events(&mut self, path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
6868
let pb = path.to_path_buf();
6969
self.trace_events_path = Some(pb.clone());
70-
7170
let mut file_output = std::fs::File::create(pb)?;
7271
file_output.write_all(HEADERV1)?;
73-
self.trace_events_file = Some(file_output);
72+
self.trace_events_file_zstd_encoder = Some(Encoder::new(file_output)?);
7473

7574
Ok(())
7675
}
7776

7877
fn finish_writing_trace_events(&mut self) -> Result<(), Box<dyn std::error::Error>> {
79-
if let Some(mut file) = self.trace_events_file.take() {
80-
let mut cursor = Cursor::new(&self.uncompressed_buf);
81-
compress(&mut cursor, &mut file, CompressionLevel::Fastest);
82-
83-
file.flush()?;
78+
if let Some(enc) = self.trace_events_file_zstd_encoder.take() {
79+
enc.finish()?;
8480

85-
self.uncompressed_buf.clear();
8681
Ok(())
8782
} else {
8883
panic!("finish_writing_trace_events() called without previous call to begin_writing_trace_events()");
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use std::{
2+
fs::File,
3+
io::{Cursor, Write},
4+
path::PathBuf,
5+
};
6+
7+
use ruzstd::encoding::{CompressionLevel, compress};
8+
9+
use crate::{
10+
TraceLowLevelEvent,
11+
abstract_trace_writer::{AbstractTraceWriter, AbstractTraceWriterData},
12+
trace_writer::TraceWriter,
13+
};
14+
15+
/// The next 3 bytes are reserved/version info.
16+
/// The header is 8 bytes in size, ensuring 64-bit alignment for the rest of the file.
17+
pub const HEADERV1: &[u8] = &[
18+
0xC0, 0xDE, 0x72, 0xAC, 0xE2, // The first 5 bytes identify the file as a CodeTracer file (hex l33tsp33k - C0DE72ACE2 for "CodeTracer").
19+
0x01, // Indicates version 1 of the file format
20+
0x00, 0x00,
21+
]; // Reserved, must be zero in this version.
22+
23+
pub struct CborZstdTraceWriter {
24+
base: AbstractTraceWriterData,
25+
26+
trace_events_path: Option<PathBuf>,
27+
trace_events_file: Option<File>,
28+
uncompressed_buf: Vec<u8>,
29+
}
30+
31+
impl CborZstdTraceWriter {
32+
/// Create a new tracer instance for the given program and arguments.
33+
pub fn new(program: &str, args: &[String]) -> Self {
34+
CborZstdTraceWriter {
35+
base: AbstractTraceWriterData::new(program, args),
36+
37+
trace_events_path: None,
38+
trace_events_file: None,
39+
uncompressed_buf: vec![],
40+
}
41+
}
42+
}
43+
44+
impl AbstractTraceWriter for CborZstdTraceWriter {
45+
fn get_data(&self) -> &AbstractTraceWriterData {
46+
&self.base
47+
}
48+
49+
fn get_mut_data(&mut self) -> &mut AbstractTraceWriterData {
50+
&mut self.base
51+
}
52+
53+
fn add_event(&mut self, event: TraceLowLevelEvent) {
54+
let buf: Vec<u8> = Vec::new();
55+
let q = cbor4ii::serde::to_vec(buf, &event).expect("CBOR encode failed");
56+
self.uncompressed_buf.extend_from_slice(&q);
57+
}
58+
59+
fn append_events(&mut self, events: &mut Vec<TraceLowLevelEvent>) {
60+
for e in events.drain(..) {
61+
<Self as AbstractTraceWriter>::add_event(self, e);
62+
}
63+
}
64+
}
65+
66+
impl TraceWriter for CborZstdTraceWriter {
67+
fn begin_writing_trace_events(&mut self, path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
68+
let pb = path.to_path_buf();
69+
self.trace_events_path = Some(pb.clone());
70+
71+
let mut file_output = std::fs::File::create(pb)?;
72+
file_output.write_all(HEADERV1)?;
73+
self.trace_events_file = Some(file_output);
74+
75+
Ok(())
76+
}
77+
78+
fn finish_writing_trace_events(&mut self) -> Result<(), Box<dyn std::error::Error>> {
79+
if let Some(mut file) = self.trace_events_file.take() {
80+
let mut cursor = Cursor::new(&self.uncompressed_buf);
81+
compress(&mut cursor, &mut file, CompressionLevel::Fastest);
82+
83+
file.flush()?;
84+
85+
self.uncompressed_buf.clear();
86+
Ok(())
87+
} else {
88+
panic!("finish_writing_trace_events() called without previous call to begin_writing_trace_events()");
89+
}
90+
}
91+
}

runtime_tracing/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,19 @@
1111
mod abstract_trace_writer;
1212
mod base64;
1313
mod capnptrace;
14+
15+
#[cfg(target_arch = "wasm32")]
16+
#[path = "./cbor_zstd_reader_wasm.rs"]
1417
mod cbor_zstd_reader;
18+
#[cfg(target_arch = "wasm32")]
19+
#[path = "./cbor_zstd_writer_wasm.rs"]
1520
mod cbor_zstd_writer;
21+
22+
#[cfg(not(target_arch = "wasm32"))]
23+
mod cbor_zstd_reader;
24+
#[cfg(not(target_arch = "wasm32"))]
25+
mod cbor_zstd_writer;
26+
1627
mod non_streaming_trace_writer;
1728
mod trace_readers;
1829
mod trace_writer;

0 commit comments

Comments
 (0)