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.
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:
fastapi
Hostearemos la aplicación a través de Docker; por lo tanto, crearemos un archivo 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:
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:
docker compose up
Docker Compose V2 ya está aquí con muchas características buenas.
Ahora podemos poblarnos la aplicación con algunos datos:
$ 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