Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
255dbcb
relabel: add Prometheus-compatible target and metric relabeling
bwplotka Nov 8, 2026
df3870c
relabel: reject explicit empty string in Action deserialization
bwplotka Nov 9, 2026
7bb7131
relabel: skip serializing unmodified default regex in Config
bwplotka Nov 9, 2026
59ec376
relabel: default ValidationScheme and Config::name_validation_scheme …
bwplotka Nov 9, 2026
7b9aee9
relabel: avoid redundant allocations in LabelMap, set_or_del, and md5…
bwplotka Nov 9, 2026
3603d0d
relabel: align expand_template variable extraction with Go regexp.Exp…
bwplotka Nov 9, 2026
4dabfa6
relabel: preserve empty target override in populate_discovered_labels…
bwplotka Nov 9, 2026
00a891d
relabel: resolve conflicting exported_ sample labels in ascending len…
bwplotka Nov 9, 2026
5cfb190
relabel: expand unit tests for serde round-trips, exported_ collision…
bwplotka Nov 9, 2026
b946d7c
relabel: add Stage 1 __name__ pushdown and Stage 2 dictionary-vectori…
bwplotka Nov 9, 2026
c81b31f
docs: specify two-stage metric relabeling and dictionary execution in…
bwplotka Nov 9, 2026
ea5fa0a
relabel: validate target label names in Lowercase, Uppercase, HashMod…
bwplotka Nov 9, 2026
5aa9647
relabel: document batch-dictionary collision scope on resolve_conflic…
bwplotka Nov 9, 2026
91eeaff
relabel: return DeleteTarget for present empty values in in-place Low…
bwplotka Nov 9, 2026
2c19de5
relabel: add Config::validate error assertions for hashmod, replaceme…
bwplotka Nov 9, 2026
eb45d25
relabel: assert exact HashMod outputs for multi-block MD5 boundary le…
bwplotka Nov 9, 2026
683e3d6
relabel: test DropEqual, KeepEqual mismatch, and empty source_labels …
bwplotka Nov 9, 2026
184e4bd
relabel: order longer exported_foo before foo in resolve_conflicting_…
bwplotka Nov 9, 2026
6c0935c
relabel: expand Stage 2 dictionary transform tests and end-to-end equ…
bwplotka Nov 9, 2026
ddbb77b
benches: add benchfmt.rs relabel benchmark suite
bwplotka Nov 9, 2026
c5242b3
relabel: fast-path default (.*) regex and single-capture $1 replacements
bwplotka Nov 9, 2026
2e56efb
relabel: validate scrape interval and timeout in populate_labels
bwplotka Nov 10, 2026
d947456
relabel: keep RE2 Perl classes (\d, \w, \s, \b) ASCII-only in Regexp
bwplotka Nov 10, 2026
4762483
relabel: match Go per-rune ToUpper and ToLower case mapping
bwplotka Nov 10, 2026
a91842a
relabel: stop template variable scan at non-decimal Unicode numbers l…
bwplotka Nov 10, 2026
faedc22
relabel: remove unused Action::Empty variant
bwplotka Nov 10, 2026
cd7c4bd
relabel: drop unused RelabelConfig type alias
bwplotka Nov 10, 2026
da3eab7
relabel: rename Regexp::is_default_pattern to is_implicit_default
bwplotka Nov 10, 2026
358ce0b
relabel: share hashmod_value helper across scalar and dictionary paths
bwplotka Nov 10, 2026
4869816
relabel: share direct_replacement fast path across scalar and diction…
bwplotka Nov 10, 2026
723f466
relabel: extract classify_value_transform helper
bwplotka Nov 10, 2026
5c8806c
relabel: reuse CaptureLocations via captures_read instead of per-call…
bwplotka Nov 10, 2026
3531f9f
relabel: drop redundant is_match check in LabelMap
bwplotka Nov 10, 2026
4ad29b6
relabel: avoid per-value String allocation for single-capture $1 repl…
bwplotka Nov 10, 2026
7b87a70
relabel: evaluate Stage 2 single-label rules lazily on referenced sou…
bwplotka Nov 10, 2026
55a8c6a
benches: materialize output attribute rows and dictionary updates in …
bwplotka Nov 10, 2026
4d738be
benches: bind named Stage 2 configs instead of slice indexing
bwplotka Nov 10, 2026
e643e2d
tests: convert ported TestRelabel suite into table-driven loop
bwplotka Nov 10, 2026
1383fb5
docs: unify specification at specs/SPEC.md across expfmt and relabel
bwplotka Nov 10, 2026
1b264d7
docs: specify how Stage 2 metric_relabel_configs rules read and overr…
bwplotka Nov 10, 2026
1c2ed48
docs: clarify Stage 1 pushdown checks wire series __name__ transitions
bwplotka Nov 10, 2026
3eab35c
docs: mark ArrowDecoder Stage 1/2 relabel wiring as planned for Phase…
bwplotka Nov 10, 2026
c494f1c
docs: document intentional batch-wide exported_ dictionary behavior v…
bwplotka Nov 10, 2026
65f1954
relabel: stack-allocate CaptureLocations per Replace and LabelMap rule
bwplotka Nov 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Do not use Rust language or std features newer than `rust-version` in `Cargo.tom

## Spec

[specs/expfmt/SPEC.md](specs/expfmt/SPEC.md) is the contract for `expfmt`. If you change behavior the spec describes, update the spec in the same PR.
[specs/SPEC.md](specs/SPEC.md) is the specification contract for `scrape.rs` (`expfmt`, `relabel`, and scrape pipeline integration). If you change behavior the spec describes, update the spec in the same PR.

## Test data

Expand Down
58 changes: 58 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,37 @@ categories = ["parser-implementations", "encoding"]
exclude = ["tests/otap-compat"]

[features]
default = ["arrow", "dto"]
default = ["arrow", "dto", "relabel"]
arrow = ["dep:arrow-array", "dep:arrow-buffer", "dep:arrow-schema"]
dto = ["dep:prost", "dep:prost-types"]
relabel = ["dep:regex", "dep:serde"]

[dependencies]
arrow-array = { version = "59", default-features = false, optional = true }
arrow-buffer = { version = "59", default-features = false, optional = true }
arrow-schema = { version = "59", default-features = false, optional = true }
prost = { version = "0.14", optional = true }
prost-types = { version = "0.14", optional = true }
regex = { version = "1", optional = true }
serde = { version = "1", features = ["derive"], optional = true }
thiserror = "2"

[dev-dependencies]
benchfmt = { git = "https://github.com/bwplotka/benchfmt.rs" }
prost-build = "=0.14.4"
protox = "0.10"
serde_json = "1"

[[bench]]
name = "decode"
harness = false
required-features = ["arrow"]

[[bench]]
name = "relabel"
harness = false
required-features = ["relabel"]

[lints.rust]
missing_docs = "warn"
unsafe_code = "forbid"
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@ Service discoveries
-> Target relabeling
-> Scrape manager / HTTP fetch
-> Streaming expfmt parser
-> Metric relabeling / drop hook
-> Stage 1: family `__name__` filter pushdown
-> Metric family assembly & string interning
-> Stage 2: dictionary-vectorized relabeling & `honor_labels`
-> Columnar Apache Arrow (OTAP) batches or Protobuf DTOs
```

