Skip to content

Commit 5d4d5eb

Browse files
committed
adding examples + formatting
1 parent ae359b8 commit 5d4d5eb

File tree

2 files changed

+374
-11
lines changed

2 files changed

+374
-11
lines changed

inqjet/examples/demo.rs

Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
use std::io::Write;
2+
3+
use inqjet::{ArchiveTag, InqJetBuilder, LevelFilter, Pod};
4+
5+
// -- Pod type: zero-cost memcpy through ring buffer --
6+
7+
#[derive(Pod, Debug, Clone)]
8+
struct OrderInfo {
9+
id: u64,
10+
price: f64,
11+
qty: i64,
12+
}
13+
14+
#[derive(Pod, Debug, Clone)]
15+
struct Tick {
16+
bid: f64,
17+
ask: f64,
18+
seq: u64,
19+
}
20+
21+
// -- Archive tags --
22+
23+
#[derive(Clone, Copy)]
24+
enum Direction {
25+
Inbound,
26+
Outbound,
27+
}
28+
29+
impl Direction {
30+
const fn as_str(self) -> &'static str {
31+
match self {
32+
Direction::Inbound => "INBOUND",
33+
Direction::Outbound => "OUTBOUND",
34+
}
35+
}
36+
}
37+
38+
#[derive(Clone, Copy)]
39+
struct VenueEvent {
40+
venue: &'static str,
41+
direction: Direction,
42+
}
43+
44+
impl ArchiveTag for VenueEvent {
45+
fn write_label(&self, out: &mut dyn Write) {
46+
let _ = write!(out, "{} {}", self.venue, self.direction.as_str());
47+
}
48+
}
49+
50+
#[derive(Clone, Copy)]
51+
struct Heartbeat;
52+
53+
impl ArchiveTag for Heartbeat {
54+
fn write_label(&self, out: &mut dyn Write) {
55+
let _ = out.write_all(b"HEARTBEAT");
56+
}
57+
}
58+
59+
fn main() -> Result<(), Box<dyn std::error::Error>> {
60+
let venue_file = std::fs::File::create("/tmp/inqjet_demo_venue.log")?;
61+
let heartbeat_file = std::fs::File::create("/tmp/inqjet_demo_heartbeat.log")?;
62+
63+
let mut builder = InqJetBuilder::default()
64+
.with_writer(std::io::stdout())
65+
.with_log_level(LevelFilter::Trace);
66+
67+
let mut venue_archive = builder.add_archive::<VenueEvent>(venue_file, 65536);
68+
let mut heartbeat_archive = builder.add_archive::<Heartbeat>(heartbeat_file, 4096);
69+
70+
let guard = builder.build()?;
71+
72+
// =====================================================================
73+
// 1. All log levels
74+
// =====================================================================
75+
eprintln!("--- all levels ---");
76+
inqjet::error!("something went wrong");
77+
inqjet::warn!("approaching memory limit");
78+
inqjet::info!("server ready");
79+
inqjet::debug!("connection pool initialized");
80+
inqjet::trace!("entering main loop");
81+
82+
// =====================================================================
83+
// 2. Custom targets
84+
// =====================================================================
85+
eprintln!("--- custom targets ---");
86+
inqjet::info!(target: "app::startup", "binding to port {}", 8080u32);
87+
inqjet::error!(target: "app::db", "connection refused: {}", "timeout");
88+
inqjet::warn!(target: "net::ws::binance", "slow frame: {}ms", 47u64);
89+
inqjet::debug!(target: "engine::matching", "order book depth: {}", 1247u32);
90+
inqjet::trace!(target: "hot::path", "tick processed in {}ns", 832u64);
91+
92+
// =====================================================================
93+
// 3. Primitive POD types (Tier 1 — memcpy)
94+
// =====================================================================
95+
eprintln!("--- POD primitives ---");
96+
inqjet::info!(
97+
"u8={} u16={} u32={} u64={}",
98+
255u8,
99+
65535u16,
100+
42u32,
101+
99999u64
102+
);
103+
inqjet::info!(
104+
"i8={} i16={} i32={} i64={}",
105+
-1i8,
106+
-100i16,
107+
-42i32,
108+
-99999i64
109+
);
110+
inqjet::info!("f32={} f64={}", 3.14f32, 2.718281828f64);
111+
inqjet::info!("bool true={} false={}", true, false);
112+
inqjet::info!("u128={}", u128::MAX);
113+
inqjet::info!("i128={}", i128::MIN);
114+
115+
// =====================================================================
116+
// 4. User-defined Pod structs (Tier 1 — memcpy)
117+
// =====================================================================
118+
eprintln!("--- Pod structs ---");
119+
let order = OrderInfo {
120+
id: 98321,
121+
price: 42150.75,
122+
qty: 25,
123+
};
124+
inqjet::info!(
125+
"order filled: id={} price={:.2} qty={}",
126+
order.id,
127+
order.price,
128+
order.qty
129+
);
130+
131+
let tick = Tick {
132+
bid: 42000.50,
133+
ask: 42001.25,
134+
seq: 7743921,
135+
};
136+
inqjet::debug!(
137+
"tick: bid={:.2} ask={:.2} seq={}",
138+
tick.bid,
139+
tick.ask,
140+
tick.seq
141+
);
142+
143+
// =====================================================================
144+
// 5. String types (Tier 1.5 — length-prefixed copy)
145+
// =====================================================================
146+
eprintln!("--- strings ---");
147+
inqjet::info!("user {} logged in", "alice");
148+
inqjet::info!("venue: {}", "BINANCE");
149+
150+
let owned = String::from("dynamic-session-id-abc123");
151+
inqjet::info!("session: {}", owned);
152+
153+
let empty_str = "";
154+
inqjet::debug!("empty string: [{}]", empty_str);
155+
156+
let long_str = "the quick brown fox jumps over the lazy dog ".repeat(5);
157+
inqjet::debug!("long string ({} chars): {}", long_str.len(), long_str);
158+
159+
// =====================================================================
160+
// 6. Float formatting
161+
// =====================================================================
162+
eprintln!("--- float formatting ---");
163+
inqjet::info!("price: {:.2}", 42150.756789f64);
164+
inqjet::info!("precise: {:.8}", std::f64::consts::PI);
165+
inqjet::info!("scientific: {:e}", 1.23456e-10f64);
166+
inqjet::info!("scientific upper: {:E}", 9.87654e20f64);
167+
inqjet::info!("no decimals: {:.0}", 42.999f64);
168+
169+
// =====================================================================
170+
// 7. Hex, octal, binary formatting
171+
// =====================================================================
172+
eprintln!("--- hex/octal/binary ---");
173+
inqjet::info!("hex: {:x}", 0xDEADBEEFu32);
174+
inqjet::info!("HEX: {:X}", 0xCAFEBABEu32);
175+
inqjet::info!("hex prefixed: {:#x}", 255u32);
176+
inqjet::info!("hex padded: {:08x}", 0x42u32);
177+
inqjet::info!("octal: {:o}", 511u32);
178+
inqjet::info!("binary: {:b}", 0b1010_1100u8);
179+
inqjet::info!("binary prefixed: {:#b}", 42u8);
180+
181+
// =====================================================================
182+
// 8. Width and alignment
183+
// =====================================================================
184+
eprintln!("--- width/alignment ---");
185+
inqjet::info!("right-aligned: [{:>10}]", 42u32);
186+
inqjet::info!("left-aligned: [{:<10}]", 42u32);
187+
inqjet::info!("zero-padded: [{:010}]", 42u32);
188+
189+
// =====================================================================
190+
// 9. Debug formatting (Tier 2 — fallback / eager format)
191+
// =====================================================================
192+
eprintln!("--- debug formatting ---");
193+
let data = vec![1u32, 2, 3, 4, 5];
194+
inqjet::info!("vec: {:?}", data);
195+
196+
let nested: Vec<Vec<u32>> = vec![vec![1, 2], vec![3, 4, 5]];
197+
inqjet::debug!("nested: {:?}", nested);
198+
199+
let tuple = (42u32, "hello", true);
200+
inqjet::debug!("tuple: {:?}", tuple);
201+
202+
let map: std::collections::HashMap<&str, u32> =
203+
[("alice", 1), ("bob", 2)].into_iter().collect();
204+
inqjet::debug!("map: {:?}", map);
205+
206+
let option_some: Option<u32> = Some(42);
207+
let option_none: Option<u32> = None;
208+
inqjet::info!("some={:?} none={:?}", option_some, option_none);
209+
210+
// =====================================================================
211+
// 10. Mixed tiers in one call
212+
// =====================================================================
213+
eprintln!("--- mixed tiers ---");
214+
// Pod u64 (T1) + &str (T1.5) + Vec debug (T2)
215+
inqjet::info!(
216+
"request #{} from user {} matched: {:?}",
217+
12345u64,
218+
"alice",
219+
vec![100u32, 200, 300]
220+
);
221+
222+
// f64 with precision (T1) + String (T1.5) + bool (T1)
223+
inqjet::info!(
224+
"trade: price={:.4} symbol={} aggressive={}",
225+
42150.7568f64,
226+
"BTC-USD",
227+
true
228+
);
229+
230+
// Multiple strings + pod
231+
inqjet::info!(
232+
"{} {} {} from {} status={} latency={}us",
233+
"POST",
234+
"/api/v2/orders",
235+
"HTTP/1.1",
236+
"10.0.1.42",
237+
201u32,
238+
847u64
239+
);
240+
241+
// =====================================================================
242+
// 11. Static messages (no args)
243+
// =====================================================================
244+
eprintln!("--- static messages ---");
245+
inqjet::info!("health check passed");
246+
inqjet::trace!("entering critical section");
247+
inqjet::error!("fatal: unrecoverable state");
248+
249+
// =====================================================================
250+
// 12. log crate bridge (log-compat feature)
251+
// =====================================================================
252+
eprintln!("--- log bridge ---");
253+
log::error!("bridge error: {}", "something broke");
254+
log::warn!("bridge warn: retries={}", 3);
255+
log::info!("bridge info: user={}", "bob");
256+
log::debug!("bridge debug: {:?}", vec![1, 2, 3]);
257+
log::trace!("bridge trace");
258+
259+
// =====================================================================
260+
// 13. Runtime level change
261+
// =====================================================================
262+
eprintln!("--- level change ---");
263+
inqjet::info!("about to restrict to WARN only");
264+
inqjet::set_level(LevelFilter::Warn);
265+
inqjet::trace!("this trace is filtered");
266+
inqjet::debug!("this debug is filtered");
267+
inqjet::info!("this info is filtered");
268+
inqjet::warn!("this warn gets through");
269+
inqjet::error!("this error gets through");
270+
inqjet::set_level(LevelFilter::Trace);
271+
inqjet::info!("back to trace level");
272+
273+
// =====================================================================
274+
// 14. Multi-threaded logging
275+
// =====================================================================
276+
eprintln!("--- multi-threaded ---");
277+
let mut handles = Vec::new();
278+
for tid in 0..4u32 {
279+
let mut archive_clone = venue_archive.clone();
280+
handles.push(std::thread::spawn(move || {
281+
for msg in 0..5u32 {
282+
inqjet::info!("thread-{} message-{}", tid, msg);
283+
archive_clone.write(
284+
VenueEvent {
285+
venue: if tid % 2 == 0 { "BINANCE" } else { "COINBASE" },
286+
direction: if msg % 2 == 0 {
287+
Direction::Inbound
288+
} else {
289+
Direction::Outbound
290+
},
291+
},
292+
format!("thread-{tid} msg-{msg}").as_bytes(),
293+
);
294+
}
295+
}));
296+
}
297+
for h in handles {
298+
h.join().expect("thread panicked");
299+
}
300+
301+
// =====================================================================
302+
// 15. Multiple archive streams
303+
// =====================================================================
304+
eprintln!("--- multiple archives ---");
305+
venue_archive.write(
306+
VenueEvent {
307+
venue: "BINANCE",
308+
direction: Direction::Inbound,
309+
},
310+
b"8=FIX.4.4|35=W|55=BTC-USD|270=42150.75",
311+
);
312+
venue_archive.write(
313+
VenueEvent {
314+
venue: "BINANCE",
315+
direction: Direction::Outbound,
316+
},
317+
b"8=FIX.4.4|35=D|55=BTC-USD|44=42149.00|38=1.5",
318+
);
319+
venue_archive.write(
320+
VenueEvent {
321+
venue: "COINBASE",
322+
direction: Direction::Inbound,
323+
},
324+
b"8=FIX.4.4|35=8|55=ETH-USD|31=2850.25|32=10.0",
325+
);
326+
327+
heartbeat_archive.write(Heartbeat, b"seq=1");
328+
heartbeat_archive.write(Heartbeat, b"seq=2");
329+
heartbeat_archive.write(Heartbeat, b"seq=3");
330+
331+
// =====================================================================
332+
// 16. Unicode / multi-byte content
333+
// =====================================================================
334+
eprintln!("--- unicode ---");
335+
inqjet::info!("greeting: {}", "こんにちは");
336+
inqjet::info!("emoji: {}", "🚀💰📊");
337+
inqjet::info!("accented: {}", "café résumé naïve");
338+
inqjet::info!(
339+
"mixed: {} traded {} at {:.2}",
340+
"münchen_desk",
341+
"BTC€",
342+
42000.50f64
343+
);
344+
345+
// Guard drop joins archiver thread, flushes everything
346+
drop(guard);
347+
348+
// Print archive contents
349+
eprintln!("\n=== venue archive ===");
350+
eprint!("{}", std::fs::read_to_string("/tmp/inqjet_demo_venue.log")?);
351+
352+
eprintln!("\n=== heartbeat archive ===");
353+
eprint!(
354+
"{}",
355+
std::fs::read_to_string("/tmp/inqjet_demo_heartbeat.log")?
356+
);
357+
358+
Ok(())
359+
}

0 commit comments

Comments
 (0)