enya-analyzer
Metrics instrumentation indexer for source code repositories.
This crate scans codebases to discover metric instrumentation points and alert rule definitions, building an in-memory index for fast lookups.
Features
Metric Scanning
Discovers metrics defined in source code using tree-sitter parsing:
| Language | Library | Patterns |
|---|---|---|
| Rust | metrics-rs | counter!(), gauge!(), histogram!() |
| Python | prometheus_client | Counter('name', 'help'), Gauge(...), Histogram(...) |
| Go | client_golang | prometheus.NewCounter(CounterOpts{...}), promauto.NewGauge(...) |
| JavaScript | prom-client | new client.Counter({name: '...'}), new Gauge({...}) |
| TypeScript | prom-client | Same as JavaScript, supports .ts and .tsx files |
For each metric, the scanner extracts:
- Metric name (e.g.,
http_requests_total) - Metric kind (counter, gauge, histogram)
- Label keys (e.g.,
["method", "status"]) - File location (path, line, column)
- Function context (containing function and impl type)
Metric Usage Tracking
Beyond definitions, the scanner also tracks where metrics are used ("hot paths"):
| Language | Usage Patterns |
|---|---|
| Python | counter.inc(), gauge.set(value), histogram.observe(value), gauge.dec() |
| Go | counter.Inc(), counter.Add(n), gauge.Set(value), histogram.Observe(value) |
| JavaScript | counter.inc(), gauge.set(value), histogram.observe(value), histogram.startTimer() |
| TypeScript | Same as JavaScript |
For each usage, the scanner extracts:
- Usage kind (increment, set, add, sub, observe, time, etc.)
- Variable name holding the metric
- Label values (if statically determinable)
- File location (path, line, column)
- Function context (containing function and class/impl type)
Alert Scanning
Discovers Prometheus alerting rules in YAML files:
groups:
- name: example
rules:
- alert: HighErrorRate
expr: rate(errors_total[5m]) > 0.1
labels:
severity: critical
annotations:
message: "Error rate is high"
For each alert, the scanner extracts:
- Alert name
- PromQL expression
- Primary metric name (extracted from expression)
- Severity and message
- File location
Lookup Features
- Exact matching: Find metrics by exact name
- Suffix matching: Find
http_requests_totalwhen queryingmyapp_http_requests_total(handles runtime metric prefixes) - Fuzzy search: Case-insensitive substring matching
- Alert lookup: Find alerts that reference a specific metric
Architecture
crates/analyzer/
├── src/
│ ├── lib.rs # Public API exports
│ ├── index.rs # CodebaseIndex - builds and queries the index
│ ├── parser.rs # Tree-sitter parsing utilities
│ ├── repo.rs # Git operations (clone, fetch)
│ └── scanner/
│ ├── mod.rs # Scanner trait and registry
│ ├── rust.rs # Rust metrics-rs scanner
│ ├── python.rs # Python prometheus_client scanner
│ ├── go.rs # Go client_golang scanner
│ ├── javascript.rs # JavaScript prom-client scanner
│ ├── typescript.rs # TypeScript prom-client scanner
│ └── yaml.rs # YAML alert rule scanner
Scanner Trait
Add support for new languages by implementing the Scanner trait:
Usage
use ;
use Path;
// Build an index from a local repository
let progress = new;
let index = build_index_with_progress?;
// Find metrics by name (supports suffix matching for prefixed metrics)
let metrics = index.find_by_name;
// Search for metrics containing a substring
let results = index.search;
// Find alerts referencing a metric
let alerts = index.find_alerts_by_metric;
Excluded Directories
The scanner automatically excludes:
target/(Rust build output).git/vendor/node_modules/