OpenPay (1 crate, ~2940 LOC, 40 tests)
op-statements Statement generation + reconciliation + fee accounting.
Render targets: PDF (template), CSV, JSON, 94-char
NACHA fixed-width. ISO 20022 camt.053 with full
BkToCstmrStmt envelope (GrpHdr/Stmt/Bal/Ntry). BAI2
with 01/02/03/16/49/98/99 records. MT940/MT942
SWIFT with :20:/:25:/:28C:/:60F:/:61:/:86:/:62F:
+ :90C:/:90D: counters. FeeBucket (interchange/scheme/
acquirer/fx/settlement-network/bnpl) + FeeSchedule
with bps + flat rules. Cadence (daily/weekly/monthly/
custom). Two-tier Reconciler (external_id → window
heuristic).
Smart Byte (1 crate, 3032 LOC, 39 tests)
smart-byte-activitypub ActivityPub W3C Rec (2018). AS2 vocab + Public
addressing; Actor (Person/Application/Group/
Organization/Service) with publicKey + shared-inbox;
Object (Note/Article/Image/Video/Tombstone) with
Mastodon extensions (sensitive, CW summary,
conversation, blurhash); 12 Activity types
(Create/Update/Delete/Follow/Accept/Reject/Announce/
Like/Undo/Move/Block/Flag) with side-effect rules;
OrderedCollection + Page; Webfinger (RFC 7033);
HTTP Signatures (cavage draft-12 + RFC 9421);
SHA-256 Digest; Ed25519 sign/verify.
EOC (1 crate, 2759 LOC, 20 tests)
eoc-observability OpenTelemetry-compatible tracing + metrics + logs.
W3C tracecontext + baggage. Span / SpanKind / Status.
Samplers: AlwaysOn/Off/RatioBased/ParentBased. Sync
BatchSpanProcessor + Exporter trait. Counter / Gauge /
Histogram. Prometheus text exposition (HELP/TYPE/
_bucket/_sum/_count/+Inf). StatsD / DogStatsD lines.
GenAI semconv (gen_ai.{operation,system,request.*,
response.*,usage.*}) + EOC extensions (eoc.joules.*,
eoc.co2e_grams, eoc.cost.usd). USD + gCO2e attribution
with PUE. LangSmith + LangFuse export adapters.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
57 lines
1.9 KiB
Rust
57 lines
1.9 KiB
Rust
//! Prometheus text exposition format.
|
|
|
|
use eoc_observability::{Counter, Gauge, Histogram, PrometheusExposer};
|
|
|
|
#[test]
|
|
fn counter_emits_help_type_and_value() {
|
|
let c = Counter::new("eoc_cache_hits_total", "1")
|
|
.with_description("Total cache hits")
|
|
.with_attribute("stage", "cache");
|
|
c.add(7);
|
|
|
|
let mut e = PrometheusExposer::new();
|
|
e.add_counter(&c);
|
|
let out = e.finish();
|
|
|
|
assert!(out.contains("# HELP eoc_cache_hits_total Total cache hits"));
|
|
assert!(out.contains("# TYPE eoc_cache_hits_total counter"));
|
|
assert!(out.contains("eoc_cache_hits_total{stage=\"cache\"} 7"));
|
|
}
|
|
|
|
#[test]
|
|
fn gauge_renders_no_attrs() {
|
|
let g = Gauge::new("eoc_active_connections", "1");
|
|
g.set(3.5);
|
|
let mut e = PrometheusExposer::new();
|
|
e.add_gauge(&g);
|
|
let out = e.finish();
|
|
assert!(out.contains("# TYPE eoc_active_connections gauge"));
|
|
assert!(out.contains("eoc_active_connections 3.5"));
|
|
}
|
|
|
|
#[test]
|
|
fn histogram_emits_cumulative_buckets() {
|
|
let h = Histogram::new(
|
|
"eoc_latency_ms",
|
|
"ms",
|
|
vec![10.0, 50.0, 100.0, 500.0],
|
|
);
|
|
h.record(5.0); // bucket 0 (<=10)
|
|
h.record(40.0); // bucket 1 (<=50)
|
|
h.record(75.0); // bucket 2 (<=100)
|
|
h.record(200.0); // bucket 3 (<=500)
|
|
h.record(2000.0); // bucket 4 (+Inf)
|
|
|
|
let mut e = PrometheusExposer::new();
|
|
e.add_histogram(&h);
|
|
let out = e.finish();
|
|
|
|
assert!(out.contains("# TYPE eoc_latency_ms histogram"));
|
|
assert!(out.contains("eoc_latency_ms_bucket{le=\"10\"} 1"));
|
|
assert!(out.contains("eoc_latency_ms_bucket{le=\"50\"} 2"));
|
|
assert!(out.contains("eoc_latency_ms_bucket{le=\"100\"} 3"));
|
|
assert!(out.contains("eoc_latency_ms_bucket{le=\"500\"} 4"));
|
|
assert!(out.contains("eoc_latency_ms_bucket{le=\"+Inf\"} 5"));
|
|
assert!(out.contains("eoc_latency_ms_count 5"));
|
|
assert!(out.contains("eoc_latency_ms_sum 2320"));
|
|
}
|