Qtrace (qtrace v1.0.0)
View SourceQuick function latency analysis and visualization based on Erlang tracing.
Qtrace
traces function calls and collects latency measurements. Uses
histogram-based aggregation to provide quantile analysis (P50, P95, P99)
and terminal-based visualization of performance distributions.
Usage
session = Qtrace.start_session(:all)
Qtrace.trace_function(session, MyApp, :my_function, 2)
Qtrace.trace_function(session, MyApp, :another_function, 1)
# ... run your code ...
Qtrace.plot_all_histograms(session)
# Getting p10
Qtrace.get_quantile(session, 0.10, MyApp, :my_function, 2)
Example output
Latency Histogram: Qtrace.Demo.web_request/0
================================================================================
0 13 26 39 52
5.9ms │███ (3)
6.9ms │█ (1)
8.1ms │██ (2)
10.3ms │█ (1)
11.2ms │██████ (5)
12.1ms │█████ (4)
13.2ms │███ (3)
14.2ms │███████ (6)
15.4ms │████████████████ (14)
16.7ms │█████████████████ (15)
18.1ms │████████████████████ (17)
19.6ms │█████████████████████████████████ (29)
21.3ms │██████████████████████████████████████████████████████████ (50)
23.0ms │██████████████████████████████████████████ (36)
24.9ms │███████████████████████████████████████████████ (41)
27.0ms │████████████████████████████████████████████████████████████ (52)
29.3ms │█████████████████████████████████████████████████████████ (49)
31.7ms │███████████████████████████████████████████████████████████ (51)
34.4ms │██████████████████████████████████████ (33)
37.2ms │████████████████████████████████████████ (35)
40.3ms │████████████████████████ (21)
43.7ms │███████ (6)
47.3ms │███ (3)
51.3ms │██ (2)
134.0ms │██ (2)
157.2ms │█ (1)
199.9ms │█ (1)
216.6ms │█████████ (8)
234.6ms │██ (2)
254.2ms │██ (2)
275.4ms │███ (3)
298.3ms │██ (2)
323.2ms │██ (2)
└────────────────────────────────────────────────────────────
0 13 26 39 52
Stats:
Min: 5.9ms
Max: 323.2ms
Samples: 502
P50: 27.0ms
P95: 47.3ms
P99: 275.4ms
Session Management
Tracing is automatically stopped when the trace session gets garbage collected. The trace process may live for a bit longer: it lives for up to two minutes of inactivity.
You can also stop sessions or clean up trace data manually:
Qtrace.stop_session(session) # Stop the trace session
Qtrace.cleanup(session) # Stop the tracer process that stores the results
Notice that, in some situations, you may need to ensure that the session doesn't get garbage collected to avoid the trace stopping unexpectedly.
Notes
- Sessions auto-stop when querying results
- Measurements are in microseconds
- Buckets have an error of up to 4%
Summary
Functions
Adds processes to an existing tracing session.
Stops the tracer process for a session.
Builds histogram data from traced function measurements.
Gets a quantile from traced function performance data. Returns latency in microseconds.
Displays histograms for all traced functions.
Displays a histogram of latency measurements in the terminal.
Removes processes from an existing tracing session.
Starts a new tracing session.
Stops a tracing session. Trace results remain available until cleanup.
Enables tracing for a specific function.
Functions
@spec add_processes(Qtrace.Session.t(), :all | :existing | :new | pid()) :: non_neg_integer()
Adds processes to an existing tracing session.
Example
session = Qtrace.start_session(:existing)
Qtrace.add_processes(session, :new) # Now traces existing + new processes
@spec cleanup(Qtrace.Session.t()) :: :ok
Stops the tracer process for a session.
Example
session = Qtrace.start_session(:all)
# ... do tracing work ...
Qtrace.cleanup(session) # Immediately stop the tracer
@spec get_histogram(Qtrace.Session.t(), module(), atom(), non_neg_integer()) :: Qtrace.Histogram.t() | nil
Builds histogram data from traced function measurements.
Returns a %Qtrace.Histogram{}
struct or nil
if no data available.
@spec get_quantile( Qtrace.Session.t(), quantile :: float(), module(), function_name :: atom(), arity() ) :: number() | nil
Gets a quantile from traced function performance data. Returns latency in microseconds.
Examples
# Get median latency (P50)
p50 = Qtrace.get_quantile(session, 0.5, MyApp, :my_function, 1)
# Get 95th percentile
p95 = Qtrace.get_quantile(session, 0.95, MyApp, :my_function, 1)
@spec plot_all_histograms( Qtrace.Session.t(), keyword() ) :: :ok
Displays histograms for all traced functions.
Options
:width
- Width of the histogram bars (default: 60)
@spec plot_histogram( Qtrace.Session.t(), module(), atom(), non_neg_integer(), keyword() ) :: :ok
Displays a histogram of latency measurements in the terminal.
Options
:width
- Width of the histogram bars (default: 60)
Example
Qtrace.plot_histogram(session, MyApp, :my_function, 1)
@spec remove_processes(Qtrace.Session.t(), :all | :existing | :new | pid()) :: non_neg_integer()
Removes processes from an existing tracing session.
Example
session = Qtrace.start_session(:all)
Qtrace.remove_processes(session, :new) # Stop tracing new processes
@spec start_session(:all | :existing | :new | pid()) :: Qtrace.Session.t()
Starts a new tracing session.
Parameters
processes
- Which processes to trace (:all
,:existing
,:new
, or apid()
)
Returns
Returns a Qtrace.Session.t()
struct containing the session details. If this struct
is garbage collected, the trace stops.
Examples
# Trace all processes
session = Qtrace.start_session(:all)
# Trace only existing processes with a custom name
session = Qtrace.start_session(:existing, :my_trace_session)
# Trace a specific process
session = Qtrace.start_session(self())
@spec stop_session(Qtrace.Session.t()) :: Qtrace.Session.t()
Stops a tracing session. Trace results remain available until cleanup.
Example
session = Qtrace.start_session(:all)
# ... do tracing work ...
Qtrace.stop_session(session)
@spec trace_function(Qtrace.Session.t(), module(), atom(), non_neg_integer()) :: non_neg_integer()
Enables tracing for a specific function.
Example
session = Qtrace.start_session(:all)
Qtrace.trace_function(session, Enum, :map, 2)
# Now all calls to Enum.map/2 will be traced
Restrictions
Some modules cannot be traced:
:tracer
Qtrace
and its submodulesDogSketch.SimpleDog