Generate Synthetic CPU Utilization Metrics in Python

Creates realistic time-series CPU utilization samples with timestamps, noise, and output as structured JSON for observability demos and testing.

Easy Python 3.9+ Aug 9, 2026 Observability & SRE 14 views 0 copies

Python code

37 lines
Python 3.9+
from datetime import datetime, timedelta
import random
import json


def generate_metric_samples(base_value, noise, count=60, interval_minutes=1):
    """Generate realistic CPU utilization samples for a given time window."""
    timestamps = []
    values = []

    now = datetime.utcnow()
    start_time = now - timedelta(minutes=(count - 1) * interval_minutes)

    for i in range(count):
        timestamp = start_time + timedelta(minutes=i * interval_minutes)
        value = base_value + random.uniform(-noise, noise)
        timestamps.append(timestamp.isoformat())
        values.append(round(max(0, min(100, value)), 2))

    return timestamps, values


if __name__ == "__main__":
    # Help beginners understand the shape of time-series data
    ts, vals = generate_metric_samples(base_value=65.0, noise=10.0, count=5, interval_minutes=1)

    dataset = {
        "metric": "cpu_utilization",
        "unit": "percent",
        "host": "web-server-01",
        "samples": [
            {"timestamp": ts[i], "value": vals[i]}
            for i in range(len(ts))
        ],
    }

    print(json.dumps(dataset, indent=2))

Output

stdout
{
  "metric": "cpu_utilization",
  "unit": "percent",
  "host": "web-server-01",
  "samples": [
    {
      "timestamp": "2025-03-23T12:34:56.789012",
      "value": 68.42
    },
    {
      "timestamp": "2025-03-23T12:35:56.789012",
      "value": 63.51
    },
    {
      "timestamp": "2025-03-23T12:36:56.789012",
      "value": 70.89
    },
    {
      "timestamp": "2025-03-23T12:37:56.789012",
      "value": 59.37
    },
    {
      "timestamp": "2025-03-23T12:38:56.789012",
      "value": 66.73
    }
  ]
}

How it works

The function generate_metric_samples computes a start time by subtracting count - 1 intervals from the current UTC time, then iterates to create timestamps at fixed intervals. Each value is the base plus a uniform random noise between -noise and +noise, then clipped to 0–100 and rounded to two decimals. The __main__ block builds a dictionary with metadata (metric name, unit, host) and a list of sample dicts, then serializes to JSON with json.dumps(indent=2) for readability. This mimics the structure of many monitoring APIs and time-series databases like Prometheus or InfluxDB.

Common mistakes

  • Using `datetime.now()` instead of `datetime.utcnow()` leading to timezone confusion in logs
  • Not clipping values to a realistic range (0–100 for CPU), producing nonsensical metrics
  • Forgetting to round values, resulting in noisy floating-point artifacts
  • Hardcoding count or interval instead of making them parameters

Variations

  1. Use `datetime.now(timezone.utc)` for timezone-aware timestamps instead of naive UTC
  2. Generate samples with a seasonal pattern using a sine wave plus noise

Real-world use cases

  • Creating synthetic CPU metrics to test dashboards in Grafana or Datadog during development.
  • Feeding realistic time-series data into alerting systems to validate threshold rules.
  • Supporting load tests by generating expected metric patterns for capacity planning.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Observability & SRE

Related tutorials and quizzes for this topic.