Crate si_trace_print
source ·Expand description
Macros for printing stack-indented trace-like print statements.
Library users should use macros provided in printers
(which are
also listed here).
Basic Usage
use si_trace_print::{
den, deo, dex, defn, defo, defx,
};
fn main() {
den!("hello from main");
deo!("main will be doing stuff...");
func1(3);
deo!("main is done doing stuff.");
dex!("goodbye from main");
}
fn func1(_var: usize) {
defn!("({:?})", _var);
defo!("doing even more stuff...");
defx!();
}
this should print to stderr
$ cargo run
→hello from main
main will be doing stuff...
→func1: (3)
func1: doing even more stuff...
←func1:
main is done doing stuff.
←goodbye from main
An example using a variety of the available println macros. These compile into debug and release builds and print to stdout.
extern crate si_trace_print;
use si_trace_print::{pf1n, pf2n, pfn, pn, po, px};
fn main() {
pn!("hello from main");
pfn!("hello again from main");
pf1n!("hello again from main!");
pf2n!("HELLO AGAIN FROM MAIN!!!");
po!("main will be doing stuff...");
mod1::mod2::func1(3);
po!("main is done doing stuff...");
px!("goodbye from main");
}
mod mod1 {
pub mod mod2 {
use si_trace_print::{
pf1n, pf1o, pf1x, pf1ñ, pf2n, pf2o, pf2x, pf2ñ, pfn, pfo, pfx, pfñ, pñ,
};
pub fn func1(var: usize) {
pf1n!("({:?})", var);
pf1o!("func1 calling func2...");
func2(var + 1);
pf1x!("({:?})", var);
}
fn func2(var: usize) {
pf2n!("({:?})", var);
pf2o!("calling func3...");
func3();
pf2x!("({:?})", var);
}
fn func3() {
pfn!();
func4();
pfo!("almost complete...");
pfx!();
}
fn func4() {
pñ!("func4 is a short function.");
pfñ!("func4 is a short function.");
pf1ñ!("func4 is a short function.");
pf2ñ!("func4 is a short function.");
}
}
}
should print to stdout
→hello from main
→main: hello again from main
→main: hello again from main!
→main: HELLO AGAIN FROM MAIN!!!
main will be doing stuff...
→mod2::func1: (3)
mod2::func1: func1 calling func2...
→mod1::mod2::func2: (4)
mod1::mod2::func2: calling func3...
→func3:
↔func4 is a short function.
↔func4: func4 is a short function.
↔mod2::func4: func4 is a short function.
↔mod1::mod2::func4: func4 is a short function.
func3: almost complete...
←func3:
←mod1::mod2::func2: (4)
←mod2::func1: (3)
main is done doing stuff...
←goodbye from main
Multi-threaded printing and the global lock
To avoid interleaved printing among threads, surround your println!
or
eprintln!
statements in the global lock guard GLOBAL_LOCK_PRINTER
.
Helper functions print_guard
or debug_print_guard
are provided.
use ::si_trace_print::{efn, efx};
use ::si_trace_print::printers::print_guard;
let mut handles: Vec<std::thread::JoinHandle<()>> = vec![];
for n in 0..10 {
let h = std::thread::spawn(move || {
efn!("time to do some work...");
// ...do some work...
let result = n;
// ...a few moments later...
// get the guard before printing
let guard = print_guard();
println!("{}", result);
// drop the guard before calling another si_trace_print macro
drop(guard);
efx!("work complete");
});
handles.push(h);
}
for h in handles {
h.join().unwrap();
}
If using si_trace_print
debug macros (the recommended way to use
this module) then call the debug_print_guard
helper function.
In this code example, guard
is a MutexGuard
in debug builds and
a ()
in non-debug release builds (which is likely optimized away).
use ::si_trace_print::{defn, defx};
use ::si_trace_print::printers::debug_print_guard;
let mut handles: Vec<std::thread::JoinHandle<()>> = vec![];
for n in 0..10 {
let h = std::thread::spawn(move || {
defn!("time to do some work...");
// ...do some work...
let result = n;
// ...a little while later...
// get the guard before printing
let guard = debug_print_guard();
println!("{}", result);
// explicitly drop the guard before calling another si_trace_print macro
drop(guard);
defx!("work complete");
});
handles.push(h);
}
for h in handles {
h.join().unwrap();
}
Modules
- Macros to derive the current function name.
- Macros to print trace statements with stack offset indentation.
- Functions to store a stack offset for indented trace prints and return the appropriate preprint
str
.
Macros
- debug eprintln!
- debug eprintln! in a function plus one namespace level when entering.
- debug eprintln! in a function plus one namespace level with offset.
- debug eprintln! in a function plus one namespace level when exiting.
- debug eprintln! in a function with one namespace levels when entering and exiting.
- debug eprintln! in a function plus two namespace levels when entering.
- debug eprintln! in a function plus two namespace levels with offset.
- debug eprintln! in a function plus two namespace levels when exiting.
- debug eprintln! in a function plus two namespace levels when entering and exiting.
- debug eprintln! in a function when entering.
- debug eprintln! in a function with offset.
- debug eprintln! in a function when exiting.
- debug eprintln! in a function when entering and exiting.
- debug eprintln! when entering.
- debug eprintln! with offset.
- debug eprintln! when exiting.
- debug eprintln! when entering and exiting.
- debug println!
- debug println! in a function plus one namespace level when entering.
- debug println! in a function plus one namespace level with offset.
- debug println! in a function plus one namespace level when exiting.
- debug println! in a function plus one namespace level when entering and exiting.
- debug println! in a function plus two namespace levels when entering.
- debug println! in a function plus two namespace levels with offset
- debug println! in a function plus two namespace levels when exiting.
- debug println! in a function plus two namespace levels when entering and exiting.
- debug println! in a function when entering.
- debug println! in a function with offset.
- debug println! in a function when exiting.
- debug println! in a function when entering and exiting.
- debug println! when entering.
- debug println! with offset.
- debug println! when exiting.
- debug println! when entering and exiting.
- eprintln!
- eprintln! in a function plus one namespace level when entering.
- eprintln! in a function with one namespace levels and offset.
- eprintln! in a function plus one namespace level when exiting.
- eprintln! in a function plus one namespace level when entering and exiting.
- eprintln! in a function plus two namespace levels when entering.
- eprintln! in a function with two namespace levels and offset.
- eprintln! in a function plus two namespace levels when exiting.
- eprintln! in a function plus two namespace levels when entering and exiting.
- eprintln! in a function when entering.
- eprintln! in a function with offset.
- eprintln! in a function when exiting.
- eprintln! in a function when entering and exiting.
- eprintln! when entering.
- eprintln! with offset.
- eprintln! when exiting.
- eprintln! when entering and exiting.
- Return the current function name as a
&'static str
, e.g."my_func"
. - Return the current function name full path as a
&'static str
, e.g."my_lib::my_mod::my_func"
. - Return the current function name plus preceding namespaces as a
&'static str
. - println!
- println! in a function plus one namespace level when entering.
- println! in a function plus one namespace level with offset.
- println! in a function plus one namespace level when exiting.
- println! in a function plus one namespace level when entering and exiting.
- println! in a function plus two namespace levels when entering.
- println! in a function plus two namespace levels with offset.
- println! in a function plus two namespace levels when exiting.
- println! in a function plus two namespace levels when entering and exiting.
- println! in a function when entering.
- println! in a function with offset.
- println! in a function when exiting.
- println! in a function when entering and exiting.
- println! when entering.
- println! with offset.
- println! when exiting.
- println! when entering and exiting.