### Run Example Application Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html This snippet shows how to run an example asyncio application that serves Prometheus metrics. Ensure you have the 'aiohttp' extra installed for this functionality. ```python loop = asyncio.get_event_loop() app = ExampleApp() loop.run_until_complete(app.start()) try: loop.run_forever() except KeyboardInterrupt: pass finally: loop.run_until_complete(app.stop()) loop.close() ``` -------------------------------- ### Running the aioprometheus Service Example Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Execute the Python script to start the aioprometheus Service and expose metrics. ```bash (venv) $ python simple-service-example.py Serving prometheus metrics on: http://127.0.0.1:8000/metrics ``` -------------------------------- ### Install development dependencies Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Install requirements and the package in editable mode. ```bash (aioprom) $ pip install -r requirements.dev.txt (aioprom) $ pip install -e .[aiohttp,binary] ``` -------------------------------- ### Installing aioprometheus with aiohttp Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Install the aioprometheus library with the necessary extras for aiohttp support. ```bash $ pip install aioprometheus[aiohttp] ``` -------------------------------- ### Install aioprometheus via pip Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Standard installation command for the aioprometheus library. ```bash $ pip install aioprometheus ``` -------------------------------- ### Setup virtual environment Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Create and activate a virtual environment to isolate project dependencies. ```bash $ python3 -m venv venv --prompt aioprom $ source venv/bin/activate (aioprom) $ (aioprom) $ pip install pip --upgrade ``` -------------------------------- ### Install aioprometheus with optional extras Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Commands to install aioprometheus with specific framework or protocol support. ```bash $ pip install aioprometheus[starlette] ``` ```bash $ pip install aioprometheus[quart] ``` ```bash $ pip install aioprometheus[aiohttp] ``` ```bash $ pip install aioprometheus[binary] ``` ```bash $ pip install aioprometheus[aiohttp,binary,starlette,quart] ``` -------------------------------- ### Basic aioprometheus Service Example Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Demonstrates embedding the aioprometheus Service to expose metrics on an HTTP endpoint. Requires aiohttp extras. The service starts, a counter metric is defined and updated periodically, and the metrics URL is printed. ```python #!/usr/bin/env python """ This example demonstrates how the ``aioprometheus.Service`` can be used to expose metrics on a HTTP endpoint. .. code-block:: console (env) $ python simple-service-example.py Serving prometheus metrics on: http://127.0.0.1:8000/metrics You can open the URL in a browser or use the ``curl`` command line tool to fetch metrics manually to verify they can be retrieved by Prometheus server. """ import asyncio import socket from aioprometheus import Counter from aioprometheus.service import Service async def main(): service = Service() events_counter = Counter( "events", "Number of events.", const_labels={"host": socket.gethostname()} ) await service.start(addr="127.0.0.1", port=8000) print(f"Serving prometheus metrics on: {service.metrics_url}") # Now start another coroutine to periodically update a metric to # simulate the application making some progress. async def updater(c: Counter): while True: c.inc({"kind": "timer_expiry"}) await asyncio.sleep(1.0) await updater(events_counter) # Finally stop server await service.stop() if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: pass ``` -------------------------------- ### Install aioprometheus with Starlette extras Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Installs the necessary dependencies for using Starlette-based metrics rendering. ```bash $ pip install aioprometheus[starlette] ``` -------------------------------- ### Prometheus Configuration for Scraping Examples Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html This is a minimal Prometheus configuration file to scrape metrics from example scripts. It sets a scrape interval and specifies the target address. ```yaml global: scrape_interval: 15s # By default, scrape targets every 15 seconds. evaluation_interval: 15s # By default, scrape targets every 15 seconds. scrape_configs: - job_name: 'test-app' # Override the global default and scrape targets from this job every # 5 seconds. scrape_interval: 5s scrape_timeout: 10s target_groups: - targets: ['localhost:8000'] labels: group: 'dev' ``` -------------------------------- ### Test Distribution Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Verifies the distribution by installing it into a fresh virtual environment and running the test suite. ```bash (aioprom) $ make test-dist ``` -------------------------------- ### GET / Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.service.html Handles requests to the root route, serving a trivial page with a link to the metrics. ```APIDOC ## GET / ### Description Handle a request to the / route. Serves a trivial page with a link to the metrics. Use this if ever you need to point a health check at your the service. ### Method GET ### Endpoint / ``` -------------------------------- ### Define and observe a Summary metric Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Example of recording observations in a Summary metric. ```python from aioprometheus import Summary http_access = Summary("http_access_time", "HTTP access time") http_access.observe({'time': '/static'}, 3.142) ``` ```python from aioprometheus import Summary http_access = Summary( "http_access_time", "HTTP access time", invariants=[(0.50, 0.05), (0.99, 0.001)]) ``` -------------------------------- ### Create and update a Counter metric Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Basic example of importing, instantiating, and incrementing a Counter metric. ```python from aioprometheus import Counter events_counter = Counter( "events_counter", "Total number of events.", ) events_counter.inc({"kind": "event A"}) ``` -------------------------------- ### Define a Counter metric Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Example of defining a Counter metric for tracking cumulative events. ```python from aioprometheus import Counter uploads_metric = Counter("file_uploads_total", "File total uploads.") uploads_metric.inc({'type': "png"}) ``` -------------------------------- ### GET /robots.txt Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.service.html Handles requests to the robots.txt file to discourage indexing. ```APIDOC ## GET /robots.txt ### Description Handle a request to /robots.txt. If a robot ever stumbles on this server, discourage it from indexing. ### Method GET ### Endpoint /robots.txt ``` -------------------------------- ### Expose Metrics with ASGI Middleware in FastAPI Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Integrate aioprometheus metrics into a FastAPI application using the ASGI middleware. This example requires fastapi, uvicorn, and aioprometheus. ```python from fastapi import FastAPI, Request, Response from aioprometheus import Counter, MetricsMiddleware from aioprometheus.asgi.starlette import metrics app = FastAPI() # Any custom application metrics are automatically included in the exposed # metrics. It is a good idea to attach the metrics to 'app.state' so they # can easily be accessed in the route handler - as metrics are often ``` -------------------------------- ### GET /metrics Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.service.html Handles requests to the metrics route, returning Prometheus metrics in the most efficient format. ```APIDOC ## GET /metrics ### Description Handles a request to the metrics route. The request is inspected and the most efficient response data format is chosen. ### Method GET ### Endpoint /metrics ``` -------------------------------- ### Push Metrics to Prometheus Push Gateway Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html This Python snippet demonstrates how to use the Pusher object to send metrics to a Prometheus Push Gateway. It requires the 'aiohttp' extra to be installed. The Pusher can be configured with a job name and grouping keys. ```python from aioprometheus import REGISTRY, Counter from aioprometheus.pusher import Pusher PUSH_GATEWAY_ADDR = "http://127.0.0.1:61423" pusher = Pusher("my-job", PUSH_GATEWAY_ADDR, grouping_key={"instance": "127.0.0.1:1234"}) c = Counter("total_requests", "Total requests.", {}) c.inc({'url': "/p/user"}) # Push to the push gateway resp = await pusher.replace(REGISTRY) ``` -------------------------------- ### GET /metrics (Starlette) Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.asgi.starlette.html The metrics function renders Prometheus metrics into the format specified by the 'accept' header. It automatically detects the registry from the Starlette app state or falls back to the default registry. ```APIDOC ## GET /metrics ### Description Render metrics into the format specified by the 'accept' header. This function attempts to retrieve the metrics Registry from the Starlette request app state, falling back to the default registry if not found. ### Method GET ### Endpoint /metrics ### Response #### Success Response (200) - **body** (string) - The rendered metrics in the format requested by the 'accept' header. ``` -------------------------------- ### GET /metrics - Quart Metrics Endpoint Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.asgi.quart.html This endpoint renders Prometheus metrics for your Quart application. It attempts to use a custom registry if configured, otherwise falls back to the default registry. ```APIDOC ## GET /metrics ### Description Renders metrics into the format specified by the ‘accept’ header. This function first attempts to retrieve the metrics Registry from `current_app` in case the app is using a custom registry instead of the default registry. If this fails then the default registry is used. ### Method GET ### Endpoint /metrics ### Parameters #### Query Parameters - **accept** (string) - Optional - The content type to render metrics in (e.g., "text/plain; version=0.0.4"). Defaults to Prometheus text format. ### Response #### Success Response (200) - **metrics** (string) - The Prometheus metrics in the requested format. ``` -------------------------------- ### Count Exceptions with @count_exceptions Decorator Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Utilize the @count_exceptions decorator to count exceptions occurring within a function. This example requires asyncio and aioprometheus.service. ```python # Create a metric to track requests currently in progress. REQUEST_EXCEPTIONS = Counter( "request_handler_exceptions", "Number of exceptions in requests" ) REQUESTS = Counter("request_total", "Total number of requests") # Decorate function with metric. @count_exceptions(REQUEST_EXCEPTIONS, {"route": "/"}) async def handle_request(duration): """A dummy function that occasionally raises an exception""" REQUESTS.inc({"route": "/"}) if duration < 0.3: raise Exception("Ooops") await asyncio.sleep(duration) async def handle_requests(): # Start up the server to expose the metrics. await svr.start(port=8000) # Generate some requests. while True: try: await handle_request(random.random()) except Exception: pass # keep handling if __name__ == "__main__": loop = asyncio.get_event_loop() svr = Service() try: loop.run_until_complete(handle_requests()) except KeyboardInterrupt: pass finally: loop.run_until_complete(svr.stop()) loop.stop() loop.close() ``` -------------------------------- ### Manage documentation Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Build and serve the project documentation locally. ```bash (aioprom) $ make docs ``` ```bash (aioprom) $ make serve-docs ``` -------------------------------- ### Run linting Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Perform static analysis using Pylint. ```bash (aioprom) $ make check-lint ``` -------------------------------- ### Run unit tests Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Execute the test suite using Makefile or the unittest module. ```bash (aioprom) $ make test ``` ```bash (aioprom) $ python -m unittest discover -s tests -v ``` ```bash (aioprom) $ cd aioprometheus/tests (aioprom) $ python -m unittest test_negotiate ``` -------------------------------- ### Apply code style Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Run the Black formatter and isort to ensure consistent code style. ```bash (aioprom) $ make style ``` -------------------------------- ### Run Prometheus with Configuration File Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Command to run the Prometheus server with a specified configuration file. ```bash $ ./prometheus -config.file my-prom-config.yaml ``` -------------------------------- ### Build Distribution Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Creates a pure Python wheel for the package. ```bash (aioprom) $ make dist ``` -------------------------------- ### Clone the repository Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Download the source code from GitHub to your local machine. ```bash $ git clone git@github.com:claws/aioprometheus.git $ cd aioprometheus ``` -------------------------------- ### Upload to PyPI Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Publishes the built distribution to the Python Package Index. ```bash (aioprom) $ make upload-dist ``` -------------------------------- ### Tag and Push Release Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Creates a version tag in the local repository and pushes it to the remote origin. ```bash $ git tag YY.MM.MICRO -m "A meaningful release tag comment" $ git tag # check release tag is in list $ git push --tags origin master ``` -------------------------------- ### Configure FastAPI with ASGI Metrics Middleware Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Attaches the MetricsMiddleware to a FastAPI application and defines a /metrics route for automatic metric collection. ```python app.state.users_events_counter = Counter("events", "Number of events.") app.add_middleware(MetricsMiddleware) app.add_route("/metrics", metrics) @app.get("/") async def root(request: Request): # pylint: disable=unused-argument return Response("FastAPI Middleware Example") @app.get("/users/{user_id}") async def get_user( request: Request, user_id: str, ): request.app.state.users_events_counter.inc({"path": request.scope["path"]}) return Response(f"{user_id}") if __name__ == "__main__": import uvicorn uvicorn.run(app) ``` -------------------------------- ### Fetching Metrics from Service Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Use curl to fetch the metrics exposed by the running aioprometheus Service in plain text format. ```bash $ curl http://127.0.0.1:8000/metrics # HELP events Number of events. ``` -------------------------------- ### Define and Observe Histograms Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html Create a Histogram metric and record observations using specific label values. ```python from aioprometheus import Histogram http_access = Histogram("http_access_time", "HTTP access time") http_access.observe({'time': '/static'}, 3.142) ``` ```python from aioprometheus import Histogram http_access = Histogram( "http_access_time", "HTTP access time", buckets=[0.1, 0.5, 1.0, 5.0]) ``` -------------------------------- ### Expose Prometheus Metrics with aioprometheus Service Source: https://aioprometheus.readthedocs.io/en/latest/user/index.html This script implements an asyncio application that exposes application metrics using the aioprometheus Service. It requires the 'psutil' package for collecting system metrics. The Service object provides a new HTTP endpoint for Prometheus metrics. ```python #!/usr/bin/env python """ This example implements an application that exposes application metrics obtained from the psutil package. This example requires the ``psutil`` package which can be installed using ``pip install psutil``. """ import asyncio import logging import random import socket import psutil from aioprometheus import Counter, Gauge, Histogram, Summary from aioprometheus.service import Service class ExampleApp: """ This example application attempts to demonstrates how ``aioprometheus`` can be integrated within a Python application built upon asyncio. This application attempts to simulate a long running distributed system process. It is intentionally not a web service application. In this case the aioprometheus Service object is used to provide a new HTTP endpoint that can be used to expose Prometheus metrics on. """ def __init__( self, metrics_host="127.0.0.1", metrics_port: int = 8000, ): self.metrics_host = metrics_host self.metrics_port = metrics_port self.timer = None # type: asyncio.Handle ###################################################################### # Create application metrics and metrics service # Create a metrics server. The server will create a metrics collector # registry if one is not specifically created and passed in. self.msvr = Service() # Define some constant labels that need to be added to all metrics const_labels = { "host": socket.gethostname(), "app": f"{self.__class__.__name__}", } # Create metrics collectors. No registry is passed when creating the # metrics so they get registered with the default registry. # Create a counter metric to track requests. self.requests_metric = Counter( "requests", "Number of requests.", const_labels=const_labels ) # Create a gauge metrics to track memory usage. self.ram_metric = Gauge( "memory_usage_bytes", "Memory usage in bytes.", const_labels=const_labels ) # Create a gauge metrics to track CPU. self.cpu_metric = Gauge( "cpu_usage_percent", "CPU usage percent.", const_labels=const_labels ) self.payload_metric = Summary( "request_payload_size_bytes", "Request payload size in bytes.", const_labels=const_labels, invariants=[(0.50, 0.05), (0.99, 0.001)], ) self.latency_metric = Histogram( "request_latency_seconds", "Request latency in seconds", const_labels=const_labels, buckets=[0.1, 0.5, 1.0, 5.0], ) async def start(self): """Start the application""" await self.msvr.start(addr=self.metrics_host, port=self.metrics_port) logger.debug(f"Serving prometheus metrics on: {self.msvr.metrics_url}") # Schedule a timer to update metrics. In a realistic application # the metrics would be updated as needed. In this example, a simple # timer is used to emulate things happening, which conveniently # allows all metrics to be updated at once. self.timer = asyncio.get_event_loop().call_later(1.0, self.on_timer_expiry) async def stop(self): """Stop the application""" await self.msvr.stop() if self.timer: self.timer.cancel() self.timer = None def on_timer_expiry(self): """Update application to simulate work""" # Update memory metrics self.ram_metric.set({"type": "virtual"}, psutil.virtual_memory().used) self.ram_metric.set({"type": "swap"}, psutil.swap_memory().used) # Update cpu metrics for c, p in enumerate(psutil.cpu_percent(interval=1, percpu=True)): self.cpu_metric.set({"core": c}, p) # Incrementing a requests counter to emulate webserver app self.requests_metric.inc({"path": "/"}) # Monitor request payload data to emulate webserver app self.payload_metric.add({"path": "/data"}, random.random() * 2 ** 10) # Monitor request latency to emulate webserver app self.latency_metric.add({"path": "/data"}, random.random() * 5) # re-schedule another metrics update self.timer = asyncio.get_event_loop().call_later(1.0, self.on_timer_expiry) if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) # Silence asyncio and aiohttp loggers logging.getLogger("asyncio").setLevel(logging.ERROR) logging.getLogger("aiohttp").setLevel(logging.ERROR) logger = logging.getLogger(__name__) ``` -------------------------------- ### MetricsMiddleware Class Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.asgi.middleware.html The MetricsMiddleware class is designed to wrap ASGI applications to automatically collect and expose Prometheus metrics. ```APIDOC ## MetricsMiddleware ### Description Implements a Prometheus metrics collection middleware for ASGI applications, tracking requests, responses, and exceptions. ### Parameters - **app** (Callable) - Required - The ASGI callable representing the next application or middleware in the chain. - **registry** (Registry) - Optional - The collector registry to use for rendering metrics. Defaults to the default registry. - **exclude_paths** (Sequence[str]) - Optional - A list of URL paths that should not trigger metric updates. Defaults to ('/metrics', '/metrics/', '/docs', '/openapi.json', '/docs/oauth2-redirect', '/redoc', '/favicon.ico'). - **use_template_urls** (bool) - Optional - Whether to use route template URLs (e.g., '/users/{user_id}') instead of literal paths. Supported in Starlette/FastAPI. Defaults to True. - **group_status_codes** (bool) - Optional - Whether to group status codes by kind (e.g., 2xx). Defaults to False. ``` -------------------------------- ### Check test coverage Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Generate a report on code coverage. ```bash (aioprom) $ make coverage ``` -------------------------------- ### Check type annotations Source: https://aioprometheus.readthedocs.io/en/latest/dev/index.html Verify type safety using mypy. ```bash (aioprom) $ make check-types ``` -------------------------------- ### Bucket Generation Utilities Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.histogram.html Utility functions to generate lists of bucket boundaries for histograms. ```APIDOC ## exponentialBuckets(start, factor, count) ### Description Returns buckets that are spaced exponentially. ### Parameters - **start** (Union[float, int]) - Required - The upper bound of the lowest bucket. - **factor** (Union[float, int]) - Required - The factor by which each following bucket's upper bound is multiplied. - **count** (int) - Required - The number of buckets to return. ## linearBuckets(start, width, count) ### Description Returns buckets that are spaced linearly. ### Parameters - **start** (Union[float, int]) - Required - The upper bound of the lowest bucket. - **width** (Union[int, float]) - Required - The width of each bucket. - **count** (int) - Required - The number of buckets to return. ``` -------------------------------- ### Metric Name and Labels Notation Source: https://aioprometheus.readthedocs.io/en/latest/api/aioprometheus.collectors.html Illustrates the notation for identifying time series using metric names and labels. Labels enable Prometheus's dimensional data model. ```text {