A real-time, web-based dashboard to monitor your server's vital statistics.
1.1K
A real-time, web-based dashboard to monitor your server's vital statistics. Built with Python, Flask, Socket.IO, psutil, and Docker for easy deployment. The frontend uses HTML, Tailwind CSS, and Chart.js for a modern, responsive, and themeable interface.

radeontop integration. Shows status message; can be extended to parse output from radeontop.localStorage.POLLING_INTERVAL_MS). Default is 2000ms.server-monitor-docker/
āāā Dockerfile # Defines the Docker image
āāā requirements.txt # Python dependencies
āāā run.py # Entrypoint script for Docker to start the Flask-SocketIO app
āāā backend/
ā āāā app.py # Flask application, Socket.IO handling, routes
ā āāā collectors.py # Data collection logic using psutil
āāā frontend/
āāā index.html # Main HTML page with CSS and JavaScript
Create Project Directory: If you haven't cloned a repository, create the project directory structure as shown above.
mkdir -p server-monitor-docker/backend
mkdir -p server-monitor-docker/frontend
cd server-monitor-docker
Populate Files:
Place the code files (Dockerfile, requirements.txt, run.py, backend/app.py, backend/collectors.py, frontend/index.html) into their respective directories as outlined in the "Project Structure" section.
(Ensure you have the correct versions of these files.)
Navigate to the root of the project directory (server-monitor-docker/) in your terminal and run:
docker build -t server-monitor-app .
This command builds a Docker image tagged as server-monitor-app using the Dockerfile in the current directory.
To run the container with default settings (2-second polling, monitoring container's root filesystem, and dummy logs generated by the application):
docker run -d -p 5000:5000 --name live-server-monitor --init server-monitor-app
-d: Run in detached mode (background).-p 5000:5000: Map port 5000 of the host to port 5000 of the container (Flask app default port).--name live-server-monitor: Assign a name to the container for easier management.--init: Runs an init process as PID 1 in the container, which helps manage signals and zombie processes. Recommended for applications like this.You can customize the monitor's behavior using environment variables and Docker volume mounts:
Environment Variables:
POLLING_INTERVAL_MS: Data refresh interval in milliseconds (e.g., 1000 for 1 second, 5000 for 5 seconds). Default: 2000. Minimum effective interval is around 500ms.STORAGE_PATHS: Comma-separated list of absolute paths inside the container to monitor for storage usage. Example: STORAGE_PATHS="/,/mnt/data,/mnt/backups". If not set, defaults to /host_root if it exists, otherwise /.LOG_CONFIG: Comma-separated list of Name:Path pairs for log files to monitor. Name is the display name in the UI, Path is the absolute path inside the container. Example: LOG_CONFIG="Syslog:/var/log/syslog_host,App Log:/app/my_app_host.log". If not set, defaults to dummy logs created by the application.FLASK_DEBUG: Set to 1 for Flask debug mode, 0 for production. Default is 0 as set in the Dockerfile. run.py uses this to toggle debug mode for socketio.run.FLASK_RUN_HOST: Host for the Flask app. Default is 0.0.0.0 as set in Dockerfile.FLASK_RUN_PORT: Port for the Flask app. Default is 5000 as set in Dockerfile.Volume Mounts (for monitoring host system resources):
STORAGE_PATHS.LOG_CONFIG.Example: Advanced Run Command
This example runs the monitor with:
/) and /mnt/important_data directories for storage./var/log/syslog and /var/log/auth.log.docker run -d \
-p 5000:5000 \
--name live-server-monitor \
--init \
-e POLLING_INTERVAL_MS=3000 \
-e STORAGE_PATHS="/host_root,/host_data" \
-e LOG_CONFIG="Host Syslog:/mnt/logs/syslog,Host Auth Log:/mnt/logs/auth.log" \
-v /:/host_root:ro \
-v /mnt/important_data:/host_data:ro \
-v /var/log/syslog:/mnt/logs/syslog:ro \
-v /var/log/auth.log:/mnt/logs/auth.log:ro \
server-monitor-app
:ro makes the mounted volumes read-only from the container's perspective, which is recommended for monitoring to prevent accidental changes to host files.Once the container is running, open your web browser and navigate to:
http://localhost:5000
(If running Docker on a remote machine or VM, replace localhost with the machine's IP address).
Set the POLLING_INTERVAL_MS environment variable during docker run.
Example: -e POLLING_INTERVAL_MS=1000 for 1-second updates. The minimum effective interval is around 500ms due to backend and frontend constraints.
-v /host/path:/container/path:ro Docker run option to mount the desired host storage directories.STORAGE_PATHS environment variable to a comma-separated list of the container paths you've mapped.
Example: -v /data/drive1:/mnt/drive1_data:ro -e STORAGE_PATHS="/,/mnt/drive1_data"-v /host/logfile.log:/container/logfile.log:ro Docker run option to mount the desired host log files.LOG_CONFIG environment variable.
Example: -v /var/log/my_app.log:/applogs/app.log:ro -e LOG_CONFIG="My Application Log:/applogs/app.log"frontend/index.html. You can modify these classes to change the appearance.<style> section of frontend/index.html. Adjust these variables (e.g., --bg-color-primary, --text-color-accent) to change the theme.frontend/index.html, specifically in the createTimeSeriesChart function and where charts are initialized.backend/collectors.py): If you need to add new metrics or change how existing ones are collected, this is the primary file to modify. It uses the psutil library extensively.backend/app.py): This file handles the Flask routes, Socket.IO events, and manages the background thread for emitting stats. Modifications here would be for changing API behavior or WebSocket communication. The eventlet.monkey_patch() is crucial and is called in run.py.The current radeontop integration is a basic placeholder that attempts to run radeontop -l 1 -d - and parse its text output.
To enable or improve it:
radeontop in Docker: Ensure radeontop is included in the apt-get install command in your Dockerfile.--device flags during docker run (e.g., --device=/dev/dri/card0 --device=/dev/kfd). This can be hardware-specific.radeontop.backend/collectors.py:
get_radeontop_data() function.subprocess.run to execute radeontop and includes a basic parser parse_radeontop_single_line_output for a specific output format. You might need to adjust the radeontop command options or the parsing logic (parse_radeontop_single_line_output) depending on your radeontop version and the desired metrics.radeontop versions.Monitoring NVIDIA GPUs typically requires using NVIDIA's own tools, primarily nvidia-smi (NVIDIA System Management Interface).
Conceptual Steps to Add NVIDIA GPU Monitoring:
nvidia/cuda:tag-base) as these come with necessary drivers and libraries.nvidia-smi is accessible within the container, which might involve installing NVIDIA drivers and utilities. This is complex and error-prone; the NVIDIA Container Toolkit on the host is the preferred way as it makes GPUs available to standard containers.backend/collectors.py:
get_nvidia_gpu_data().subprocess.run to execute nvidia-smi commands.
nvidia-smi --query-gpu=timestamp,name,temperature.gpu,utilization.gpu,utilization.memory,memory.total,memory.used,memory.free --format=csv,noheader,nounitsnvidia-smi.backend/app.py:
get_nvidia_gpu_data() within get_all_stats() and add its output to the current_stats dictionary.frontend/index.html:
--gpus all flag (or specify particular GPUs) if using the NVIDIA Container Toolkit.docker run -d -p 5000:5000 --name live-server-monitor --init --gpus all server-monitor-app
Challenges:
nvidia-smi: While nvidia-smi offers CSV output, robust parsing is still needed.Container not starting/exiting immediately:
docker logs live-server-monitor (or your container name). Look for Python errors, issues with environment variables, or problems in run.py or backend/app.py during startup.CMD in your Dockerfile is correct (e.g., CMD ["python", "run.py"]).eventlet.monkey_patch() is called at the very beginning of run.py.No data on webpage / "Connection Error" / "Disconnected":
docker ps. If not listed, check docker ps -a and then docker logs <container_id_or_name>.docker logs live-server-monitor. Pay attention to errors from collectors.py or app.py.socket.io requests).5000 (or the port you've mapped) on the host or between your client machine and the Docker host.app.py is configured with cors_allowed_origins="*", which should generally prevent CORS issues. If you've modified this, ensure your frontend's origin is allowed.POLLING_INTERVAL_MS too low: If set extremely low (e.g., below 100ms), it might overload the server or client. The application enforces a minimum of 500ms.Incorrect storage/log paths:
-v): Ensure the host path exists and the container path matches what's used in STORAGE_PATHS or LOG_CONFIG. Paths are case-sensitive.-e): Verify STORAGE_PATHS and LOG_CONFIG are correctly formatted (comma-separated, Name:Path for logs).Dockerfile) has read access to the mounted volumes. The :ro flag helps prevent writes but read access is still needed./host_root or / for storage, and dummy logs for log files. Check backend/app.py logs for warnings about invalid configurations.Data not updating or updating erratically:
docker logs live-server-monitor for errors in the background_thread in backend/app.py or within get_all_stats in collectors.py.socketio.sleep() is used in the background_thread rather than time.sleep() for proper cooperative multitasking with eventlet. (This is correctly implemented in the provided app.py).CPU usage seems off or slow to update:
psutil.cpu_percent(interval=0.1) is used. A very short interval can sometimes be less accurate or slightly delayed. The polling interval of the app itself (POLLING_INTERVAL_MS) is the main driver for UI updates.Network rates are zero or incorrect:
get_network_traffic depends on the difference between two consecutive calls. The first data point will show 0 rates. Ensure the polling interval is not too short for meaningful deltas to be calculated.AMD GPU (Radeontop) section shows "Radeontop data not available" or error:
radeontop not installed: Add radeontop to apt-get install in Dockerfile.--device=/dev/dri/cardX and potentially --device=/dev/kfd with docker run.radeontop command or parsing error: Check the status message and raw output sample in the UI. The get_radeontop_data function in backend/collectors.py captures errors. You might need to adjust the command or the parse_radeontop_single_line_output function if your radeontop version has different output."Error creating dummy log" or "Error writing to or trimming dummy log":
/app/dummy_logX.log or that the filesystem is read-only where it's trying to write. The default Dockerfile should allow this, but custom base images or security settings might interfere.Contributions, issues, and feature requests are welcome!
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the GNU General Public License Version 3, 29 June 2007. You can find the full license text hereā .
Content type
Image
Digest
sha256:6538b93d2ā¦
Size
55.2 MB
Last updated
over 1 year ago
docker pull weasts/servermon-weast