DiscordLogger
A minimal, reliable Minecraft server logging plugin that posts clean messages to a Discord webhook — as rich embeds or plain Markdown text.
No bot to invite, no token to manage, no third-party service. It posts over a plain Discord webhook, so setup is a copy-paste and a restart.
Paper only
This plugin uses Paper's chat API. On Spigot or CraftBukkit it tells you so on startup rather than failing with a stack trace. Paper forks such as Purpur, Pufferfish and Leaf work fine.
| Requirement | Version |
|---|---|
| Server | Paper 1.19 – 26.2, or a fork such as Purpur |
| Java | 17 or newer |
| Discord | A webhook URL — no bot required |
Compiled for Java 17, so it loads on that and anything newer. Your Minecraft version sets the real floor — 1.19 needs Java 17, 1.20.5 needs 21, 26.x needs 25. Whatever your server already runs on is fine.
Tested with Geyser/Floodgate for Bedrock cross-play.
What it logs
Every event has its own toggle, its own embed colour, and can be sent to its own Discord channel.
- Player — Join, Quit, Chat, Command, Death, Advancement, Teleport, Gamemode
- Server — Start, Stop, Console Command, Explosion (with the source and blocks destroyed)
- Moderation — Ban, Unban, Kick, Op, Deop, Whitelist toggle, Whitelist add/remove
Moderation events only log when they actually succeeded — a failed ban attempt from someone without permission doesn't appear.
Features
Per-event channel routing. Send moderation to a private staff channel and chat to a public one. Anything left blank uses the main webhook, and each destination gets its own queue so a busy chat channel never delays your moderation log.
Fourteen filters. Ignore specific commands, players, worlds, chat content, advancements, teleport causes, death causes and explosion sources, with minimum chat length, teleport distance and explosion size thresholds.
Passwords stay out of your channel. /login, /register and /msg are filtered by default. Command logging posts the line exactly as typed, so without this it would publish passwords and private messages to Discord.
Every message is yours. lang.yml holds all 79 of them — reword or translate anything without touching code. In-game text supports MiniMessage formatting; Discord text is plain, with Markdown.
Rich embeds. Per-event colours, configurable author, player avatar thumbnails, server icon and timestamps. Or switch the whole thing to plain text.
Bedrock indicator. Joins from Bedrock are flagged when the server runs Geyser with Floodgate. It never labels anyone "Java" — that would be a guess presented as a fact.
Death details. The cause of death is its own embed field, built from server-side damage context rather than client-localised text, so it reads the same for Java and Bedrock players. Coordinates optional.
Nothing gets dropped. Sends are queued and paced against Discord's rate limits, per webhook.
Your config survives updates. Settings migrate forward one schema version at a time, comments and all, and the previous file is always kept. A config from a newer build is never silently downgraded.
Setup
- Drop the JAR in
plugins/and start the server once. It writesconfig.ymlandlang.yml. - Set your webhook:
/discordlogger webhook https://discord.com/api/webhooks/… - That's it — logging starts immediately.
The plugin runs happily without a webhook, logging to console and telling you what's missing, so nothing breaks while you finish setting up.
Don't want to edit YAML? The config generator builds both files in your browser — every event, colour, filter and message. Your webhook URL never leaves your browser except to Discord.
Commands
Aliases: /dlogger, /dlog
| Command | What it does | Permission |
|---|---|---|
/discordlogger reload |
Reload config.yml and lang.yml |
discordlogger.reload |
/discordlogger webhook <url> |
Set the webhook and reload, no YAML editing | discordlogger.webhook |
/discordlogger regen [confirm] |
Rebuild config.yml from this build's default, backing up the current one |
discordlogger.regen |
The webhook URL is never echoed back and is redacted from command logging, so running that command doesn't publish the URL to the channel you're setting up.
Guides
- Setup guide — creating the webhook, and checking events actually arrive
- Log to Discord without a bot — why a webhook is enough, and what you give up
- Moderation logs in a private channel — per-event routing
- Reduce logging spam — the fourteen filters, by the problem each solves
- Translate every message —
lang.yml - Geyser and Bedrock — cross-play logging
- Webhook not posting? — troubleshooting
- Configuration reference — every key explained
- GitHub — source, issues and releases
Privacy
Anonymous usage metrics are reported to bStats. They describe your setup, never your players: server and Java version, whether you run behind a proxy, which companion plugins are installed, which events and filters you've changed from the defaults, and where your config came from.
Never collected: webhook URLs, player names, UUIDs, IP addresses, message content, coordinates, or world names. Counts are reported as ranges rather than exact numbers.
Opt out in plugins/bStats/config.yml, which covers every bStats plugin at once.
