clook-ftp-monitor
Tracks all file uploads to FTP on your cPanel server in real time, giving you clear stats on who uploaded what, when, and how much data was transferred. The dashboard helps IT or operations staff quickly spot unusual upload activity and filter uploads by user or filename. It removes the need to dig through logs manually and keeps everything secure by using existing login sessions.
FTP Upload Monitor
A lightweight dashboard for monitoring FTP uploads on cPanel servers with Pure-FTPd.
Features
- Real-time tracking of all FTP uploads
- Filter by username or filename
- Summary statistics (total uploads, last 24h, unique users, total data)
- Summary by filename (upload count, total size, users, last uploaded)
- Daily totals with anomaly detection (highlights unusual activity)
- Sortable columns on all tables
- Copy-to-clipboard for file paths
- Auto-refresh every 60 seconds
- Last FTP upload timestamp
- Authenticated via existing PHP session system (no separate login required)
- JSON data stored outside web root for security
File Structure
/home/xxxxxxxx/ftpmonitor/
├── ftp_log_parser.py # Log parser script
├── ftp_uploads.json # Upload data (auto-generated, outside web root)
├── parser.log # Parser execution log
└── .htpasswd # (unused - auth handled by PHP sessions)
/home/xxxxxxxx/public_html/ftp-monitor/
├── ftp_dashboard.php # Web dashboard (PHP session auth required)
└── ftp_data.php # Authenticated JSON data endpoint
Installation
1. Create directories
mkdir -p /home/xxxxxxxx/ftpmonitor
mkdir -p /home/xxxxxxxx/public_html/ftp-monitor
2. Set correct ownership
chown xxxxxxxx:xxxxxxxx /home/xxxxxxxx/ftpmonitor
chown xxxxxxxx:xxxxxxxx /home/xxxxxxxx/public_html/ftp-monitor
3. Make /var/log/messages readable
chmod 644 /var/log/messages
To persist this after log rotation, add create 0644 root root to /etc/logrotate.d/syslog:
sed -i 's/missingok/missingok\n create 0644 root root/' /etc/logrotate.d/syslog
4. Deploy files
Upload to the server:
ftp_log_parser.py→/home/xxxxxxxx/ftpmonitor/ftp_dashboard.php→/home/xxxxxxxx/public_html/ftp-monitor/ftp_data.php→/home/xxxxxxxx/public_html/ftp-monitor/
5. Run initial parse
python3 /home/xxxxxxxx/ftpmonitor/ftp_log_parser.py
6. Set up cron job (under xxxxxxxx user)
crontab -e -u xxxxxxxx
Add:
*/5 * * * * /usr/bin/python3 /home/xxxxxxxx/ftpmonitor/ftp_log_parser.py >> /home/xxxxxxxx/ftpmonitor/parser.log 2>&1
7. Access the dashboard
https://yourdomain.com/ftp-monitor/ftp_dashboard.php
Requires an active session from the existing reporting login at account_login.php.
How It Works
- Log Parser: Reads
/var/log/messagesand extracts Pure-FTPd upload events - Data Storage: Stores upload records in JSON at
/home/xxxxxxxx/ftpmonitor/ftp_uploads.json(outside web root, keeps last 1000 records) - Data Endpoint:
ftp_data.phpvalidates the PHP session then serves the JSON with correctLast-Modifiedheaders - Dashboard:
ftp_dashboard.phpchecks PHP session auth, then fetches data fromftp_data.php - Cron Job: Runs the parser every 5 minutes under the
xxxxxxxxuser
Configuration
Parser
Edit /home/xxxxxxxx/ftpmonitor/ftp_log_parser.py:
LOG_FILE = "/var/log/messages" # Source log file
DATA_FILE = "/home/xxxxxxxx/ftpmonitor/ftp_uploads.json" # Output JSON
MAX_RECORDS = 1000 # Records to keep
Dashboard auto-refresh
Edit ftp_dashboard.php to change the refresh interval:
setInterval(loadData, 60000); // milliseconds
Security
ftp_uploads.jsonis stored outside the web root — not directly accessible via browserftp_data.phpvalidates the PHP session before serving any data, returning 401 if unauthenticatedftp_dashboard.phpredirects unauthenticated users toaccount_login.php- Auth reuses the existing session system (groups: Admin, User, Business, Despatch)
- Dashboard is read-only
Troubleshooting
No uploads showing
Verify Pure-FTPd logging is enabled:
grep VerboseLog /etc/pure-ftpd.conf # Should show: VerboseLog yesConfirm uploads are being logged:
grep "uploaded" /var/log/messages | tail -5Check the parser log:
cat /home/xxxxxxxx/ftpmonitor/parser.logRun the parser manually as the cron user to test:
su -s /bin/bash xxxxxxxx -c "/usr/bin/python3 /home/xxxxxxxx/ftpmonitor/ftp_log_parser.py"
Dashboard shows "Failed to load data"
Check the JSON file exists:
ls -la /home/xxxxxxxx/ftpmonitor/ftp_uploads.jsonCheck file permissions (must be readable by xxxxxxxx):
chmod 644 /home/xxxxxxxx/ftpmonitor/ftp_uploads.jsonOpen browser console (F12) and check for errors
Cron not running
Verify the cron entry:
crontab -l -u xxxxxxxxCheck directory ownership (xxxxxxxx must own ftpmonitor to write parser.log):
ls -la /home/xxxxxxxx/ | grep ftpmonitorTest manually as xxxxxxxx user:
su -s /bin/bash xxxxxxxx -c "/usr/bin/python3 /home/xxxxxxxx/ftpmonitor/ftp_log_parser.py"
Sample Record
{
"timestamp": "2026-04-03T11:18:37",
"username": "user@example.com",
"ip_address": "xxx.xxx.xxx.xxx",
"filepath": "/home/xxxxxxxx/public_html/path/to/file.csv",
"filename": "Orders.csv",
"bytes": 18677,
"size_mb": 0.02,
"speed": "686.02KB/sec"
}