Skip to main content

Production-ready metrics instrumentation for RL-based autoscaling systems

Project description

rl-autoscale

๐ŸŽฏ Production-ready metrics instrumentation for RL-based autoscaling systems

A lightweight Python library that provides standardized Prometheus metrics for applications managed by reinforcement learning autoscalers. Works with Flask, FastAPI, and other Python web frameworks.

PyPI version Python 3.10+ License: MIT

Features

โœ… One-Line Integration - Add 2 lines of code, get full observability โœ… Framework Agnostic - Flask, FastAPI, Django support โœ… Zero Overhead - Minimal performance impact (<1ms per request) โœ… Production Ready - Battle-tested with proper error handling โœ… RL Optimized - Metrics designed specifically for RL autoscaling agents โœ… Standardized - Consistent metrics across all your microservices

Quick Start

Flask Application

from flask import Flask
from rl_autoscale import enable_metrics

app = Flask(__name__)

# ๐ŸŽฏ ONE LINE - that's it!
enable_metrics(app, port=8000)

@app.route("/api/hello")
def hello():
    return "Hello World"

if __name__ == "__main__":
    app.run()

FastAPI Application

from fastapi import FastAPI
from rl_autoscale import enable_metrics

app = FastAPI()

# ๐ŸŽฏ ONE LINE - that's it!
enable_metrics(app, port=8000)

@app.get("/api/hello")
async def hello():
    return {"message": "Hello World"}

Installation

# Using pip
pip install rl-autoscale[flask]      # For Flask apps
pip install rl-autoscale[fastapi]    # For FastAPI apps

# Using uv (recommended - 10x faster!)
uv pip install rl-autoscale[flask]
uv pip install rl-autoscale[fastapi]

# Core only
pip install rl-autoscale

๐Ÿ’ก Tip: This project uses uv for blazingly fast package management. See UV_GUIDE.md for details.

What Metrics Are Exposed?

The library exports these standard Prometheus metrics:

1. http_request_duration_seconds (Histogram)

Request latency distribution used by RL agents to calculate percentiles (p50, p90, p99).

Labels:

  • method: HTTP method (GET, POST, etc.)
  • path: Request path (e.g., /api/users)

Buckets: Optimized for web APIs (5ms to 10s)

2. http_requests_total (Counter)

Total request count used for throughput analysis.

Labels:

  • method: HTTP method
  • path: Request path
  • http_status: HTTP status code (200, 404, etc.)

Advanced Usage

Path Normalization

Prevent cardinality explosion by normalizing dynamic paths:

from rl_autoscale import enable_metrics
from rl_autoscale.flask_middleware import normalize_api_paths

app = Flask(__name__)

enable_metrics(
    app,
    port=8000,
    path_normalizer=normalize_api_paths  # /user/123 -> /user/:id
)

Custom Configuration

enable_metrics(
    app,
    port=8000,
    namespace="myapp",  # Prefix metrics: myapp_http_request_duration_seconds
    histogram_buckets=[0.001, 0.01, 0.1, 1.0, 10.0],  # Custom buckets
    exclude_paths=["/health", "/metrics", "/internal/*"],  # Skip these paths
)

Manual Instrumentation

For non-web workloads or custom metrics:

from rl_autoscale import get_metrics_registry

metrics = get_metrics_registry()

# Record a custom operation
with timer():
    result = expensive_operation()
    duration = timer.elapsed()

metrics.observe_request(
    method="BATCH",
    path="/jobs/process",
    duration=duration,
    status_code=200
)

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Your App      โ”‚ โ† Clean business logic (no metrics code!)
โ”‚   (Flask/       โ”‚
โ”‚    FastAPI)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  RL Metrics     โ”‚ โ† This library (automatic instrumentation)
โ”‚  Middleware     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚ HTTP :8000/metrics
         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Prometheus     โ”‚ โ† Scrapes metrics every 15-60s
โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚ PromQL queries
         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   RL Agent      โ”‚ โ† Makes autoscaling decisions
โ”‚ (DQN/Q-Learning)โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why This Library?

Before (Without Library) โŒ

from prometheus_client import Counter, Histogram, start_http_server

# 50+ lines of boilerplate in EVERY service
REQUEST_LATENCY = Histogram(...)
REQUEST_COUNT = Counter(...)

@app.before_request
def before_request():
    request.start_time = time.time()

