Skip to content
Arxo Arxo

Effects and Telemetry

The engine supports side-effect detection (per-file effect profiles) and runtime telemetry (OpenTelemetry-style traces) for correlation between code structure and runtime behavior.

Side effects are classified using EffectType (from arxo-types::data::effects):

EffectDescription
IoFile or stream I/O
NetworkNetwork requests
StoragePersistent storage (DB, cache)
LogLogging
TimeTime-dependent behavior (e.g. Date, timers)
RandomRandom number generation
MutationObservable mutation (e.g. global state)
LlmLLM/API calls

You can use EffectType::as_str() for string names ("io", "network", etc.) and EffectType::from_str(s) to parse from config or API.

The engine builds an effect index per analyzed codebase. For each file (or entity), you get an EffectProfile (from arxo-types::data::effects):

  • effects: Set of EffectType present in that file.
  • call_site_count: Number of effect call sites.
  • apis_used: List of APIs used (e.g. function names).

EffectProfile helpers:

  • has_effect(EffectType) — whether that effect is present.
  • is_pure() — true if there are no effects (pure function/file).

Effect data is used by metrics such as effect_violations (layer rules that restrict which effects are allowed in which layers) and by quality/observability metrics.

When you use the engine as a library, the DataStore trait (from arxo-types::core::types) exposes the effect index:

// data_store implements DataStore
let effect_index = data_store.effect_index().await?;
// Query per-node effect profiles, check is_pure(), has_effect(...), etc.

Custom metric plugins receive a MetricContext that provides DataStore access, so they can call effect_index() and use it in their computation.

To feed runtime trace data into the engine, configure data.telemetry in your DataConfig (from arxo-types::config::schema):

data:
telemetry:
source_path: "traces/otel.json" # file or directory
format: "otel_json" # otel_json | zipkin_json | jaeger_json
time_window: # optional filter
start: "2024-01-01T00:00:00Z"
end: "2024-01-02T00:00:00Z"
service_name: "my-service" # optional filter
  • source_path: Path to telemetry data (file or directory).
  • format: otel_json, zipkin_json, or jaeger_json.
  • time_window: Optional start/end to restrict which traces are loaded.
  • service_name: Optional service name filter.

The engine parses the traces and builds a telemetry mapping that correlates runtime spans with code (e.g. call graph nodes). Metrics like sensitive_data_flow can use this to prioritize violations on hot paths.

From arxo-types::data::telemetry:

  • Telemetry: Container with traces, time_window, and service_name.
  • Trace: trace_id and spans.
  • Span: span_id, parent_span_id, name, start_time, duration_ms, attributes.
  • TimeWindow: start and end (e.g. for filtering).

The DataStore exposes telemetry() and telemetry_mapping() for metrics and custom plugins that need runtime–code correlation.

ArchitectureConfig (in config schema) defines layers with allowed_effects per layer. The layer_violations and effect_violations metrics compare each file’s effect profile to its layer’s allowed effects and report violations. See Configuration for layer definitions.