Export Metrics with OTLP Mock in Python
Simulates system metric collection and exports them as an OTLP-like JSON payload using only Python's standard library.
Python code
53 linesfrom dataclasses import dataclass, asdict
import json
import random
import time
@dataclass
class Metric:
name: str
value: float
timestamp: int
unit: str = "1"
def collect_system_metrics() -> list[Metric]:
"""Mock metric collection for OTLP export simulation."""
now = int(time.time())
return [
Metric("system.cpu.usage", round(random.uniform(0.0, 1.0), 3), now, "percent"),
Metric("system.memory.usage", round(random.uniform(0.5, 0.9), 3), now, "percent"),
Metric("system.disk.io", round(random.uniform(0, 100), 2), now, "bytes"),
]
def export_otlp_metrics(metrics: list[Metric]) -> str:
"""Transform metrics to OTLP-like JSON payload and print it."""
resource = {"attributes": {"service.name": "mock-otlp-exporter"}}
scope_metrics = [
{
"name": m.name,
"unit": m.unit,
"gauge": {
"dataPoints": [
{
"asDouble": m.value,
"timeUnixNano": m.timestamp * 1_000_000_000,
}
]
},
}
for m in metrics
]
payload = {
"resource": resource,
"scopeMetrics": [{"scope": {"name": "single-test"}, "metrics": scope_metrics}],
}
return json.dumps(payload, indent=2)
if __name__ == "__main__":
sample = collect_system_metrics()
output = export_otlp_metrics(sample)
print(output)
Output
{
"resource": {
"attributes": {
"service.name": "mock-otlp-exporter"
}
},
"scopeMetrics": [
{
"scope": {
"name": "single-test"
},
"metrics": [
{
"name": "system.cpu.usage",
"unit": "percent",
"gauge": {
"dataPoints": [
{
"asDouble": 0.523,
"timeUnixNano": 1699999999000000000
}
]
}
},
{
"name": "system.memory.usage",
"unit": "percent",
"gauge": {
"dataPoints": [
{
"asDouble": 0.712,
"timeUnixNano": 1699999999000000000
}
]
}
},
{
"name": "system.disk.io",
"unit": "bytes",
"gauge": {
"dataPoints": [
{
"asDouble": 42.5,
"timeUnixNano": 1699999999000000000
}
]
}
}
]
}
]
}
How it works
This code uses a dataclass Metric to hold each metric's name, value, timestamp, and unit. The collect_system_metrics function generates random values and a current epoch timestamp to mimic real telemetry. export_otlp_metrics structures these metrics into an OTLP-compatible JSON shape with a resource and scope section, converting timestamps to nanoseconds as the OTLP protocol expects. The output is printed with indentation for readability, making it easy to inspect or forward to a collector like Grafana or Prometheus.
Common mistakes
- Forgetting to convert timestamps from seconds to nanoseconds using `* 1_000_000_000`.
- Using `time.time()` directly instead of an integer cast, causing floating-point precision issues.
- Omitting the `unit` field or setting it to an empty string when the metric type requires it.
- Structuring the JSON incorrectly, missing the nested `scopeMetrics` or `dataPoints` keys.
Variations
- Use the `opentelemetry-exporter-otlp-proto-http` package to send real OTLP requests instead of mocking.
- Use a dictionary comprehension to build the scope metrics list inline instead of a manual loop.
Real-world use cases
- Testing an OTLP exporter locally without a live telemetry backend by generating sample data.
- Validating the JSON payload structure before integrating with an OpenTelemetry Collector.
- Simulating system metrics in a CI pipeline to verify dashboard or alarm configuration.
Sponsored
More from Observability & SRE
- Adding a Correlation ID to Log Context in Python medium
- Calculate Error Rate from Log Stream in Python easy
- Check if a Timestamp Falls in a Daily Maintenance Window in Python easy
- Generate Mock CPU and Memory Metrics in Python easy
- Generate Prometheus Text Exposition Format in Python easy
- Generate Synthetic CPU Utilization Metrics in Python easy
Keep learning
Related tutorials and quizzes for this topic.