@app.after_request
def after_request(response):
    latency = time.time() - request.start_time
    REQUEST_LATENCY.labels(...).observe(latency)
    REQUEST_COUNT.labels(...).inc()
    return response

start_http_server(8000)
# ... more boilerplate

After (With Library) โœ…

from rl_autoscale import enable_metrics

enable_metrics(app, port=8000)  # Done! ๐ŸŽ‰

Benefits:

  • โœ… 60+ lines โ†’ 1 line - Massive code reduction
  • โœ… Standardized - Same metrics across all services
  • โœ… Maintainable - Update once, affects all services
  • โœ… Tested - Production-ready error handling
  • โœ… Reusable - Use in Flask, FastAPI, Django

Configuration via Environment Variables

# Metrics port
export RL_METRICS_PORT=8000

# Custom namespace
export RL_METRICS_NAMESPACE=myapp

# Excluded paths (comma-separated)
export RL_METRICS_EXCLUDE_PATHS=/health,/metrics,/internal/*

Kubernetes Deployment

Add Prometheus scrape annotations to your deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8000"
        prometheus.io/path: "/metrics"
    spec:
      containers:
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 5000  # App port
        - containerPort: 8000  # Metrics port

Prometheus Queries

Example queries for your RL agent:

# P90 response time over last 5 minutes
histogram_quantile(0.90,
  rate(http_request_duration_seconds_bucket[5m])
)

# Requests per second
rate(http_requests_total[1m])

# Error rate (HTTP 5xx)
rate(http_requests_total{http_status=~"5.."}[5m])

Performance

  • Overhead: <1ms per request
  • Memory: ~10MB baseline
  • CPU: Negligible (<0.1% on most workloads)

Tested with 10,000 requests/second with zero performance degradation.

Troubleshooting

Port Already in Use

# If port 8000 is taken, use another port
enable_metrics(app, port=8001)

Metrics Not Showing Up

  1. Check metrics endpoint: curl http://localhost:8000/metrics
  2. Verify Prometheus can reach your app
  3. Check Prometheus scrape config
  4. Look for errors in application logs

High Cardinality Warning

If you see thousands of unique metric labels:

# Add path normalization
from rl_autoscale.flask_middleware import normalize_api_paths

enable_metrics(app, path_normalizer=normalize_api_paths)

Contributing

See CONTRIBUTING.md for development setup and guidelines.

# Clone repository
git clone https://github.com/ghazafm/rl-autoscale
cd rl-autoscale

# Setup with uv (recommended - one command!)
uv sync --all-extras

# Or traditional way with pip
pip install -e ".[dev,flask,fastapi]"

# Run tests
pytest

# Format and lint code (using ruff for both!)
ruff format .
ruff check .

๐Ÿ“– Quick Start: See QUICK_START.md for fastest setup! ๐Ÿ“– Developer Guide: See UV_GUIDE.md for using uv and ruff effectively.

License

MIT License - See LICENSE file

Support


Made with โค๏ธ for RL Autoscaling Systems

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

rl_autoscale-1.0.4.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

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

rl_autoscale-1.0.4-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file rl_autoscale-1.0.4.tar.gz.

File metadata

  • Download URL: rl_autoscale-1.0.4.tar.gz
  • Upload date:
  • Size: 15.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rl_autoscale-1.0.4.tar.gz
Algorithm Hash digest
SHA256 ca06b9c17834a6014639669ff62c9fd579834b4e86058b4801e1013937a59cfd
MD5 b39d9a20056edc8580985a9e4002a34e
BLAKE2b-256 0dc8da5a07792290e8836485d8a008cf20538a9a864a5d92b9683aaf013fd2f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rl_autoscale-1.0.4.tar.gz:

Publisher: publish.yml on ghazafm/rl-autoscale

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rl_autoscale-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: rl_autoscale-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rl_autoscale-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ddad1b5beaa7cde1e2c262d88e671d18ceeeb0746fe47d23f4858bd24fd10320
MD5 d4e2f597bb284f7b2caa5018c0f9edbb
BLAKE2b-256 e067118d1b7bca53aa26cbaeca0e343b79b1bde97f039f05420367b2564f68db

See more details on using hashes here.

Provenance

The following attestation bundles were made for rl_autoscale-1.0.4-py3-none-any.whl:

Publisher: publish.yml on ghazafm/rl-autoscale

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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