Когда речь идет о наблюдаемости Grafana является стандартным инструментом для визуализации. Dashboard Grafana состоит из различных визуализаций, которые, как правило, поддерживаются базой данных.
Это не всегда так. Иногда вместо того, чтобы выталкивать данные из базы как есть, может потребоваться отформатировать данные. Это не всегда можно реализовать с помощью функций, которые предоставляет база данных. Например, может потребоваться извлечь результаты из закрытого API. В этом месте вступает в действие плагин grafana-infinity-datasource. С помощью grafana-infinity-datasource можно создавать визуализации на основе JSON, XML, CSV и т. д. Можно выполнять HTTP-запрос к REST API и настраивать полученные данные.
Tutorial
Предположим, у нас есть приложение eShop. Мы создадим простой Python API с использованием FastAPI для управления товарами в eShop и объемом покупок.
через этот API мы добавим элементы и записи об объеме покупок.
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
Также нам нужно добавить FastAPI в requirements.txt:
fastapi
Мы будем хостить приложение через Docker; следовательно, мы создадим 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"]
Мы должны перейти к визуализациям Grafana. в принципе, у нас есть две различные источники данных.
Модель Item будет представлена в таблице, а модель purchase будет представлена через график временных рядов.
Я буду использовать Docker Compose для настройки Grafana, а также 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
В основном с помощью переменной среды Docker я активирую плагин infinity-datasource
.
Мы можем запустить наши экземпляры, выполнив следующее:
docker compose up
Docker Compose V2 уже есть с множеством хороших функций.
Теперь мы можем заполнить приложение какими-то данными:
$ 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}'
Продолжая, создадим панель управления в Grafana.
Один визуализаций для элементов:
Одна визуализация для объема покупок:
Как вы можете видеть в обоих случаях, я использовал endpoint http://app:8000, который наш приложение, и DNS, который Compose-приложение может исправить.
Вот это все! Мы нарисовали нашу данные с помощью REST API с использованием Grafana.
Source:
https://dzone.com/articles/plot-rest-endpoints-using-grafana-infinity-datasource