GraniteLog is a high-performance block logging and rollback plugin built for Paper/Spigot servers. It prioritizes speed, clarity, and admin usability, while keeping the database schema simple, efficient, and migration-friendly.
✅ Actively tested on latest Paper builds
✅ Compact storage with
zero-NBT by default (optional JSON compression)
✅ Multiple storage options:
SQLite, MySQL/MariaDB, PostgreSQL
Key Features
Block & Action Tracking
- Tracks all major block-related events:
- Block place/break, fluid flow, crop growth, explosions
- Interactions: doors, levers, buttons, beds, armor stands, sign edits, books
- Container edits (add/remove items) with meta-aware diffs
- Hopper/pipe IO moves tracked separately
Investigation Tools
- /inspect — Click blocks to view full history
- Sneak → paginate results
- Sprint → view container diffs + recent sign edits
- /lookup — Quickly list changes at the targeted block
⏪ Rollback, Restore & Undo
- Rollback/restore any set of changes with filters:
- Radius, time, user, block ID, action, entity
- Preview → Confirm workflow prevents mistakes
- Each operation generates a batch ID, allowing precise undo with /rbundo
Discord Webhooks
- Send formatted change logs straight to Discord
- Features:
- Multiple endpoints with per-webhook action filters
- Async dispatch queue (won’t block gameplay)
- TNT explosions show affected block counts
Storage & Maintenance
- Databases supported: SQLite (default), MySQL/MariaDB, PostgreSQL
- Automatic schema migrations on startup
- Retention policy to purge old data automatically
- Optional JSON meta compression to save space
⚡ Performance-Oriented
- Async ingest queue with backpressure + drop counter
- Batched database writes & optimized indices
- Configurable safety caps for heavy rollbacks
Commands Overview
Inspection & Lookup
- /inspect [on|off] → Click a block for history
- /lookup [limit=N] → List recent changes instantly
Rollback & Restore
- /rollback preview <filters>
- /rollback confirm <filters>
- /restore preview <filters>
- /restore confirm <filters>
- Filters: radius|r, time=30m/12h/3d, user=<name>, block=<ns:id>, action=place,break,explode, entity=<ns:id>, chunklock, page=<n>
Undo
- /rbundo <batchId> — Undo an exact rollback/restore
Admin
- /glog status → Event & queue stats
- /glog reload → Reload config
- /glog purge olderThan:<time> → Purge old rows (e.g. 90d, 12h)
- /glog migrate to:mysql → Migrate data from SQLite → MySQL
Permissions
GraniteLog uses fine-grained permission nodes so you can control who can investigate, rollback, and manage data.
permissions:
glog.inspect:
description: Use inspect mode
default: op
glog.lookup:
description: Lookup history
default: op
glog.rollback:
description: Execute rollbacks
default: op
glog.restore:
description: Execute restores
default: op
glog.rbundo:
description: Undo a rollback batch
default: op
glog.admin:
description: Use GraniteLog admin commands
default: op
children:
glog.admin.status: true
glog.admin.purge: true
glog.admin.reload: true
glog.admin.status:
description: View GraniteLog status
default: op
glog.admin.purge:
description: Purge old GraniteLog records
default: op
glog.admin.reload:
description: Reload GraniteLog config/locales
default: op
Permission Overview
- glog.inspect → Toggle inspect mode and click blocks for history
- glog.lookup → Use /lookup to list recent changes
- glog.rollback → Run rollbacks with /rollback
- glog.restore → Run restores with /restore
- glog.rbundo → Undo rollbacks/restores with /rbundo
- glog.admin → Master node for all admin commands
- glog.admin.status → View plugin statistics
- glog.admin.purge → Purge old data
- glog.admin.reload → Reload config and locales
⚙ Config Highlights (config.yml)
- Choose storage: sqlite | mysql | postgres
- Configure limits:
- Inspect max entries
- Rollback preview/confirm thresholds
- Enable/disable action logging (block, container, interactions, fluids, growth, explosions, containerIO)
- JSON compression with configurable threshold
- Webhook settings: endpoints, filters, timeouts
Data Migration (SQLite → MySQL)
Migrate seamlessly without losing data:
- Configure MySQL in config.yml (keep storage.type: sqlite)
- Run: /glog migrate to:mysql
- Switch storage type to mysql and restart
Migration is safe: SQLite remains intact as a backup.
Inspect & Lookup in Action
- Inspect → View detailed history with timestamps & actors
- Sprint while inspecting to show:
- Container changes (-3x cobblestone | +2x sand)
- Sign edits (preview old → new)
- Lookup → One-shot block history without interaction
⏪ Rollback/Restore Workflow
- Preview to review changes
- Confirm to apply rollback/restore
- GraniteLog reports: Rollback applied. Batch <id>, changed <n> blocks.
- Undo at any time with /rbundo <id>
Performance & Storage
- Automatic schema migrations
- Retention policies to purge old logs
- Optimized indices for fast lookups
- Async queue ensures no TPS drops during heavy logging
❓ FAQ
Q: Does it support PostgreSQL?
A: Yes — set storage.type: postgres.
Q: How do I find a batch ID for /rbundo?
A: After a rollback/restore, GraniteLog prints Batch <id> in chat.
Q: Can I filter Discord notifications?
A: Yes — set per-webhook action filters.
Q: How do I reduce database size?
A: Enable JSON meta compression + configure retention.
Roadmap
- Smarter webhook rate limiting/backoff
- Optional Discord embed formatting
- More granular filters & summaries in /inspect
Support
- Open an issue with your server version + config
- For performance help, include: timings, row counts, database type