Skip to main content

Prometheus range-query JSON -> metric-type aware summaries

Project description

Prometheus Metric Summarizer

Apache-2.0 licensed Python library that converts Prometheus range query JSON (GET /api/v1/query_range) into compact, metric-type–aware summaries for agentic pipelines and AI-Ops.

Scope: Only range (matrix) responses are supported. Instant/vector queries are out of scope.

Quickstart

# Using the convenience script (venv at ../venv)
./run_venv.sh

# Or manually
python -m venv ../venv && source ../venv/bin/activate
pip install -r requirements.txt
python -m promsum.cli --metric-type gauge --input examples/sample_gauge.json

Development

Installing for Development

# Activate your virtual environment
source ../venv/bin/activate  # or ./run_venv.sh

# Install in editable mode
pip install -e .

# Now you can use the command directly
promsum --metric-type gauge --input examples/sample_gauge.json

Building the Package

# Install build tools
pip install build twine

# Build source distribution and wheel
python -m build

# Output will be in dist/
# - prometheus_metric_summarizer-0.1.0-py3-none-any.whl
# - prometheus_metric_summarizer-0.1.0.tar.gz
# and it will be in your venv 
which promsum     # shows you the location

Testing

# Test with example files (basic output)
promsum --metric-type counter --input examples/sample_counter.json
promsum --metric-type gauge --input examples/sample_gauge.json
promsum --metric-type histogram --input examples/sample_histogram.json
promsum --metric-type summary --input examples/sample_summary.json

# Include scrape interval analysis (data quality metrics)
promsum --metric-type gauge --input examples/sample_gauge.json --include-scrape-analysis

# Or using the module directly
python -m promsum.cli --metric-type gauge --input examples/sample_gauge.json

Installing from Built Package

# Install the wheel
pip install dist/prometheus_metric_summarizer-0.1.0-py3-none-any.whl

# Or install the source distribution
pip install dist/prometheus-metric-summarizer-0.1.0.tar.gz

Using as a Python Library

Basic Usage

from promsum.cli import summarize
import json

# Load your Prometheus range query result
with open("examples/sample_gauge.json") as f:
    data = f.read()

# Get the summary as a JSON string
result = summarize("gauge", data)
print(result)

# Or parse it as a dictionary
summary_dict = json.loads(result)
print(f"Metric type: {summary_dict[0]['metric_type']}")
print(f"Mean value: {summary_dict[0]['stats']['mean']}")

With Scrape Analysis

from promsum.cli import summarize
import json

with open("examples/sample_gauge.json") as f:
    data = f.read()

# Include scrape analysis for data quality insights
result = summarize("gauge", data, include_scrape_analysis=True)
summary = json.loads(result)

# Access scrape analysis data
scrape_info = summary[0].get('scrape_analysis', {})
print(f"Expected scrape interval: {scrape_info.get('expected_interval_seconds')}s")
print(f"Missed scrapes: {scrape_info.get('missed_scrapes')}")
print(f"Regularity: {scrape_info.get('scrape_regularity')}")

Using Individual Summarizers

from promsum.counter import summarize_counter
from promsum.gauge import summarize_gauge
from promsum.histogram import summarize_histogram
from promsum.summary import summarize_summary
import json

# Load Prometheus data
with open("examples/sample_histogram.json") as f:
    prom_data = json.load(f)

# Call summarizer directly
result = summarize_histogram(prom_data, include_scrape_analysis=True)

# Process results
for metric in result:
    stats = metric['stats']
    print(f"Labels: {metric['labels']}")
    print(f"Observations: {stats['count']}")
    print(f"Average: {stats['avg']}")
    print(f"P95: {stats['p95']}")
    
    # Check data quality
    if 'scrape_analysis' in metric:
        sa = metric['scrape_analysis']
        if sa['missed_scrapes'] > 0:
            print(f"⚠️  Warning: {sa['missed_scrapes']} scrapes were missed")
        if sa['scrape_regularity'] == 'irregular':
            print("⚠️  Warning: Irregular scrape intervals detected")

Processing Multiple Metrics

import json
from promsum.gauge import summarize_gauge

# Process multiple gauge metrics
metric_files = [
    "examples/sample_gauge.json",
    # Add more files...
]

all_results = []
for file_path in metric_files:
    with open(file_path) as f:
        data = json.load(f)
    
    summaries = summarize_gauge(data, include_scrape_analysis=True)
    all_results.extend(summaries)

# Filter for metrics with data quality issues
problematic_metrics = [
    m for m in all_results 
    if m.get('scrape_analysis', {}).get('missed_scrapes', 0) > 5
]

print(f"Found {len(problematic_metrics)} metrics with >5 missed scrapes")

Integration with Analysis Tools

import json
import pandas as pd
from promsum.gauge import summarize_gauge

# Load and summarize
with open("examples/sample_gauge.json") as f:
    data = json.load(f)

summaries = summarize_gauge(data, include_scrape_analysis=True)

