On the subject of observability Grafana is the go-to instrument for visualization. A Grafana dashboard consists of assorted types of visualizations that are often backed by a database.
This isn’t all the time the case. Typically as an alternative of pushing the info from the database as is, you may need to refine the info. This can not all the time be achieved via the functionalities the DB offers. For instance, you may need to fetch outcomes from a proprietary API. That is the place the grafana-infinity-datasource plugin kicks in. With grafana-infinity-datasource, you’ll be able to create visualizations primarily based on JSON, XML, CSV, and so forth. You may situation an HTTP request to a REST API and plot the acquired information.
Tutorial
Let’s assume we’ve an eShop software. We are going to create a easy Python API utilizing FastAPI to handle the gadgets of the eShop and the acquisition quantity.
By way of this API, we are going to add gadgets and purchase-volume entries.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Record
from datetime import datetime
app = FastAPI()
class Merchandise(BaseModel):
id: int
title: str
description: str = None
worth: float
class Buy(BaseModel):
worth: float
time: datetime
gadgets = []
purchases = []
@app.submit("/items/", response_model=Merchandise)
def create_item(merchandise: Merchandise):
gadgets.append(merchandise)
return merchandise
@app.get("/items/", response_model=Record[Item])
def read_items():
return gadgets
@app.get("/items/{item_id}", response_model=Merchandise)
def read_item(item_id: int):
for merchandise in gadgets:
if merchandise.id == item_id:
return merchandise
elevate HTTPException(status_code=404, element="Item not found")
@app.delete("/items/{item_id}", response_model=Merchandise)
def delete_item(item_id: int):
for idx, merchandise in enumerate(gadgets):
if merchandise.id == item_id:
return gadgets.pop(idx)
elevate HTTPException(status_code=404, element="Item not found")
@app.submit("/purchases/", response_model=Buy)
def create_purchase(buy: Buy):
purchases.append(buy)
return buy
@app.get("/purchases/", response_model=Record[Purchase])
def read_purchases():
return purchases
We additionally want FastAPI to be added to the necessities.txt:
We are going to host the applying via Docker; thus, we are going to create a Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY necessities.txt .
RUN pip set up --no-cache-dir -r necessities.txt
COPY fundamental.py fundamental.py
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
We must always proceed to the Grafana visualizations. Basically, we’ve two totally different sources of information.
The mannequin Merchandise will likely be visualized in a desk and the mannequin buy will likely be visualized via a time sequence graph.
I shall use Docker Compose to provision Grafana in addition to the Python software:
model: '3.8'
providers:
app:
construct: .
ports:
- 8000:8000
grafana:
picture: grafana/grafana:newest
ports:
- "3000:3000"
volumes:
- ./grafana:/var/lib/grafana
setting:
- GF_SECURITY_ADMIN_USER=check
- GF_SECURITY_ADMIN_PASSWORD=infinity
- GF_INSTALL_PLUGINS=yesoreyeram-infinity-datasource
Basically via the setting variable on Docker, I allow the the infinity-datasource
plugin.
We will get our cases up and operating by issuing the next:
Docker Compose V2 is on the market with many good options.
We will now populate the applying with some information:
$ 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}'
Transferring onward, create a dashboard on Grafana.
One visualization for gadgets:
One visualization for buy quantity:
As you’ll be able to see in each circumstances, I used the http://app:8000 endpoint which is our software, and the DNS that the Compose software can resolve.
That’s it! We plotted our information from a REST API utilizing Grafana.