Analysis and Querying
Once a computation has been executed (or events have been streamed), PyRapide provides a rich set of query functions that operate on the causal graph. These functions answer questions that timestamp-ordered logs fundamentally cannot.
Computation object. You can obtain one from Engine.run(), StreamProcessor.computation(), or deserialize_computation().critical_path
Returns the longest causal chain in the computation. This is the sequence of events that determines the minimum end-to-end latency.
from pyrapide import critical_path
path = critical_path(computation)
for event in path:
print(f"{event.name} at {event.timestamp}")
root_causes
Given a target event, walks backward through the causal graph to find the originating events that have no causal predecessors.
from pyrapide import root_causes
causes = root_causes(computation, target_event)
# Returns all events with no causal predecessors
# that are ancestors of target_event
impact_set
Given a source event, returns every event that is causally downstream, revealing the full blast radius.
from pyrapide import impact_set
affected = impact_set(computation, source_event)
print(f"{len(affected)} events affected by {source_event.name}")
causal_distance
Returns the length of the shortest causal path between two events. If the events are not causally related, returns None.
from pyrapide import causal_distance
dist = causal_distance(computation, event_a, event_b)
if dist is not None:
print(f"Events are {dist} causal steps apart")
else:
print("Events are causally independent")
common_ancestors
Given two events, finds all events that are causal ancestors of both. Useful for identifying shared root causes of seemingly independent failures.
from pyrapide import common_ancestors
shared = common_ancestors(computation, event_a, event_b)
for ancestor in shared:
print(f"Shared ancestor: {ancestor.name}")
backward_slice
Returns the transitive closure of all causal predecessors of a given event: everything that contributed to it.
from pyrapide import backward_slice
# Everything that led to this failure
predecessors = backward_slice(computation, failure_event)
print(f"{len(predecessors)} events in the backward slice")
forward_slice
Returns the transitive closure of all causal successors of a given event: everything that it affected.
from pyrapide import forward_slice
# Everything affected by this configuration change
successors = forward_slice(computation, config_change_event)
print(f"{len(successors)} events in the forward slice")
backward_slice and forward_slice are the causal equivalents of program slicing in software analysis. They answer "what contributed to X?" and "what did X affect?" respectively.parallel_events
Returns all events that are causally independent of a given event. These are events that happened concurrently with no causal relationship.
from pyrapide import parallel_events
concurrent = parallel_events(computation, event)
print(f"{len(concurrent)} events concurrent with {event.name}")
bottleneck_events
Identifies events that appear on a disproportionate number of causal paths. These are the points where many independent chains converge, and where failures have the largest blast radius.
from pyrapide import bottleneck_events
bottlenecks = bottleneck_events(computation, threshold=0.5)
for event, score in bottlenecks:
print(f"{event.name}: appears on {score:.0%} of causal paths")
event_frequency
Counts the number of times each event type appears in the computation. Useful for profiling and identifying hot paths.
from pyrapide import event_frequency
freq = event_frequency(computation)
for event_type, count in freq.most_common(10):
print(f"{event_type}: {count} occurrences")
causal_density
Returns a ratio of causal edges to total possible edges. A high density means events are tightly coupled; a low density means the system has high concurrency and loose coupling.
from pyrapide import causal_density
density = causal_density(computation)
print(f"Causal density: {density:.3f}")
# 0.0 = fully concurrent (no causal links)
# 1.0 = fully sequential (total order)
bottleneck_events to identify the specific chokepoints.Next Steps
- Prediction: predict future events from causal patterns
- Anomaly Detection: detect deviations from learned causal behavior
- Visualization: render causal graphs for inspection