Skip to main content

gwr_track/
lib.rs

1// Copyright (c) 2020 Graphcore Ltd. All rights reserved.
2
3#![doc(test(attr(deny(unused_must_use))))]
4#![doc = std::include_str!(concat!(env!("OUT_DIR"), "/crate-docs.md"))]
5// Enable warnings for missing documentation
6#![warn(missing_docs)]
7
8use std::cell::RefCell;
9use std::rc::Rc;
10use std::str::FromStr;
11
12#[doc(hidden)]
13pub use log;
14
15pub mod builder;
16pub mod entity;
17pub mod id;
18
19#[cfg(feature = "perfetto")]
20pub mod perfetto_trace_builder;
21
22/// Include the trackers.
23pub mod tracker;
24pub use tracker::{Track, Tracker};
25
26/// A type alias for objects that receive _log_ / _trace_ events.
27pub type Writer = Box<dyn std::io::Write>;
28type SharedWriter = Rc<RefCell<Writer>>;
29
30/// Take the command-line string and convert it to a Level
31#[must_use]
32pub fn str_to_level(lvl: &str) -> log::Level {
33    match log::Level::from_str(lvl) {
34        Ok(level) => level,
35        Err(_) => panic!("Unable to parse level string '{lvl}'"),
36    }
37}
38
39/// Type used for unique IDs
40///
41/// Each _log_/_trace_ event within the application is given a unique ID to
42/// identify it. There are two reserved ID values: [NO_ID](constant.NO_ID.html)
43/// and [ROOT](constant.ROOT.html)
44pub use id::Id;
45
46pub mod test_helpers;
47pub mod trace_visitor;
48
49/// ID value which indicates where there is no valid ID
50pub const NO_ID: Id = id::Id(0);
51
52/// The root ID from which all other IDs are derived
53pub const ROOT: Id = id::Id(1);
54
55/// Create a unique ID for tracking.
56///
57/// The user must specify an entity with a [`Tracker`] to create the ID.
58///
59/// **Note:** this macro should be used when the object being assigned the
60///           [`Id`] will have its creation tracked with the
61///           [`track_create_object`] macro.
62#[macro_export]
63macro_rules! create_id {
64    ($entity:expr) => {{ $entity.tracker.unique_id() }};
65}
66
67/// Add an object creation event.
68///
69/// The details string is only formatted when trace-level events are enabled for
70/// the entity.
71#[macro_export]
72macro_rules! track_create_object {
73    ($entity:expr ; $created:expr, $size:expr, $units:expr, $req_type:expr, $($details:tt)+) => {{
74        let entity = &$entity;
75        if entity.trace_enabled() {
76            let details = format!($($details)+);
77            entity.tracker.create_object(
78                entity.id,
79                $created,
80                $size,
81                $units,
82                $req_type,
83                &details,
84            );
85        }
86    }};
87}
88
89/// Destroy an ID
90///
91/// Destroying an ID indicates to the logging system that this ID is finished
92/// with and should therefore not be used any more. This is not enforced at
93/// runtime, and therefore will not cause any errors to be reported if it is
94/// used.
95#[macro_export]
96macro_rules! destroy_id {
97    ($entity:expr ; $id:expr) => {{
98        $entity.tracker.destroy($entity.id, $id);
99    }};
100}
101
102/// Add an entity destroy event
103#[macro_export]
104macro_rules! destroy {
105    ($entity:expr) => {{
106        match &$entity.parent {
107            Some(parent) => $entity.tracker.destroy($entity.id, parent.id),
108            None => $entity.tracker.destroy($entity.id, $crate::NO_ID),
109        };
110    }};
111}
112
113/// Connect two entities
114#[macro_export]
115macro_rules! connect {
116    ($from_entity:expr ; $to_entity:expr) => {{
117        $from_entity.tracker.connect($from_entity.id, $to_entity.id);
118    }};
119}
120
121/// Update the current time.
122#[macro_export]
123macro_rules! set_time {
124    ($entity:expr ; $time_ns:expr) => {{
125        $entity.tracker.time($entity.id, $time_ns);
126    }};
127}
128
129/// Base macro for log messages of all level.
130///
131/// This wrapper calls both the [`log`](https://docs.rs/log)::log macro and also the
132/// [`Trace`](trait.Trace.html) [message](trait.Trace.html#tymethod.message)
133/// function which will emit `message` tracking events to the Cap'n Proto binary
134/// stream.
135#[macro_export]
136macro_rules! log_base {
137    ($entity:expr ; $lvl:expr, $($arg:tt)+) => {{
138        let entity = &$entity;
139        let level = $lvl;
140        if entity.enabled_for(level) {
141            entity.tracker.log(entity.id, level, format_args!($($arg)+));
142        }
143    }};
144}
145
146/// The `trace` macro provides a wrapper for the [`log`](macro.log.html) macro
147/// at level `log::Level::Trace`
148#[macro_export]
149macro_rules! trace {
150    ($entity:expr ; $($arg:tt)+) => (
151        $crate::log_base!($entity ; $crate::log::Level::Trace, $($arg)+);
152    );
153}
154
155/// The `debug` macro provides a wrapper for the [`log`](macro.log.html) macro
156/// at level `log::Level::Debug`
157#[macro_export]
158macro_rules! debug {
159    ($entity:expr ; $($arg:tt)+) => (
160        $crate::log_base!($entity ; $crate::log::Level::Debug, $($arg)+);
161    );
162}
163
164/// The `info` macro provides a wrapper for the [`log`](macro.log.html) macro at
165/// level `log::Level::Info`
166#[macro_export]
167macro_rules! info {
168    ($entity:expr ; $($arg:tt)+) => (
169        $crate::log_base!($entity ; $crate::log::Level::Info, $($arg)+);
170    );
171}
172
173/// The `warn` macro provides a wrapper for the [`log`](macro.log.html) macro at
174/// level `log::Level::Info`
175#[macro_export]
176macro_rules! warn {
177    ($entity:expr ; $($arg:tt)+) => (
178        $crate::log_base!($entity ; $crate::log::Level::Warn, $($arg)+);
179    );
180}
181
182/// the `error` macro provides a wrapper for the [`log`](macro.log.html) macro
183/// at level `log::Level::Error`
184#[macro_export]
185macro_rules! error {
186    ($entity:expr ; $($arg:tt)+) => (
187        $crate::log_base!($entity ; $crate::log::Level::Error, $($arg)+);
188    );
189}
190
191/// Auto-generated [Cap'n Proto](https://capnproto.org/) module
192///
193/// The contents of this file are created by `build.rs` at compile-time. They
194/// provide all the functions required to build up
195/// [Cap'n Proto](https://capnproto.org/) events as defined in the
196/// `schemas/gwr_trace.capnp` file.
197pub mod gwr_track_capnp {
198    // No need to emit warnings for auto-generated Cap'n Proto code
199    #![allow(missing_docs)]
200    #![allow(clippy::all)]
201    #![allow(clippy::pedantic)]
202    include!(concat!(env!("OUT_DIR"), "/gwr_track_capnp.rs"));
203}