Planear tus puntos finales de REST utilizando grafana-infinity-datasource

Cuando se trata de observabilidad, Grafana es la herramienta de primera elección para la visualización. Un tablero de Grafana consta de varios tipos de visualizaciones, que normalmente están respaldadas por una base de datos.
Esto no siempre es el caso. A veces, en lugar de enviar los datos de la base de datos tal cual, podría querer refinar los datos. Esto no siempre se puede lograr mediante las funcionalidades que proporciona la BD. Por ejemplo, podría querer obtener resultados de una API propietaria. Es aquí donde entra en juego el plugin grafana-infinity-datasource. Con grafana-infinity-datasource, puede crear visualizaciones basadas en JSON, XML, CSV, etc. Puede enviar una solicitud HTTP a una API REST y representar los datos recibidos.

Tutorial

Supongamos que tenemos una aplicación de eShop. Crearemos una API de Python simple utilizando FastAPI para administrar los artículos del eShop y el volumen de compras.

A través de esta API, agregaremos elementos y entradas de volumen de compra.

Python

 

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
from datetime import datetime
 
app = FastAPI()
 
class Item(BaseModel):
    id: int
    name: str
    description: str = None
    price: float
 
class Purchase(BaseModel):
    price: float
    time: datetime
 
items = []
purchases = []
 
@app.post("/items/", response_model=Item)
def create_item(item: Item):
    items.append(item)
    return item
 
@app.get("/items/", response_model=List[Item])
def read_items():
    return items
 
@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
    for item in items:
        if item.id == item_id:
            return item
    raise HTTPException(status_code=404, detail="Item not found")
 
@app.delete("/items/{item_id}", response_model=Item)
def delete_item(item_id: int):
    for idx, item in enumerate(items):
        if item.id == item_id:
            return items.pop(idx)
    raise HTTPException(status_code=404, detail="Item not found")
 
@app.post("/purchases/", response_model=Purchase)
def create_purchase(purchase: Purchase):
    purchases.append(purchase)
    return purchase
 
@app.get("/purchases/", response_model=List[Purchase])
def read_purchases():
    return purchases

También necesitamos agregar FastAPI a requirements.txt:

Properties files

 

fastapi

Hostearemos la aplicación a través de Docker; por lo tanto, crearemos un archivo Dockerfile:

Dockerfile

 

FROM python:3.11-slim
 
WORKDIR /app
 
COPY requirements.txt .
 
RUN pip install --no-cache-dir -r requirements.txt
 
COPY main.py main.py
 
EXPOSE 8000
 
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Deberíamos proceder a las visualizaciones de Grafana. Básicamente, tenemos dos fuentes de datos diferentes.
La modelo de Item se mostrará en una tabla y el modelo de compra se mostrará a través de un gráfico de series temporales.

Utilizaré Docker Compose para proporcionar tanto a Grafana como a la aplicación Python:

Dockerfile

 

version: '3.8'
 
services:
  app:
    build: .
    ports:
      - 8000:8000
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - ./grafana:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=test
      - GF_SECURITY_ADMIN_PASSWORD=infinity
      - GF_INSTALL_PLUGINS=yesoreyeram-infinity-datasource

Básicamente, a través de la variable de entorno en Docker, habilito el plugin infinity-datasource.

Podemos poner nuestras instancias en funcionamiento mediante el siguiente comando:

Shell

 

docker compose up

Docker Compose V2 ya está aquí con muchas características buenas.

Ahora podemos poblarnos la aplicación con algunos datos:

Shell

 

$ curl -X POST "http://127.0.0.1:8000/purchases/" -H "Content-Type: application/json" -d '{"time": "2024-07-15T12:40:56","price":2.5}'
$ curl -X POST "http://127.0.0.1:8000/purchases/" -H "Content-Type: application/json" -d '{"time": "2024-07-15T12:41:56","price":4.0}'
$ curl -X POST "http://127.0.0.1:8000/purchases/" -H "Content-Type: application/json" -d '{"time": "2024-07-15T12:42:56","price":1.5}'
$ curl -X POST "http://127.0.0.1:8000/purchases/" -H "Content-Type: application/json" -d '{"time": "2024-07-15T12:43:56","price":3.5}'
 
$ curl -X POST "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -d '{"id": 1, "name": "Item 1", "description": "This is item 1", "price": 10.5, "tax": 0.5}'

Siguiendo adelante, creamos un panel en Grafana.

Una visualización para los elementos:

Una visualización para el volumen de compra:

Como pueden ver en ambos casos, utilicé el punto final http://app:8000 que es nuestra aplicación, y el DNS que la aplicación Compose puede resolver.

¡Eso es todo! Hemos representado nuestros datos de una API REST usando Grafana.

Source:
https://dzone.com/articles/plot-rest-endpoints-using-grafana-infinity-datasource