1
0
Fork
You've already forked cleaner
0
Tool to automatically remove dead or inactive federated servers from a Mastodon server.
  • Python 100%
2026年05月13日 13:17:02 +02:00
app Add TOOTCTL_PATH to .env variables. Add daily_stats table accumulative stats. Add ALT text description. Fix purge error. 2026年05月13日 13:17:02 +02:00
graphs first commit 2026年04月29日 22:43:17 +02:00
logs first commit 2026年04月29日 22:43:17 +02:00
LICENSE Add AGPL-3.0 license 2026年04月29日 22:54:50 +02:00
README.md Add save historic stats 2026年04月30日 17:30:24 +02:00
requirements.txt first commit 2026年04月29日 22:43:17 +02:00

Cleaner

Tool to automatically remove dead or inactive federated servers from a Mastodon server.

Description

This script analyzes all servers federated with your Mastodon server, checks their availability (DNS and HTTP), and automatically purges those that have been consecutively failing for 14 days. All verification data is stored in an independent PostgreSQL database to reliably track each server's status.

Features

  • Asynchronous and concurrent DNS and HTTP checking
  • Dedicated database to store verification history
  • Quarantine system with automatic purging after N days of failures
  • Detailed logs with automatic rotation
  • Dry-run mode to test without making actual changes
  • Interactive configuration on first run
  • Support for Unbound as local DNS resolver

Project Structure

cleaner
├── .env # Configuration (auto-generated)
├── logs # Execution logs
│ ├── cleanup.log # Full logs
│ ├── errors.log # Only errors
│ └── purge.log # Purge records
└── app
 ├── cleaner.py # Main script
 ├── publish.py # publish to Mastodon
 ├── publica.py # publish to Mastodon (catalan language)
 ├── db
 │ ├── schema.py # Database schema creation
 │ └── stats.py # save historic stats
 │ 
 └── services
 └── postgres.py # PostgreSQL connection management

Prerequisites

  • Python 3.10+
  • PostgreSQL (installed and running)
  • Mastodon (with access to /api/v1/instance/peers API)
  • Unbound (recommended for fast DNS resolution)

Python Dependencies

pip install asyncpg aiohttp loguru python-dotenv

Installation

  1. Clone the repository
git clone https://codeberg.org/spla/cleaner.git
cd cleaner
  1. Create virtual environment
python3 -m venv .
source bin/activate
  1. Install dependencies
pip install -r requirements.txt

Usage

First run (interactive configuration)

python app/cleaner.py

The script will ask for:

Your Mastodon server URL PostgreSQL credentials Advanced parameters (concurrency, timeouts, etc.) Responses are saved to the .env file.

Normal execution (dry-run by default)

python app/cleaner.py

Checks all federated servers Updates the database DOES NOT purge anything (analysis mode) Execute with real purge

python app/cleaner.py --execute

Checks all servers Updates the database PURGES servers that have been failing for 14 consecutive days Run with DEBUG log level

python app/cleaner.py --log-level DEBUG

Configuration

The auto-generated .env file contains:

MASTODON_URL=https://your-mastodon-server.org
DB_DSN=postgresql://user:password@localhost:5432/your_database
CONCURRENCY=20
TIMEOUT_DNS=5
TIMEOUT_HTTP=10
MAX_FAILURE_DAYS=14
BATCH_SIZE=50

Recommended settings

Parameter Default Description
CONCURRENCY 20-50 Concurrent checks (higher = faster but more resource intensive
TIMEOUT_DNS 3-5 Maximum seconds for DNS resolution
TIMEOUT_HTTP 5-10 Maximum seconds for HTTP request
MAX_FAILURE_DAYS 14 Consecutive failure days before purging
BATCH_SIZE 50 How many domains to purge per batch

Database

The script automatically creates a new database (default fedcleaner) with the server_health table:

Field Description
domain Federated server domain name
first_seen First time the server was checked
last_checked Last verification time
check_count Total number of verifications
consecutive_failures Current consecutive failures
last_success Last time it responded successfully
status alive, quarantine or dead
should_purge Flagged for purging

Useful queries

-- Connect to the database
psql-Umastodon-dfedcleaner-- View server status distribution
SELECTstatus,COUNT(*)FROMserver_healthGROUPBYstatus;-- View domains flagged for purging
SELECTdomain,consecutive_failures,last_checkedFROMserver_healthWHEREshould_purge=trueLIMIT10;

Automation with cron

To run the script daily in dry-run mode:

Edit crontab

crontab -e

Add (runs every day at 3:00 AM)

0 3 * * * cd /home/mastodon/bots/cleaner && source bin/activate && python app/cleaner.py > /dev/null

After several days (when MAX_FAILURE_DAYS has accumulated), you can manually run the real purge:

python app/cleaner.py --execute

Troubleshooting

"Too many open files"

Reduce CONCURRENCY in .env:

CONCURRENCY=10

PostgreSQL connection error

Verify credentials in .env and ensure PostgreSQL is running:

sudo systemctl status postgresql

Issues with Unbound

Make sure Unbound is configured as local resolver:

cat /etc/resolv.conf

Should show: nameserver 127.0.0.1

Logs

Logs are stored in logs/ with automatic rotation:

cleanup_YYYY-MM-DD.log: Full logs
errors_YYYY-MM-DD.log: Only errors
purge_YYYY-MM-DD.log: Purge records

Dry-run mode

By default, the script runs in dry-run mode (analysis without purging). This mode:

Checks all servers
Updates the database
Does NOT execute tootctl domains purge
To perform a real purge, use --execute.

Security

Passwords are stored in the .env file with 600 permissions
The database is independent from Mastodon's database
Purges are done in batches to avoid system overload

License

AGPL-3.0

Contributing

Contributions are welcome. Open an issue or pull request.