Expand description
§Overview
A tracing library that allows you to efficiently record timestamps and metadata as datapoints within a span.
The Chronograph is the main entry point for starting spans.
Spans are recorded when they are dropped from memory where an underlying SpanRecorder is responsible for recording a span’s data.
§Spans
All spans contain a unique monotonically increasing ID, a start unix time, a start instant, an end instant, and user datapoints.
- The start unix time is the unix time at the start of the span.
- The start instant is a monotonic instant, accurate nanosecond timer elapsed from when the Cronograph was started.
- The start instant can be used to calculate the duration of the span.
- The end instant is a monotonic instant, accurate nanosecond timer elapsed from when the Cronograph was started.
- User datapoints are typically recorded as “instant” time measurements, but they can also include metadata as simple types.
§Datapoints
User datapoints are recorded as a set of key-value pairs.
The DatapointId key is serialized as a u64 value.
- Any
impl Into<DatapointId>
can be used as a datapoint. - A
u64
will be used as-is. - A
&str
will be converted to a u64 using zwohash to derive a one-way, consistent u64 value.
The RecordValue can be one of the following types:
- Instant: A monotonic instant, accurate nanosecond timer elapsed from when the Cronograph was started.
- UnixTime: A unix time, as nanoseconds since epoch.
- Utf8String: A string value formatted as UTF-8.
- I32: A 32-bit signed integer.
- I64: A 64-bit signed integer.
- I128: A 128-bit signed integer.
- U32: A 32-bit unsigned integer.
- U64: A 64-bit unsigned integer.
- U128: A 128-bit unsigned integer.
- F32: A 32-bit floating point number.
- F64: A 64-bit floating point number.
§Sampling
Spans can elect to be sampled. It is most efficient to use a sampling rate that is a power of two.
§Global Chronograph
The global chronograph is a singleton that can be used to record spans.
It is initialized by calling the init function, and can be accessed with the global function.
§Macros
The macros module provides macros for recording datapoints.
- macros::start_span can be used to start a new thread-local span from the global chronograph.
- macros::record_instant can be used to record an instant datapoint to the current thread-local span.
- macros::record_unix_time can be used to record a unix time datapoint.
- macros::record_value can be used to record a value datapoint.
- macros::end_span can be used to end the current thread-local span.
- macros::take_span can be used to take the current thread-local span.
§Thread-local Spans
Thread-local spans can be used to record spans without needing to keep a reference to the Span. These are the same thread-local spans used by the macros module.
A thread-local span can be started with the global chronograph by calling the start_threadlocal_span function. You may alternative set it to any arbitraty span using the set_threadlocal_span function.
The thread-local span can be accessed with the get_threadlocal_span function or with the included macros.
end_threadlocal_span and take_threadlocal_span can be used to end/take the current thread-local span
§Global Instance Example with Macros
use std::time::Duration;
use std::thread::sleep;
use chronograph::macros::*;
use chronograph::recorder::batch::*;
use chronograph::schema::*;
use chronograph::Chronograph;
// Create a batching span recorder that will print each batch.
// Your code should elect to store the results somewhere.
// The collect callback function is called from a dedicated collector thread.
let recorder = BatchingSpanRecorder::start(
Box::new(|batch: SpanBatch| {
let serialized: Vec<u8> = batch.into();
let deserialized = SpanBatch::try_from(serialized.as_slice()).unwrap();
println!("collected {:?}", deserialized);
println!("serialized to {} bytes", serialized.len());
}),
BatchCollectionOptions::default().with_batch_size_threshold(4),
);
// Initialize the global chronograph and record some random spans.
chronograph::init(
Chronograph::builder()
.with_recorder(recorder)
.with_sample_rate(16) // it's most efficient to sample at a power of two
.build(),
);
// Record some random data
for _ in 0..1000 {
start_span!();
record_instant!("my_op_start");
record_value!("count", 42);
record_instant!("mt_op_end");
end_span!();
sleep(Duration::from_millis(1));
}
// Give the collector thread a chance to wakeup and batch spans.
sleep(Duration::from_millis(100));
§Zero-Magic Example
Example without macros or global instances.
use chronograph::recorder::batch::*;
use chronograph::schema::*;
use chronograph::Chronograph;
use std::thread::sleep;
use std::time::Duration;
// Create a batching span recorder that will print each batch.
// Your code should elect to store the results somewhere.
// The collect callback function is called from a dedicated collector thread.
let recorder = BatchingSpanRecorder::start(
Box::new(|batch: SpanBatch| {
let serialized: Vec<u8> = batch.into();
let deserialized = SpanBatch::try_from(serialized.as_slice()).unwrap();
println!("collected {:?}", deserialized);
println!("serialized to {} bytes", serialized.len());
}),
BatchCollectionOptions::default().with_batch_size_threshold(4),
);
// Create a chronograph and record some random spans.
let chronograph = Chronograph::builder()
.with_recorder(recorder)
.with_sample_rate(16) // it's most efficient to sample at a power of two
.build();
// Record some random data
for _ in 0..1000 {
let mut span = chronograph.start_span();
span.record_instant("my_op_start");
span.record_value("count", 42);
span.record_instant("my_op_end");
sleep(Duration::from_millis(1));
}
// Give the collector thread a chance to wakeup and batch spans.
sleep(Duration::from_millis(100));
Re-exports§
pub use chronograph_macros as macros;
Modules§
- processor
- Traits for user to hook into completed spans by reference.
- recorder
- schema
- Serialization and deserialization of chronograph data, utilizing rkyv for fast serialization and deserialization.
Structs§
- Chronograph
- The main chronograph struct, which is used to start spans.
- Chronograph
Builder - Created using Chronograph::builder
- Span
- A span records a set of related datapoints. The span data is recorded when the span is dropped from memory.
Functions§
- end_
threadlocal_ span - Explicitly end the current thread-local span, dropping it from memory if it existed.
- get_
threadlocal_ span - Get a mutable reference to the current thread-local span. If no span exists, a new one will be automatically created using the global chronograph. This ensures that a valid span is always available.
- global
- Get a reference to the global chronograph.
If
init
has not been called, a no-op chronograph will be returned. - init
- Initialize the global chronograph.
- set_
threadlocal_ span - Set the current thread-local span.
- start_
threadlocal_ span - Start a new current thread-local span from the global chronograph.
- take_
threadlocal_ span - Take the current thread-local span, leaving
None
in its place.