-
Notifications
You must be signed in to change notification settings - Fork 0
TMI Promtail Logger
Promtail logger application for sending TMI server logs to Grafana via Loki.
The TMI Promtail Logger is a lightweight log forwarding service that streams TMI server logs to Grafana Loki for centralized logging, monitoring, and analysis. It uses Grafana's Promtail agent configured specifically for Heroku deployments to collect and forward logs in real-time.
Repository: /Users/efitz/Projects/tmi-promtail
This tool enables comprehensive log management for TMI server deployments, making it easy to:
- Search and filter logs across time ranges
- Monitor application health and performance
- Debug issues with historical log data
- Set up alerts based on log patterns
- Visualize log metrics in Grafana dashboards
- Heroku Integration - Designed for Heroku log drain integration
- Real-time Streaming - Forwards logs to Loki as they're generated
- Label Enrichment - Automatically labels logs with app, environment, and dyno information
- Secure Transport - HTTPS connection with basic authentication
- Low Resource Usage - Lightweight Promtail agent with minimal overhead
- Auto-scaling - Scales with your Heroku dynos
┌─────────────┐
│ TMI Server │
│ (Heroku) │
└──────┬──────┘
│ Heroku Log Drain (HTTPS)
▼
┌─────────────┐
│ Promtail │
│ (Heroku) │
└──────┬──────┘
│ HTTPS + Basic Auth
▼
┌─────────────┐
│ Loki │
│ (Grafana) │
└──────┬──────┘
│
▼
┌─────────────┐
│ Grafana │
│ Dashboard │
└─────────────┘
- TMI Server generates logs on Heroku
- Heroku Log Drain forwards logs to Promtail via HTTPS
- Promtail processes and enriches logs with labels
- Loki stores logs in time-series format
- Grafana provides querying and visualization
- Heroku account with TMI server deployed
- Grafana Cloud account (or self-hosted Loki/Grafana)
- Git for deployment
- Log in to Grafana Cloud
- Navigate to Connections > Data Sources
- Find your Loki data source
- Note the URL (e.g.,
https://logs-prod-us-central1.grafana.net/loki/api/v1/push) - Create a new API key:
- Go to Security > API Keys
- Click Add API key
- Name: "TMI Promtail Logger"
- Role: MetricsPublisher
- Copy the API key
Your credentials:
- LOKI_URL: The push endpoint URL
- LOKI_USERNAME: Your Grafana instance ID (from URL)
- LOKI_PASSWORD: The API key you just created
If you're running your own Loki instance:
-
LOKI_URL: Your Loki push endpoint (e.g.,
http://loki:3100/loki/api/v1/push) - LOKI_USERNAME: Your basic auth username (if configured)
- LOKI_PASSWORD: Your basic auth password (if configured)
cd ~/Projects
git clone <repository-url> tmi-promtail
cd tmi-promtail# Create app
heroku create your-app-name-promtail
# Set buildpack for shell script execution
heroku buildpacks:add --index 1 heroku-community/apt
heroku buildpacks:add --index 2 https://github.com/heroku/heroku-buildpack-shell# Set Loki credentials
heroku config:set LOKI_URL="https://logs-prod-us-central1.grafana.net/loki/api/v1/push"
heroku config:set LOKI_USERNAME="123456" # Your Grafana instance ID
heroku config:set LOKI_PASSWORD="your-api-key-here"
# Promtail will use Heroku's $PORT automatically# Deploy
git push heroku master
# Verify deployment
heroku logs --tailAdd the Promtail app as a log drain for your TMI server:
# Get Promtail app URL
PROMTAIL_URL=$(heroku info -s | grep web_url | cut -d= -f2)
# Add log drain to TMI server app
heroku drains:add $PROMTAIL_URL --app your-tmi-server-app
# Verify drain was added
heroku drains --app your-tmi-server-app- Open Grafana
- Go to Explore
- Select your Loki data source
- Query:
{app="tmi-server"} - You should see logs streaming in
The configuration is defined in promtail-config.yaml:
server:
http_listen_port: ${PORT}
positions:
filename: /tmp/positions.yaml
clients:
- url: ${LOKI_URL}
basic_auth:
username: ${LOKI_USERNAME}
password: ${LOKI_PASSWORD}
scrape_configs:
- job_name: heroku
heroku_drain:
labels:
job: heroku
app: tmi-server
environment: heroku
source: heroku-dyno
relabel_configs:
- source_labels: [__heroku_drain_dyno]
target_label: dyno
- source_labels: [__heroku_drain_app]
target_label: heroku_appServer Configuration:
-
http_listen_port: ${PORT}- Uses Heroku's dynamic port assignment
Position Tracking:
-
filename: /tmp/positions.yaml- Tracks which logs have been sent (ephemeral on Heroku)
Loki Client:
-
url- Loki push endpoint -
basic_auth- Credentials for Loki
Labels:
-
job: heroku- Identifies log source -
app: tmi-server- Application name -
environment: heroku- Deployment environment -
source: heroku-dyno- Log origin
Dynamic Labels:
-
dyno- Extracted from__heroku_drain_dyno -
heroku_app- Extracted from__heroku_drain_app
Edit promtail-config.yaml to add custom labels:
scrape_configs:
- job_name: heroku
heroku_drain:
labels:
job: heroku
app: tmi-server
environment: production # Change this
team: security # Add custom label
region: us-east-1 # Add regionAfter changes, commit and redeploy:
git add promtail-config.yaml
git commit -m "Update Promtail labels"
git push heroku masterDefines the Heroku process:
web: ./promtail-linux-amd64 -config.file=./promtail-config.yaml -config.expand-env
- Runs Promtail binary
- Uses configuration file
-
-config.expand-envenables environment variable expansion
Buildpack script that downloads Promtail:
#!/bin/bash
curl -L -o promtail-linux-amd64.zip https://github.com/grafana/loki/releases/download/v3.5.5/promtail-linux-amd64.zip
unzip promtail-linux-amd64.zip
chmod +x promtail-linux-amd64Downloads Grafana Promtail v3.5.5 during deployment.
Specifies system dependencies:
unzip
Required to extract the Promtail binary.
{app="tmi-server"}
Shows all logs from TMI server.
{app="tmi-server", dyno="web.1"}
Shows logs from specific dyno.
{app="tmi-server"} |= "ERROR"
Shows only error logs.
{app="tmi-server"} |= "authentication failed"
rate({app="tmi-server"}[5m])
Log rate over 5-minute intervals.
sum by (dyno) (rate({app="tmi-server"}[5m]))
Log rate per dyno.
LogQL is Loki's query language, similar to PromQL:
Pattern Matching:
{app="tmi-server"} |~ "error|exception|failed"
JSON Parsing:
{app="tmi-server"} | json | level="error"
Metrics from Logs:
sum(rate({app="tmi-server"} |= "request" | json | status="500" [1m]))
Top Errors:
topk(10, sum by (error) (count_over_time({app="tmi-server"} |= "ERROR" [1h])))
In Grafana, create a dashboard with panels for:
Log Volume Panel:
sum(rate({app="tmi-server"}[1m]))
Error Rate Panel:
sum(rate({app="tmi-server"} |= "ERROR" [5m]))
Response Time Panel:
{app="tmi-server"} | json | __error__="" | unwrap duration | quantile_over_time(0.95, [5m])
Create alerts in Grafana for:
High Error Rate:
sum(rate({app="tmi-server"} |= "ERROR" [5m])) > 10
Application Down:
absent_over_time({app="tmi-server"}[5m])
Authentication Failures:
sum(rate({app="tmi-server"} |= "authentication failed" [5m])) > 5
Check Promtail is Running:
heroku ps --app your-promtail-appShould show web.1: up.
Check Promtail Logs:
heroku logs --tail --app your-promtail-appLook for connection errors or authentication failures.
Verify Drain Configuration:
heroku drains --app your-tmi-server-appShould show your Promtail URL.
Test Loki Connection:
curl -u "$LOKI_USERNAME:$LOKI_PASSWORD" "$LOKI_URL"Symptom: Promtail logs show "401 Unauthorized"
Solution:
- Verify
LOKI_USERNAMEandLOKI_PASSWORDare correct - Check API key hasn't expired
- Ensure API key has
MetricsPublisherrole - Update credentials:
heroku config:set LOKI_PASSWORD="new-api-key" --app your-promtail-app
Symptom: Promtail logs show "context deadline exceeded"
Solution:
- Check Loki URL is correct and accessible
- Verify network connectivity from Heroku
- Check Grafana Cloud status page
- Increase timeout (requires custom Promtail config)
Symptom: Logs appear but without expected labels
Solution:
- Verify
promtail-config.yamllabel configuration - Check
relabel_configsare correct - Ensure
-config.expand-envflag is set in Procfile - Restart Promtail after config changes
Check Crash Logs:
heroku logs --tail --app your-promtail-app | grep "error"Common Causes:
- Invalid configuration file (YAML syntax error)
- Missing environment variables
- Port binding issues (ensure using
$PORT) - Out of memory (upgrade dyno type)
Solution:
# Validate config locally
promtail -config.file=./promtail-config.yaml -config.expand-env=true -dry-run
# Check dyno size
heroku ps:type --app your-promtail-app
# Upgrade if needed
heroku ps:type web=standard-1x --app your-promtail-appSymptom: Promtail uses excessive memory
Causes:
- Large batch sizes
- High log volume
- Position file growth
Solutions:
- Adjust batch size in config
- Upgrade dyno type
- Clear position file periodically (though it's ephemeral on Heroku)
Promtail is lightweight but dyno size depends on log volume:
- Hobby/Free: Suitable for low-volume testing
- Standard-1X: Good for production with moderate logs
- Standard-2X: High-volume production deployments
# Check current dyno type
heroku ps --app your-promtail-app
# Upgrade if needed
heroku ps:type web=standard-2x --app your-promtail-app- Promtail itself is open source and free
- Heroku dyno costs apply (starting at $7/month for Standard-1X)
- Grafana Cloud has free tier (50GB logs/month)
- Self-hosted Loki has no licensing costs
Monitor and control log volume to reduce costs:
- Set appropriate log levels in TMI server
- Filter logs in Promtail config to exclude verbose logs
- Set retention policies in Loki
- Use sampling for high-frequency logs
To upgrade to a newer Promtail version:
-
Edit
buildpack-run.shand update version number:curl -L -o promtail-linux-amd64.zip https://github.com/grafana/loki/releases/download/v3.6.0/promtail-linux-amd64.zip
-
Commit and deploy:
git add buildpack-run.sh git commit -m "Upgrade Promtail to v3.6.0" git push heroku master -
Verify upgrade:
heroku logs --tail --app your-promtail-app | grep "version"
If you prefer Docker over Heroku:
FROM grafana/promtail:3.5.5
COPY promtail-config.yaml /etc/promtail/config.yaml
ENTRYPOINT ["/usr/bin/promtail", "-config.file=/etc/promtail/config.yaml", "-config.expand-env"]Deploy to any container platform (ECS, Cloud Run, Kubernetes).
For Kubernetes deployments:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: promtail
spec:
selector:
matchLabels:
app: promtail
template:
metadata:
labels:
app: promtail
spec:
containers:
- name: promtail
image: grafana/promtail:3.5.5
args:
- -config.file=/etc/promtail/config.yaml
- -config.expand-env
env:
- name: LOKI_URL
valueFrom:
secretKeyRef:
name: promtail-secrets
key: loki-url
volumeMounts:
- name: config
mountPath: /etc/promtail
- name: varlog
mountPath: /var/log
volumes:
- name: config
configMap:
name: promtail-config
- name: varlog
hostPath:
path: /var/logAlternatively, use Grafana Cloud's native Heroku integration:
- Install Grafana Cloud app from Heroku marketplace
- Configure directly without Promtail middleman
Pros: Simpler setup, no Promtail management Cons: Less control over log processing and enrichment
- Rotate API keys regularly
- Use environment variables for all credentials (never hardcode)
- Enable TLS for Loki connections (default with Grafana Cloud)
- Restrict Promtail to only MetricsPublisher role
- Monitor access logs in Grafana Cloud
- Monitor Promtail health with Grafana alerts
- Set up dyno alerts in Heroku dashboard
- Configure log retention policies in Loki
- Test failover scenarios periodically
- Document recovery procedures
- Right-size dynos based on log volume
- Batch logs efficiently with Promtail config
- Use labels wisely (too many = high cardinality)
- Set sensible retention (balance cost vs. history)
- Archive old logs to S3 if needed
- Monitoring and Health - TMI monitoring guide
- Debugging Guide - Debugging techniques
- Performance Troubleshooting - Performance issues
- Database Operations - Database monitoring
- Grafana Loki Documentation
- Promtail Documentation
- LogQL Query Language
- Heroku Log Drains
- Grafana Cloud
For issues:
- Check Promtail logs:
heroku logs --tail --app your-promtail-app - Verify drain configuration:
heroku drains --app your-tmi-server-app - Test Loki connectivity with curl
- Review Grafana Cloud status page
- See Getting Help for support channels
Promtail Version: 3.5.5 License: Apache License 2.0
- Using TMI for Threat Modeling
- Accessing TMI
- Creating Your First Threat Model
- Understanding the User Interface
- Working with Data Flow Diagrams
- Managing Threats
- Collaborative Threat Modeling
- Using Notes and Documentation
- Metadata and Extensions
- Planning Your Deployment
- Deploying TMI Server
- Deploying TMI Web Application
- Setting Up Authentication
- Database Setup
- Component Integration
- Post-Deployment
- Monitoring and Health
- Database Operations
- Security Operations
- Performance and Scaling
- Maintenance Tasks