Bij het thema observabiliteit is Grafana de tool van eerste keus voor visualisaties. Een Grafana-dashboard bestaat uit verschillende vormen van visualisaties, die meestal worden ondersteund door een database.
Dit is echter niet altijd het geval. Soms wil je de data niet direct van de database aanroepen zoals ze is, maar zijn je wel van plan de data te verfijnen. Dit kan soms niet worden behaald met de functionaliteiten die de DB biedt. Bijvoorbeeld, je wil misschien resultaten ophalen van een eigen API. Daar komt de grafana-infinity-datasource-plugin voor in de binnenkant. Met de grafana-infinity-datasource kun je visualisaties aanmaken op basis van JSON, XML, CSV, enzovoort. Je kunt een HTTP-verzoek uitvoeren naar een REST-API en de ontvangen data plotten.
Tutorial
Stel dat we een eShop-toepassing hebben. We zullen een eenvoudige Python-API aanmaken met FastAPI om de artikelen van de eShop en de aantal aankopen te beheren.
Via deze API zullen we items en aankoopvolume-entries toevoegen.
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
We hebben ook FastAPI nodig om toegevoegd te worden aan de requirements.txt:
fastapi
We zullen de applicatie hosten via Docker; dus zullen we een Dockerfile aanmaken:
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"]
We moeten verdergaan met de Grafana visualisaties. In essentie hebben we twee verschillende databronnen.
Het model Item zal in een tabel getoond worden en het model aankoop zal getoond worden via een tijdsreeksgrafiek.
Ik zal Docker Compose gebruiken om Grafana en de Python-applicatie in te stellen:
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
In essentie zetten we met behulp van de omgevingsvariabele op Docker de infinity-datasource
-plugin in.
We kunnen onze instanties opstarten door de volgende opdracht uit te voeren:
docker compose up
Docker Compose V2 is beschikbaar met vele goede functionaliteiten.
We kunnen nu de applicatie met enige data volgen:
$ 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}'
Verdergaande, maak een dashboard op Grafana.
Eén visualisatie voor items:
Eén visualisatie voor aankoopvolume:
Als u kunt zien in beide gevallen, heb ik de endpoint http://app:8000 gebruikt die onze applicatie is, en de DNS-naam die de Compose-toepassing kan resolveren.
Dat is het! We hebben onze data uit een REST API met Grafana geplot.
Source:
https://dzone.com/articles/plot-rest-endpoints-using-grafana-infinity-datasource