A Prometheus exporter for Listmonk newsletter and mailing list manager
Project description
Listmonk Exporter
A Prometheus exporter for Listmonk, the self-hosted newsletter and mailing list manager. Monitor your email campaigns, subscriber counts, bounce rates, and more with this lightweight exporter.
Features
- 📊 Subscriber Metrics: Track subscriber counts by status (confirmed, unconfirmed, unsubscribed)
- 📧 Campaign Statistics: Monitor sent, opened, clicked, and bounced emails per campaign
- 📋 List Metrics: View subscriber counts across all your lists
- 🔄 Bounce Tracking: Track bounce counts by type (hard, soft, complaint)
- ⚡ Lightweight: Built with Python and runs as a single process
- 🐳 Docker Ready: Includes official Docker image for easy deployment
- 🔧 Configurable: Flexible configuration via environment variables or CLI arguments
Installation
Via pip
pip install listmonk-exporter
Via Docker
docker pull ghcr.io/meysam81/listmonk-exporter:latest
Configuration
Configure the exporter using environment variables or command-line arguments.
Required Configuration
| Environment Variable | Description | Example |
|---|---|---|
LISTMONK_HOST |
Listmonk instance URL | https://listmonk.example.com |
LISTMONK_API_USER |
Listmonk API username | admin |
LISTMONK_API_TOKEN |
Listmonk API token | your-api-token |
LIST_ID |
List ID to monitor | 1 |
LIST_NAME |
Name of the list | Newsletter |
Optional Configuration
| Environment Variable | Default | Description |
|---|---|---|
SCRAPE_INTERVAL |
60 |
Scrape interval in seconds |
PORT |
8000 |
Port for Prometheus HTTP server |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
Usage
Quick Start with pip
# Set required environment variables
export LISTMONK_HOST=https://listmonk.example.com
export LISTMONK_API_USER=admin
export LISTMONK_API_TOKEN=your-api-token
export LIST_ID=1
export LIST_NAME="Newsletter"
# Run the exporter
listmonk-exporter
Docker Compose
version: "3.8"
services:
listmonk-exporter:
image: ghcr.io/meysam81/listmonk-exporter:latest
ports:
- "8000:8000"
environment:
LISTMONK_HOST: https://listmonk.example.com
LISTMONK_API_USER: admin
LISTMONK_API_TOKEN: your-api-token
LIST_ID: 1
LIST_NAME: Newsletter
SCRAPE_INTERVAL: 60
LOG_LEVEL: INFO
restart: unless-stopped
Docker Run
docker run -d \
-p 8000:8000 \
-e LISTMONK_HOST=https://listmonk.example.com \
-e LISTMONK_API_USER=admin \
-e LISTMONK_API_TOKEN=your-api-token \
-e LIST_ID=1 \
-e LIST_NAME=Newsletter \
ghcr.io/meysam81/listmonk-exporter:latest
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: listmonk-exporter
spec:
replicas: 1
selector:
matchLabels:
app: listmonk-exporter
template:
metadata:
labels:
app: listmonk-exporter
spec:
containers:
- name: listmonk-exporter
image: ghcr.io/meysam81/listmonk-exporter:latest
ports:
- containerPort: 8000
env:
- name: LISTMONK_HOST
value: "https://listmonk.example.com"
- name: LISTMONK_API_USER
valueFrom:
secretKeyRef:
name: listmonk-credentials
key: username
- name: LISTMONK_API_TOKEN
valueFrom:
secretKeyRef:
name: listmonk-credentials
key: token
- name: LIST_ID
value: "1"
- name: LIST_NAME
value: "Newsletter"
---
apiVersion: v1
kind: Service
metadata:
name: listmonk-exporter
spec:
selector:
app: listmonk-exporter
ports:
- port: 8000
targetPort: 8000
Exported Metrics
The exporter provides the following Prometheus metrics:
| Metric Name | Type | Description | Labels |
|---|---|---|---|
listmonk_subscribers_by_status |
Gauge | Number of subscribers by subscription status | list_name, subscription_status |
listmonk_subscribers_total |
Gauge | Total number of subscribers in the list | list_name |
listmonk_campaign_stats |
Gauge | Campaign statistics (sent, opened, clicked, bounced) | campaign_id, campaign_name, campaign_status, stat_type |
listmonk_list_subscribers |
Gauge | Total subscribers per list | list_id, list_name, list_type |
listmonk_bounces_total |
Gauge | Total number of bounces by type | bounce_type |
listmonk_scrape_duration_seconds |
Histogram | Duration of scrape operations | operation |
listmonk_scrape_success |
Gauge | Whether the last scrape was successful (1=success, 0=failure) | operation |
listmonk_scrape_errors_total |
Counter | Total number of scrape errors | operation |
Metric Details
Subscriber Metrics:
subscription_statusvalues:confirmed,unconfirmed,unsubscribed
Campaign Metrics:
stat_typevalues:sent,opened,clicked,bouncedcampaign_statusvalues:draft,scheduled,running,paused,finished,cancelled
Bounce Metrics:
bounce_typevalues:hard,soft,complaint
Exporter Metrics:
operationvalues:subscribers,campaigns,lists,bounces
Prometheus Configuration
Add the following to your prometheus.yml:
scrape_configs:
- job_name: "listmonk"
static_configs:
- targets: ["localhost:8000"]
Note: For complete configuration examples including scrape jobs and alerting rules, see the examples directory.
Grafana Dashboard
Import the provided Grafana dashboard (coming soon) or create your own using the exported metrics.
Example queries:
# Total subscribers
listmonk_subscribers_total{list_name="Newsletter"}
# Confirmed subscribers
listmonk_subscribers_by_status{list_name="Newsletter",subscription_status="confirmed"}
# Campaign open rate
(listmonk_campaign_stats{stat_type="opened"} / listmonk_campaign_stats{stat_type="sent"}) * 100
Development
Prerequisites
- Python 3.11 or higher
- pip
Setup
# Clone the repository
git clone https://github.com/meysam81/listmonk-exporter.git
cd listmonk-exporter
# Install dependencies
pip install -e .
# Run locally
python main.py
Building Docker Image
docker build -t listmonk-exporter .
Troubleshooting
Exporter can't connect to Listmonk
- Verify
LISTMONK_HOSTis correct and accessible - Check that API credentials are valid
- Ensure Listmonk API is enabled
Metrics not updating
- Check
SCRAPE_INTERVALsetting - Review logs with
LOG_LEVEL=DEBUG - Verify the list ID exists in Listmonk
High memory usage
- Increase
SCRAPE_INTERVALto reduce scraping frequency - Check Listmonk API response sizes
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
Support
- 🐛 Issue Tracker
- 💬 Discussions
- 📧 Email: [Your email]
Acknowledgments
- Listmonk - The amazing newsletter manager
- Prometheus - Monitoring and alerting toolkit
- prometheus_client - Python client for Prometheus
Made with ❤️ for the open-source community.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file listmonk_exporter-0.1.1.tar.gz.
File metadata
- Download URL: listmonk_exporter-0.1.1.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f433ba8e51b81a84a3e6a47ae5088f9bcbab84f10f754220d768684e97747272
|
|
| MD5 |
43c49d3e597fe8fb7daec4145a38fabf
|
|
| BLAKE2b-256 |
d600ecfb1f2a7780944721b86743bcc0e7dde7e87a308729810d55c703df6241
|
Provenance
The following attestation bundles were made for listmonk_exporter-0.1.1.tar.gz:
Publisher:
ci.yml on meysam81/listmonk-exporter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
listmonk_exporter-0.1.1.tar.gz -
Subject digest:
f433ba8e51b81a84a3e6a47ae5088f9bcbab84f10f754220d768684e97747272 - Sigstore transparency entry: 636551027
- Sigstore integration time:
-
Permalink:
meysam81/listmonk-exporter@6fe5c0e8f53489d1a4d264f2a0d89943606c51eb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/meysam81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@6fe5c0e8f53489d1a4d264f2a0d89943606c51eb -
Trigger Event:
push
-
Statement type:
File details
Details for the file listmonk_exporter-0.1.1-py3-none-any.whl.
File metadata
- Download URL: listmonk_exporter-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bc65db898f8f2646173b202179c7bd42fe26b08ea57a18b96da2687793dc3db
|
|
| MD5 |
d2c5c07e519dbeaefae67b53bc34fd30
|
|
| BLAKE2b-256 |
1164afdaec58af8dfe1b0cbc2fdca02d625aab3520c60263dc5a88c804a685c3
|
Provenance
The following attestation bundles were made for listmonk_exporter-0.1.1-py3-none-any.whl:
Publisher:
ci.yml on meysam81/listmonk-exporter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
listmonk_exporter-0.1.1-py3-none-any.whl -
Subject digest:
8bc65db898f8f2646173b202179c7bd42fe26b08ea57a18b96da2687793dc3db - Sigstore transparency entry: 636551041
- Sigstore integration time:
-
Permalink:
meysam81/listmonk-exporter@6fe5c0e8f53489d1a4d264f2a0d89943606c51eb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/meysam81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@6fe5c0e8f53489d1a4d264f2a0d89943606c51eb -
Trigger Event:
push
-
Statement type: