Modern applications generate a lot of logs — from API response times to critical errors. Instead of tailing logs manually, I wanted a way to:
- Collect logs in one place
- Query them easily
- Get notified in Slack when something breaks
For this, I set up Grafana Loki as my log store, integrated it with Python, and added Slack alerts for production errors.
In this post, I’ll walk through the full setup:
- Setting up Loki
- Configuring Python logging with Loki
- Querying Loki using Python
- Sending alerts to Slack if an error occurs
🔹 Step 1: Setting Up Loki
First, install Loki and Promtail (Promtail collects logs and ships them to Loki).
Using Docker Compose
Create a docker-compose.yml
:
version: "3"
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:latest
volumes:
- /var/log:/var/log
command: -config.file=/etc/promtail/config.yml
Start Loki:
docker-compose up -d
Now Loki should be running at:
👉 http://localhost:3100
🔹 Step 2: Configure Promtail
Promtail’s job is to send your logs into Loki.
Example config.yml
:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*.log
This configuration ships logs from /var/log/*.log
into Loki.
🔹 Step 3: Python Logging to Loki
Now let’s push Python application logs to Loki.
Install the Loki Python handler:
pip install logging-loki
Update your Python app (app.py
):
import logging
from logging_loki import LokiHandler
# Loki URL (adjust to your setup)
LOKI_URL = "http://localhost:3100/loki/api/v1/push"
# Configure logger
logger = logging.getLogger("python-app")
logger.setLevel(logging.ERROR)
handler = LokiHandler(
url=LOKI_URL,
tags={"application": "my-python-app"},
version="1",
)
logger.addHandler(handler)
# Example: simulate an error
try:
1 / 0
except Exception as e:
logger.error("🚨 Production error occurred", exc_info=True)
Now, whenever your app throws an error, it gets pushed directly into Loki with structured metadata.
🔹 Step 4: Querying Loki with Python
Sometimes, you may want to query Loki programmatically (e.g., check API response times or errors).
import requests
LOKI_QUERY_URL = "http://localhost:3100/loki/api/v1/query"
query = '{application="my-python-app"} |= "error"'
response = requests.get(LOKI_QUERY_URL, params={"query": query})
if response.status_code == 200:
results = response.json()["data"]["result"]
for log in results:
print(log)
This lets you fetch error logs directly in Python.
🔹 Step 5: Slack Alerts for Errors
Finally, let’s notify Slack when something breaks.
Create a Slack Webhook
- Go to Slack → Apps → Create App → Incoming Webhooks
- Copy the Webhook URL
Python Code to Send Alerts
import requests
import json
import logging
from logging_loki import LokiHandler
# Slack webhook URL
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/XXX/YYY/ZZZ"
def send_slack_alert(message: str):
payload = {"text": message}
headers = {"Content-Type": "application/json"}
res = requests.post(SLACK_WEBHOOK_URL, data=json.dumps(payload), headers=headers)
if res.status_code != 200:
print(f"Slack alert failed: {res.text}")
# Loki logger
LOKI_URL = "http://localhost:3100/loki/api/v1/push"
logger = logging.getLogger("python-app")
logger.setLevel(logging.ERROR)
logger.addHandler(LokiHandler(url=LOKI_URL, tags={"app": "python-app"}, version="1"))
# Example: simulate production error
try:
result = 1 / 0
except Exception as e:
error_message = f"🚨 Error in production: {str(e)}"
logger.error(error_message, exc_info=True) # send to Loki
send_slack_alert(error_message) # send to Slack
🎯 Final Workflow
- Python app runs in production
- Any error → Logged to Loki
- Same error → Triggered as a Slack notification
This gives me two layers of monitoring:
- A full log history in Loki (via Grafana dashboards)
- Real-time notifications in Slack
✅ Conclusion
By combining Loki, Python, and Slack, I now have a centralized logging and alerting system:
- Loki collects and indexes all logs
- Python pushes structured errors directly
- Slack instantly alerts the team when something breaks
This setup has already saved me debugging time and ensures I never miss a production issue.
Top comments (0)