Expand description
A mock OpenTelemetry OTLP collector server for testing.
This library provides a mock collector that can receive OTLP logs, traces, and metrics over gRPC, HTTP/JSON, or HTTP/Protobuf, and provides a fluent assertion API for verifying the received telemetry data in tests.
§Features
- Multiple Signal Support: Logs, Traces, and Metrics
- Single Collector: One collector handles all signals - test logs, traces, and metrics together
- Multiple Protocol Support: gRPC, HTTP/Protobuf, and HTTP/JSON
- Fluent Assertion API: Easy-to-use builder pattern for test assertions
- Async Waiting: Wait for telemetry to arrive with timeout support
- Severity Level Assertions: Assert on log severity levels (Debug, Info, Warn, Error, Fatal)
- Count-Based Assertions: Assert exact counts, minimums, or maximums
- Negative Assertions: Verify logs/spans/metrics don’t exist
- Async-Ready: Built with Tokio for async/await compatibility
- Graceful Shutdown: Proper resource cleanup
§Quick Start
use mock_collector::{MockServer, Protocol};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Start a server (supports logs, traces, and metrics)
let server = MockServer::builder().start().await?;
// Your application exports logs, traces, and metrics here...
// Assert on collected data
server.with_collector(|collector| {
// Logs
collector
.expect_log_with_body("Application started")
.with_resource_attributes([("service.name", "my-service")])
.assert_exists();
// Logs with severity
use mock_collector::SeverityNumber;
collector
.expect_log()
.with_severity(SeverityNumber::Error)
.assert_not_exists();
// Traces
collector
.expect_span_with_name("Initialize")
.with_resource_attributes([("service.name", "my-service")])
.assert_exists();
// Metrics
collector
.expect_metric_with_name("requests_total")
.with_resource_attributes([("service.name", "my-service")])
.assert_exists();
}).await;
// Graceful shutdown
server.shutdown().await?;
Ok(())
}§Async Waiting
When testing async telemetry pipelines, signals often arrive asynchronously after the operation that generates them completes. The library provides waiting methods to handle this pattern:
use mock_collector::MockServer;
use std::time::Duration;
let server = MockServer::builder().start().await?;
// Trigger async telemetry export...
// Wait for telemetry to arrive before asserting
server.wait_for_spans(1, Duration::from_secs(5)).await?;
server.wait_for_logs(2, Duration::from_secs(5)).await?;
server.wait_for_metrics(3, Duration::from_secs(5)).await?;
// Or use a custom predicate for complex conditions
server.wait_until(
|c| c.expect_span_with_name("http.request")
.with_attributes([("http.status_code", 200)])
.count() >= 1,
Duration::from_secs(5),
).await?;
// Now safe to run assertions
server.with_collector(|collector| {
collector.expect_span_with_name("http.request").assert_exists();
}).await;§Assertion API
The library provides assertion methods for logs, traces, and metrics:
§Log Assertions
LogAssertion::assert_exists: Assert at least one log matchesLogAssertion::assert_not_exists: Assert no logs matchLogAssertion::assert_count: Assert exact number of matchesLogAssertion::assert_at_least: Assert minimum matchesLogAssertion::assert_at_most: Assert maximum matches
§Trace Assertions
SpanAssertion::assert_exists: Assert at least one span matchesSpanAssertion::assert_not_exists: Assert no spans matchSpanAssertion::assert_count: Assert exact number of matchesSpanAssertion::assert_at_least: Assert minimum matchesSpanAssertion::assert_at_most: Assert maximum matches
§Metric Assertions
MetricAssertion::assert_exists: Assert at least one metric matchesMetricAssertion::assert_not_exists: Assert no metrics matchMetricAssertion::assert_count: Assert exact number of matchesMetricAssertion::assert_at_least: Assert minimum matchesMetricAssertion::assert_at_most: Assert maximum matches
§Histogram, ExponentialHistogram, and Summary Assertions
For type-specific metric assertions, use the dedicated builders:
HistogramAssertion: Assert on histogram count, sum, min, max, and bucket countsExponentialHistogramAssertion: Assert on exponential histogram with zero_count and scaleSummaryAssertion: Assert on summary count, sum, and quantile values
// Histogram with value assertions
collector
.expect_histogram("http_request_duration")
.with_count_gte(100)
.with_sum_gte(5000.0)
.assert_exists();
// Summary with quantile assertions
collector
.expect_summary("response_time")
.with_quantile_lte(0.99, 500.0) // p99 <= 500ms
.assert_exists();§Waiting Methods
ServerHandle::wait_until: Wait for a custom predicate to return trueServerHandle::wait_for_spans: Wait for at least N spans to arriveServerHandle::wait_for_logs: Wait for at least N logs to arriveServerHandle::wait_for_metrics: Wait for at least N metrics to arrive
§Examples
See the examples directory for complete working examples.
Structs§
- Exponential
Histogram Assertion - A builder for constructing exponential histogram metric assertions.
- Histogram
Assertion - A builder for constructing histogram metric assertions.
- LogAssertion
- A builder for constructing log assertions.
- Metric
Assertion - A builder for constructing metric assertions.
- Mock
Collector - A mock collector that stores received OTLP logs, traces, and metrics for test assertions.
- Mock
Server - A mock OTLP server for testing.
- Mock
Server Builder - A builder for configuring a mock OTLP server.
- Server
Handle - A handle to a running mock server.
- Span
Assertion - A builder for constructing span assertions.
- Summary
Assertion - A builder for constructing summary metric assertions.
- Test
LogRecord - A flattened log record with resource and scope attributes copied for easy test assertions.
- Test
Metric - A flattened metric with resource and scope attributes copied for easy test assertions.
- Test
Span - A flattened span with resource and scope attributes copied for easy test assertions.
Enums§
- Mock
Server Error - Protocol
- The communication protocol to use when exporting data.
- Severity
Number - Possible values for LogRecord.SeverityNumber.