A sample environment running on Docker to showcase IT monitoring with the Elastic Stack. The monitored web apps support the backend of a simple todos application.
The demo environment consists of:
- a
backend
composed of two web apps exposed as REST APIs. The apps are written in Python using the FastAPI framework and run with the Uvicorn server. In particular:- the
xw-app-todos
app allows to read/create/update a todo item. It uses Redis as a persistence layer. - the
xw-app-reports
app allows to download a PDF summary of all todos, fetched via a REST call fromxw-app-todos
.
- the
- a one-node
Elasticsearch
cluster - a single instance of
Kibana
, connected to the Elasticsearch cluster - two running Beats to collect observability data from the backend: a
Filebeat
module to crawl and fetch logs, and aMetricbeat
module to collect performance metrics regularly - an Elastic APM Server that collects traces shipped by the APM Agents deployed on the backend apps
The diagram below displays the overall architecture of the demo environment.
All components of the demo environment run in Docker containers, in the same virtual Docker network. One can spin up the whole environment using docker compose.
docker-compose -f path/to/this/repo/apps-docker-compose.yml up
docker-compose -f path/to/this/repo/elasticsearch-docker-compose.yml up
docker-compose -f path/to/this/repo/beats-docker-compose.yml up
echo ELASTIC_APM_ENABLED=true > .env
docker-compose -f path/to/this/repo/apm-server-docker-compose.yml up
(to disable the APM agents again: echo ELASTIC_APM_ENABLED=false
)
echo ELASTIC_APM_ENABLED=true > .env
docker-compose -f path/to/this/repo/apps-docker-compose.yml -f path/to/this/repo/elasticsearch-docker-compose.yml -f path/to/this/repo/beats-docker-compose.yml -f path/to/this/repo/apm-server-docker-compose.yml up
The APIs of the xw-app-todos
and xw-app-reports
app are documented in Swagger and accessible at "/docs
". Below, just a quick overview:
GET /
: greetingsGET /todos?(showAll=true|false)
: get all the persisted todos. The optionalshowAll
parameter allows you to request only the uncompleted ones (default behaviour) or all of themGET /todos/{id}
: get a todo by idGET /todos/{id}/done
: update the status of the todo with the provided id, to mark it as doneGET /todos/{id}/undone
: update the status of the todo with the provided id, to mark it as not donePOST /todos
: create a new todo. Data is passed in the request body as JSON.
GET /
: greetingsGET /report
: get a PDF with the list of all the todos