# Convert to DataFrame for analysis
df = pd.json_normalize(summaries)

# Analyze data quality
print("Data Quality Summary:")
print(df[['labels', 'scrape_analysis.scrape_regularity', 
         'scrape_analysis.missed_scrapes']].to_string())

# Statistical analysis
print(f"\nMean value across all series: {df['stats.mean'].mean()}")
print(f"Max value observed: {df['stats.max'].max()}")

Input format (exact Prometheus range-query shape)

{
  "status": "success",
  "data": {
    "resultType": "matrix",
    "result": [ { "metric": {...}, "values": [[ts, "val"], ...] } ]
  }
}

Output (per unique label set)

All metric types include time anchors:

  • start_timestamp, end_timestamp, duration_seconds
  • For counter and gauge: start_value, end_value, count (number of data points)
  • For histogram and summary: num_data_points (number of scrape samples)

Gauge Example

[{
  "labels": {"namespace": "payments", "pod": "worker-1"},
  "metric_type": "gauge",
  "stats": {
    "count": 9,
    "start_timestamp": 1731003000,
    "end_timestamp": 1731003120,
    "duration_seconds": 120,
    "start_value": 0.42,
    "end_value": 0.55,
    "min": 0.42, "max": 0.55, "mean": 0.48, "median": 0.47, "stddev": 0.06,
    "trend": "rising", "change_over_window": 0.13
  }
}]

Reductions

  • Counter: count (data points), start/end timestamps & values, delta, rate_per_second, rate_per_minute, total=end_value.
  • Gauge: count (data points), start/end timestamps & values, min, max, mean, median, stddev, trend, change_over_window.
  • Histogram: num_data_points (scrape samples), start/end timestamps, duration, window deltas from buckets, count (observations), sum, avg, quantiles (p50, p90, p95, p99) via bucket reconstruction, dominant_bucket.
  • Summary: num_data_points (scrape samples), start/end timestamps, duration, deltas for _sum/_count, count (observations), avg=sum/count, and quantiles grouped under stats.quantiles.

Scrape Analysis (Optional)

Add --include-scrape-analysis to include data quality metrics:

promsum --metric-type gauge --input examples/sample_gauge.json --include-scrape-analysis

This adds a scrape_analysis object to each metric with:

{
  "scrape_analysis": {
    "expected_interval_seconds": 15.0,
    "missed_scrapes": 2,
    "scrape_regularity": "mostly_regular",
    "scrape_regularity_cv": 0.15,
    "counter_resets_detected": 0,
    "total_gaps": 9,
    "irregular_gaps": 1
  }
}

Scrape Analysis Fields

  • expected_interval_seconds: Median time between scrapes (robust against outliers)
  • missed_scrapes: Estimated number of missing data points based on gaps > 1.5x expected interval
  • scrape_regularity: Classification of scrape consistency
    • "regular": CV < 0.1 (very consistent scraping)
    • "mostly_regular": CV 0.1-0.3 (some variation)
    • "irregular": CV > 0.3 (high variation in scrape intervals)
    • "single_interval": Only 2 data points
    • "insufficient_data": Only 1 data point
  • scrape_regularity_cv: Coefficient of variation (stddev/mean) of intervals - technical metric for regularity
  • counter_resets_detected: (Counter metrics only) Number of times the counter value decreased (resets)
  • total_gaps: Total number of intervals between data points
  • irregular_gaps: Number of gaps exceeding 1.5x the expected interval

Use Cases for Scrape Analysis

  • Data Quality Assessment: Identify metrics with unreliable scraping
  • Troubleshooting: Detect scrape targets that went down (large gaps)
  • Counter Reset Detection: Find when counters were reset (app restarts, etc.)
  • SLO Validation: Ensure monitoring meets collection frequency requirements

LLM Prompt Examples

Counter Metrics

Analyze this Prometheus counter metric summary:
{counter_output}

Fields explained:
- count: Number of data points scraped (e.g., 9 means Prometheus scraped this metric 9 times)
- start_timestamp/end_timestamp: Unix timestamps marking the query window
- duration_seconds: Total time span of the data
- start_value/end_value: Counter values at beginning and end (counters only increase)
- total: Final counter value (same as end_value)
- delta: How much the counter increased during the window (end_value - start_value)
- rate_per_second: Average rate of increase per second (delta / duration)
- rate_per_minute: Average rate of increase per minute (rate_per_second * 60)

Example interpretation: "The http_requests_total counter increased by {delta} requests over {duration_seconds} seconds, averaging {rate_per_second} requests/second or {rate_per_minute} requests/minute."

Gauge Metrics

Analyze this Prometheus gauge metric summary:
{gauge_output}

Fields explained:
- count: Number of data points scraped
- start_timestamp/end_timestamp: Unix timestamps marking the query window
- duration_seconds: Total time span of the data
- start_value/end_value: Gauge values at beginning and end (gauges can go up or down)
- min/max: Lowest and highest values observed during the window
- mean: Average value across all data points
- median: Middle value when sorted (50th percentile)
- stddev: Standard deviation showing how much values vary
- trend: Classification of the gauge behavior (e.g., "rising", "falling", "stable", "fluctuating")
- change_over_window: Net change from start to end (end_value - start_value)