The project serves two main use cases:

1. Columnar scraping for OpenTelemetry Arrow. [`open-telemetry/otel-arrow#3277`](https://github.com/open-telemetry/otel-arrow/issues/3277) defines an OTAP-native `prometheus_scrape` receiver in Rust. `scrape.rs` streams scrape bytes through pre-allocation relabeling and metric family assembly directly into Apache Arrow (`OtapArrowRecords`) tables on thread-per-core `!Send` runtimes with bounded memory.
1. Columnar scraping for OpenTelemetry Arrow. [`open-telemetry/otel-arrow#3277`](https://github.com/open-telemetry/otel-arrow/issues/3277) defines an OTAP-native `prometheus_scrape` receiver in Rust. `scrape.rs` streams scrape bytes through early `__name__` family filtering, metric family assembly, and dictionary-vectorized relabeling directly into Apache Arrow (`OtapArrowRecords`) tables on thread-per-core `!Send` runtimes with bounded memory.
2. Standalone Rust Prometheus tooling. Validation harnesses such as OpenTelemetry Weaver live-checking `/metrics` endpoints against semantic conventions, CLIs, and custom collectors can use individual components (such as `expfmt` DTO decoding or `relabel`) without pulling in the full scrape runtime.

## Components and scope

| Component | Status | Specification | Scope |
| :--- | :--- | :--- | :--- |
| `expfmt` | In progress | [specs/expfmt/SPEC.md](./specs/expfmt/SPEC.md) | `Content-Type` and `Accept` negotiation, zero-copy streaming parsers for Prometheus Text 0.0.4, OpenMetrics 1.0, OpenMetrics 2.0, and Prometheus Protobuf, primary Apache Arrow / OTAP decoder (`ArrowDecoder`), and [`MetricFamily`](https://github.com/prometheus/prometheus/blob/main/prompb/io/prometheus/client/metrics.proto) protobuf DTO decoder. |
| `relabel` | Planned | TBD | Prometheus-compatible target and metric relabeling (`replace`, `keep`, `drop`, `hashmod`, `labelmap`, `labeldrop`, `labelkeep`, `lowercase`, `uppercase`, `keepequal`, `dropequal`), including pre-allocation filtering on borrowed parser label buffers. |
| `expfmt` | In progress | [specs/SPEC.md](./specs/SPEC.md) | `Content-Type` and `Accept` negotiation, zero-copy streaming parsers for Prometheus Text 0.0.4, OpenMetrics 1.0, OpenMetrics 2.0, and Prometheus Protobuf, primary Apache Arrow / OTAP decoder (`ArrowDecoder`), and [`MetricFamily`](https://github.com/prometheus/prometheus/blob/main/prompb/io/prometheus/client/metrics.proto) protobuf DTO decoder. |
| `relabel` | In progress | [specs/SPEC.md](./specs/SPEC.md#target-and-metric-relabeling-architecture) | Prometheus-compatible target and metric relabeling (`replace`, `keep`, `drop`, `hashmod`, `labelmap`, `labeldrop`, `labelkeep`, `lowercase`, `uppercase`, `keepequal`, `dropequal`), Stage 1 `__name__` filter pushdown, and Stage 2 dictionary-vectorized relabeling and `honor_labels` resolution. |
| `discovery` | Planned | TBD | Standard Prometheus service discovery mechanisms (static targets, file-based SD, HTTP SD, DNS SD, Kubernetes SD) emitting target groups and `__meta_*` labels. |
| `scrape` | Planned | TBD | Bounded HTTP scrape scheduling, target pool lifecycle, compression and content negotiation, stale marker handling, target state reporting, and self-telemetry. |

Expand All @@ -51,8 +53,9 @@ Run the Go differential fixture extractor and tests (requires Go):
cd tests/go-harness && go test ./...
```

Run the decoding benchmarks in Go `benchfmt` format for [`benchstat`](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat):
Run the decoding and relabeling benchmarks in Go `benchfmt` format for [`benchstat`](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat):

```sh
cargo bench --bench decode -- -bench '^BenchmarkDecode' -benchtime 1s -count 6 -cpu 2 -benchmem | tee decode.txt
cargo bench --bench relabel -- -bench '^BenchmarkRelabel' -benchtime 1s -count 6 -cpu 2 -benchmem | tee relabel.txt
```
Loading
Loading