Python Microservice: Monitoring Stack
Both Prometheus and Grafana are compatible with microservice applications, integrating Prometheus with Flask is straightforward to provide performance and monitoring metrics.
Here I will update the docker-compose to add Prometheus and Grafana as services, then add Prometheus metrics in both order and user application code by importing PrometheusMetrics from the prometheus_flask_exporter module, which is used to expose Prometheus metrics for the Flask application. Then initialize Prometheus metrics with metrics = PrometheusMetrics(app). Use @metrics.counter('get_orders_count', 'Count of calls to the get_orders endpoint') to define a Prometheus counter metric that increments each time the get_orders endpoint is called.
Import os to enable environment variable for Logstash host, logstash_host = os.getenv('LOGSTASH_HOST', 'localhost') to fetch the Logstash host from environment variables, defaulting to localhost.
# Folder structure
/06-with-monitoringstack
├── api_gateway
│ ├── api_gateway.py
│ └── Dockerfile
├── docker-compose.yml
├── logstash.conf
├── order_service
│ ├── Dockerfile
│ ├── order_service.py
├── prometheus.yaml
└── user_service
├── Dockerfile
└── user_service.py
# add Prometheus and Grafana in docker-compose.yaml
version: '3'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
# create prometheus.yml for Prometheus configration
# vim prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'flask'
static_configs:
- targets: ['user-service:5001', 'order-service:5002']
# add Monitoring logic into python code
# order_service.py
import logging
import requests
from flask import Flask, jsonify
from pygelf import GelfUdpHandler
from prometheus_flask_exporter import PrometheusMetrics
import os
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('/orders')
def get_orders():
orders = [
{'id': 1, 'item': 'Laptop', 'price': 1200},
{'id': 2, 'item': 'Phone', 'price': 800}
]
app.logger.info("Fetched order data")
return jsonify(orders)
def register_service():
payload = {
"ID": "order-service",
"Name": "order-service",
"Address": "order-service",
"Port": 5002
}
response = requests.put('http://consul:8500/v1/agent/service/register', json=payload)
if response.status_code == 200:
app.logger.info("Order service registered successfully")
else:
app.logger.error("Failed to register order service")
if __name__ == '__main__':
# Configure logging
logstash_host = os.getenv('LOGSTASH_HOST', 'localhost')
handler = GelfUdpHandler(host=logstash_host, port=12201)
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)
register_service()
app.run(host='0.0.0.0', port=5002)
# user_service.py
import logging
import requests
from flask import Flask, jsonify
from pygelf import GelfUdpHandler
from prometheus_flask_exporter import PrometheusMetrics
import os
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('/users')
def get_users():
users = [
{'id': 1, 'name': 'Alice'},
{'id': 2, 'name': 'Bob'}
]
app.logger.info("Fetched user data")
return jsonify(users)
def register_service():
payload = {
"ID": "user-service",
"Name": "user-service",
"Address": "user-service",
"Port": 5001
}
response = requests.put('http://consul:8500/v1/agent/service/register', json=payload)
if response.status_code == 200:
app.logger.info("User service registered successfully")
else:
app.logger.error("Failed to register user service")
if __name__ == '__main__':
# Configure logging
logstash_host = os.getenv('LOGSTASH_HOST', 'localhost')
handler = GelfUdpHandler(host=logstash_host, port=12201)
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)
register_service()
app.run(host='0.0.0.0', port=5001)
Now Run docker-compose to bring all containers up and running. Should see all services with Prometheus and Grafana.
docker-compose up --build Creating 06-with-monitoringstack_api-gateway_1 ... done Creating 06-with-monitoringstack_order-service_1 ... done Creating 06-with-monitoringstack_user-service_1 ... done Creating 06-with-monitoringstack_kibana_1 ... done Creating 06-with-monitoringstack_grafana_1 ... done Creating 06-with-monitoringstack_logstash_1 ... done Creating 06-with-monitoringstack_prometheus_1 ... done Creating 06-with-monitoringstack_elasticsearch_1 ... done Creating 06-with-monitoringstack_consul_1 ... done
Verify Prometheus and Grafana
Access Grafana via http://localhost:3000, log in with admin/admin.
Add Prometheus as a Data Source in Grafana by setting the URL to http://localhost:9090 and save.
Create Dashboards in Grafana to use the Prometheus data source to visualize metrics from user-service and order-service.
Conclusion
Now we can enable monitoring with Prometheus and Grafana.
In the next post, I will see how to deploy our Python Flask microservice into Kubernetes.