Example interpretation: "The memory_usage_bytes gauge ranged from {min} to {max} with an average of {mean}. It showed a {trend} pattern with a net {change_over_window} change."

Histogram Metrics

Analyze this Prometheus histogram metric summary:
{histogram_output}

Fields explained:
- num_data_points: Number of times Prometheus scraped this metric
- start_timestamp/end_timestamp: Unix timestamps marking the query window
- duration_seconds: Total time span of the data
- count: Total number of observations (e.g., HTTP requests) recorded during the window
- sum: Sum of all observed values (e.g., total response time in seconds)
- avg: Average value per observation (sum / count)
- p50/p90/p95/p99: Percentiles showing distribution (e.g., p95=0.5 means 95% of requests took ≤0.5s)
- dominant_bucket: Bucket with the most observations (shows the most common value range)

Example interpretation: "Over {duration_seconds} seconds, {count} HTTP requests were observed with an average response time of {avg}s. 95% of requests completed in {p95}s or less, with most requests falling in the {dominant_bucket} bucket."

Summary Metrics

Analyze this Prometheus summary metric summary:
{summary_output}

Fields explained:
- num_data_points: Number of times Prometheus scraped this metric
- start_timestamp/end_timestamp: Unix timestamps marking the query window
- duration_seconds: Total time span of the data
- count: Total number of observations recorded during the window
- sum: Sum of all observed values
- avg: Average value per observation (sum / count)
- quantiles: Pre-calculated percentiles from the application (e.g., {"0.5": 0.23, "0.9": 0.45, "0.99": 0.78})
  - Keys are quantile levels (0.5 = median, 0.9 = 90th percentile, etc.)
  - Values show that X% of observations were at or below this value

Example interpretation: "During {duration_seconds} seconds, {count} observations were recorded with an average of {avg}. The median (50th percentile) was {quantiles['0.5']}, and 99% of values were at or below {quantiles['0.99']}."

Understanding count vs num_data_points

Key distinction for LLM analysis:

Counter/Gauge metrics:
- "count": How many times Prometheus scraped this metric (sampling frequency)
- Example: count=9 over 120 seconds means Prometheus scraped every ~13 seconds

Histogram/Summary metrics:
- "num_data_points": How many times Prometheus scraped the metric (sampling frequency)
- "count": How many observations/events were recorded (business metric)
- Example: num_data_points=9 (scraped 9 times), count=50000 (50k HTTP requests handled)

When analyzing: num_data_points/count tells you about the data collection frequency, while the "count" field in histograms/summaries tells you about actual system activity.

Scrape Analysis Fields (Optional)

When --include-scrape-analysis is used, each metric includes a scrape_analysis object:

{
  "expected_interval_seconds": 15.0,     // Median time between scrapes
  "missed_scrapes": 2,                   // Estimated missing data points
  "scrape_regularity": "mostly_regular", // regular | mostly_regular | irregular
  "scrape_regularity_cv": 0.15,          // Coefficient of variation (technical)
  "counter_resets_detected": 0,          // Counter metrics only: # of resets
  "total_gaps": 9,                       // Total intervals analyzed
  "irregular_gaps": 1                    // Gaps > 1.5x expected interval
}

Interpretation guidance:
- missed_scrapes > 0: Data collection had gaps (target down, network issues, etc.)
- scrape_regularity "irregular": Unreliable scraping, use data cautiously
- counter_resets_detected > 0: Application restarted or counter reset
- irregular_gaps / total_gaps > 0.2: More than 20% of intervals were irregular

Example: "The metric was scraped every ~15 seconds with mostly_regular consistency. 
However, 2 scrapes were missed, suggesting brief collection interruptions."

License

Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

prometheus_metric_summarizer-0.1.0.tar.gz (14.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

prometheus_metric_summarizer-0.1.0-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file prometheus_metric_summarizer-0.1.0.tar.gz.

File metadata

File hashes

Hashes for prometheus_metric_summarizer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d6e8ac2339789d98408ec70038cddd22c38d0f2e53ad2ac861b839307f4b237
MD5 edf3962a3b898319da3db61564e99331
BLAKE2b-256 08d8f618a40c05fdc26f6b0e4263851952a67ec5997b6e984ddab0fc9c9e6ff2

See more details on using hashes here.

File details

Details for the file prometheus_metric_summarizer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for prometheus_metric_summarizer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a1af98d2b168aff9536eec83d6f107bb37769d7a8f8c8e30ff1d2cb092c73fd
MD5 e81d6742f62ee48e5ffd48416c2a33ab
BLAKE2b-256 b3bdaed9a38dc213307a3766bd7b796090cf450381b15a5cf88cdd738ee8efbd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page