diff --git a/README.md b/README.md index 91daef2..163f83a 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,70 @@ -# 数据可视化展示大屏 +# PromdataPanel -多源 Prometheus 服务器监控展示大屏,支持对接多个 Prometheus 实例,实时展示所有服务器的 CPU、内存、磁盘、网络等关键指标。 +多源 Prometheus 服务器监控展示大屏。支持对接多个 Prometheus 实例,实时聚合展示所有服务器的 CPU、内存、磁盘、带宽等关键指标,并提供可视化节点分布图。 ## 功能特性 -- 🔌 **多数据源管理** - MySQL 存储配置,支持对接多个 Prometheus 实例 -- 📊 **NodeExporter 数据查询** - 自动聚合所有 Prometheus 中的 NodeExporter 数据 -- 🌐 **网络流量统计** - 24 小时网络流量趋势图,总流量统计 -- ⚡ **实时带宽监控** - 所有服务器网络带宽求和,实时显示 -- 💻 **资源使用概览** - CPU、内存、磁盘的总使用率和详细统计 -- 🖥️ **服务器列表** - 所有服务器的详细指标一览表 +- 🔌 **多数据源管理** - 支持对接多个 Prometheus 实例(Node_Exporter / BlackboxExporter) +- 📊 **指标自动聚合** - 自动汇总所有数据源的 NodeExporter 指标,实时计算全网负载 +- 🌐 **网络流量统计** - 24 小时流量趋势图,实时带宽(Rx/Tx)求和显示 +- 🗺️ **节点分布可视化** - 自动识别服务器地理位置,并在全球地图上展示实时连接状态与延迟 +- ⚡ **毫秒级实时性** - 深度优化查询逻辑,支持 5s 采集频率的实时动态展示 +- 📱 **响应式与美学设计** - 现代 UI/UX 体验,支持暗色模式,极致性能优化 -## 快速开始 +## 快速安装 -### 1. 环境要求 +### 方式一:一键脚本安装 (推荐) -- Node.js >= 16 -- MySQL >= 5.7 -- Valkey >= 7.0 (或 Redis >= 6.0) - -### 2. 配置 - -复制环境变量文件并修改: +在 Linux 服务器上,您可以使用以下脚本一键完成下载、环境检测、依赖安装并将其注册为 Systemd 系统服务: ```bash -cp .env.example .env +# 下载安装最新版本 (默认 v0.1.0) +VERSION=v0.1.0 curl -sSL https://git.littlediary.cn/CN-JS-HuiBai/PromdataPanel/raw/branch/master/install.sh | bash ``` -编辑 `.env` 文件,配置 MySQL 和 Valkey 连接信息: +### 方式二:手动安装 -```env -# MySQL 配置 -MYSQL_HOST=localhost -MYSQL_PORT=3306 -MYSQL_USER=root -MYSQL_PASSWORD=your_password -MYSQL_DATABASE=display_wall +#### 1. 环境要求 +- **Node.js** >= 18 +- **MySQL** >= 8.0 +- **Valkey** >= 7.0 (或 Redis >= 6.0) -# Valkey/Redis 缓存配置 (可选) -VALKEY_HOST=localhost -VALKEY_PORT=6379 -VALKEY_PASSWORD= -VALKEY_TTL=30 +#### 2. 配置与启动 +1. 克隆代码库:`git clone https://git.littlediary.cn/CN-JS-HuiBai/PromdataPanel.git` +2. 复制配置文件:`cp .env.example .env` +3. 安装依赖:`npm install --production` +4. 启动服务:`npm start` -PORT=3000 -``` +#### 3. 系统初始化 +首次运行后,访问 `http://your-ip:3000/init.html`,按照引导完成 MySQL 数据库和 Valkey 缓存的连接。 -### 3. 系统初始化 +## 使用指引 -访问 `http://localhost:3000/init.html`,按照引导完成数据库和缓存的初始化。 +### 1. 添加 Prometheus 数据源 +点击页面右上角的 ⚙️ 按钮进入设置,添加并测试您的 Prometheus HTTP 地址。 -### 4. 安装依赖并启动 - -```bash -npm install -npm run dev -``` - -访问 `http://localhost:3000` 即可看到展示大屏。 - -### 5. 配置 Prometheus 数据源 - -点击右上角的 ⚙️ 按钮,添加你的 Prometheus 地址(如 `http://prometheus.example.com:9090`)。 - -### 6. Prometheus 配置参考 (Example) - -在您的 Prometheus 配置文件 `prometheus.yml` 中,建议执行以下配置(`scrape_interval` 建议设为 `5s` 以获取最佳实时展示效果): +### 2. Prometheus 采集配置 +建议在 `prometheus.yml` 中设置采集周期为 `5s` 以实现平滑的实时动态效果: ```yaml global: scrape_interval: 5s -scrape_configs: - - job_name: '机器名称' - static_configs: - - targets: ['IP:Port'] -``` +scrape_configs: + - job_name: 'nodes' + static_configs: + - targets: ['your-server-ip:9100'] +``` ## 技术栈 -- **后端**: Node.js + Express -- **数据库**: MySQL (存储配置数据) -- **缓存**: Valkey / Redis (用于加速流量计算结果读取) -- **数据源**: Prometheus HTTP API -- **前端**: 原生 HTML/CSS/JavaScript -- **图表**: 自定义 Canvas 渲染 +- **Runtime**: Node.js +- **Framework**: Express.js +- **Database**: MySQL 8.0+ +- **Caching**: Valkey / Redis +- **Visualization**: ECharts / Canvas +- **Frontend**: Vanilla JS / CSS3 -## API 接口 +## LICENSE -| 方法 | 路径 | 说明 | -|------|------|------| -| GET | `/api/sources` | 获取所有数据源 | -| POST | `/api/sources` | 添加数据源 | -| PUT | `/api/sources/:id` | 更新数据源 | -| DELETE | `/api/sources/:id` | 删除数据源 | -| POST | `/api/sources/test` | 测试数据源连接 | -| GET | `/api/metrics/overview` | 获取聚合指标概览 | -| GET | `/api/metrics/network-history` | 获取24h网络流量历史 | -| GET | `/api/metrics/cpu-history` | 获取CPU使用率历史 | +MIT License diff --git a/install.sh b/install.sh index 802fa9c..d8d2204 100644 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/bash -# Data Visualization Display Wall - Systemd Installer -# Requirements: Node.js, NPM, Systemd (Linux) +# PromdataPanel - Multi-Prometheus Monitoring Dashboard Installer +# This script handles OS detection, Node.js installation, project setup, and Systemd configuration. # Colors for output RED='\033[0;31m' @@ -10,69 +10,148 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color -echo -e "${BLUE}=== Data Visualization Display Wall Installer ===${NC}" +# 0. Configuration +VERSION=${VERSION:-"v0.1.0"} +DOWNLOAD_URL="https://git.littlediary.cn/CN-JS-HuiBai/PromdataPanel/archive/${VERSION}.zip" +MIN_NODE_VERSION=18 -# 1. Permission check (no longer mandatory) +echo -e "${BLUE}================================================${NC}" +echo -e "${BLUE} PromdataPanel Auto-Installer ${NC}" +echo -e "${BLUE} Version: ${VERSION} ${NC}" +echo -e "${BLUE}================================================${NC}" + +# 1. OS Detection +detect_os() { + if [ -f /etc/os-release ]; then + . /etc/os-release + OS_ID=$ID + OS_VER=$VERSION_ID + else + echo -e "${RED}Error: Cannot detect operating system type (/etc/os-release missing).${NC}" + exit 1 + fi + echo -e "Detected OS: ${GREEN}${OS_ID} ${OS_VER}${NC}" +} + +# 2. Node.js Installation/Verification +install_node() { + echo -e "${BLUE}Verifying Node.js environment...${NC}" + + NODE_INSTALLED=false + if command -v node &> /dev/null; then + CURRENT_NODE_VER=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) + if [ "$CURRENT_NODE_VER" -ge "$MIN_NODE_VERSION" ]; then + echo -e "${GREEN}Node.js v$(node -v) is already installed.${NC}" + NODE_INSTALLED=true + else + echo -e "${YELLOW}Existing Node.js version (v$(node -v)) is too old (Requires >= $MIN_NODE_VERSION).${NC}" + fi + fi + + if [ "$NODE_INSTALLED" = false ]; then + echo -e "${BLUE}Installing Node.js 20.x...${NC}" + case "$OS_ID" in + ubuntu|debian|raspbian) + sudo apt-get update + sudo apt-get install -y ca-certificates curl gnupg + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs + ;; + centos|rhel|almalinux|rocky) + curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - + sudo yum install -y nodejs + ;; + fedora) + curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - + sudo dnf install -y nodejs + ;; + *) + echo -e "${RED}Unsupported OS for automatic Node.js installation: $OS_ID${NC}" + echo -e "Please install Node.js >= 18 manually.${NC}" + exit 1 + ;; + esac + fi +} + +# 3. Download and Extract (If needed) +if [ ! -f "server/index.js" ]; then + echo -e "${YELLOW}Project files not found. Starting download...${NC}" + + if ! command -v curl &> /dev/null; then + echo -e "${BLUE}Installing curl...${NC}" + [ "$OS_ID" = "ubuntu" ] || [ "$OS_ID" = "debian" ] && sudo apt-get install -y curl + [ "$OS_ID" = "centos" ] || [ "$OS_ID" = "rhel" ] && sudo yum install -y curl + fi + + if ! command -v unzip &> /dev/null; then + echo -e "${BLUE}Installing unzip...${NC}" + [ "$OS_ID" = "ubuntu" ] || [ "$OS_ID" = "debian" ] && sudo apt-get install -y unzip + [ "$OS_ID" = "centos" ] || [ "$OS_ID" = "rhel" ] && sudo yum install -y unzip + fi + + TEMP_ZIP="promdatapanel_${VERSION}.zip" + echo -e "${BLUE}Downloading ${DOWNLOAD_URL}...${NC}" + curl -L "$DOWNLOAD_URL" -o "$TEMP_ZIP" + + if [ $? -ne 0 ]; then + echo -e "${RED}Download failed.${NC}" + exit 1 + fi + + echo -e "${BLUE}Extracting files...${NC}" + unzip -q "$TEMP_ZIP" + + EXTRACTED_DIR=$(ls -d */ | grep -E "^PromdataPanel" | head -n 1) + if [ -d "$EXTRACTED_DIR" ]; then + cd "$EXTRACTED_DIR" || exit 1 + else + EXTRACTED_DIR=$(ls -d */ | head -n 1) + [ -d "$EXTRACTED_DIR" ] && cd "$EXTRACTED_DIR" || exit 1 + fi + rm "../$TEMP_ZIP" 2>/dev/null || rm "$TEMP_ZIP" 2>/dev/null +fi + +# 4. Initialize Setup +# Permission check if [ "$EUID" -eq 0 ]; then - # If run as sudo, get the real user that called it REAL_USER=${SUDO_USER:-$USER} else REAL_USER=$USER fi -# 2. Get current directory and user -PROJECT_DIR=$(pwd) -USER_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6) +detect_os +install_node +PROJECT_DIR=$(pwd) echo -e "Project Directory: ${GREEN}$PROJECT_DIR${NC}" echo -e "Running User: ${GREEN}$REAL_USER${NC}" -# 3. Check for mandatory files -if [ ! -f "server/index.js" ]; then - echo -e "${RED}Error: server/index.js not found. Please run this script from the project root.${NC}" - exit 1 -fi - -# 4. Check for dependencies -echo -e "${BLUE}Checking dependencies...${NC}" -check_dep() { - if ! command -v "$1" &> /dev/null; then - echo -e "${RED}$1 is not installed. Please install $1 first.${NC}" - exit 1 - fi -} -check_dep node -check_dep npm - -# 5. Check for .env file +# Check for .env file if [ ! -f ".env" ]; then - echo -e "${YELLOW}Warning: .env file not found.${NC}" if [ -f ".env.example" ]; then - echo -e "Creating .env from .env.example..." + echo -e "${BLUE}Creating .env from .env.example...${NC}" cp .env.example .env - echo -e "${GREEN}Created .env file. Please ensure values are correct.${NC}" - else - echo -e "${RED}Error: .env.example not found. Configuration missing.${NC}" fi fi -# 6. Install NPM dependencies -echo -e "${BLUE}Installing dependencies...${NC}" -npm install +# 5. Install Dependencies +echo -e "${BLUE}Installing NPM dependencies...${NC}" +npm install --production if [ $? -ne 0 ]; then echo -e "${RED}NPM install failed.${NC}" exit 1 fi -# 7. Create Systemd Service File +# 6. Create Systemd Service File SERVICE_FILE="/etc/systemd/system/promdatapanel.service" NODE_PATH=$(command -v node) -echo -e "${BLUE}Creating systemd service at $SERVICE_FILE... (May require password)${NC}" +echo -e "${BLUE}Creating systemd service at $SERVICE_FILE...${NC}" sudo bash -c "cat < '$SERVICE_FILE' [Unit] -Description=Data Visualization Display Wall +Description=PromdataPanel Monitoring Dashboard After=network.target mysql.service redis-server.service valkey-server.service Wants=mysql.service @@ -86,153 +165,33 @@ RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=promdatapanel -# Pass environment via .env file injection EnvironmentFile=-$PROJECT_DIR/.env Environment=NODE_ENV=production -# Security Hardening -CapabilityBoundingSet= -NoNewPrivileges=true -LimitNOFILE=65535 - [Install] WantedBy=multi-user.target EOF" -# 8. Reload Systemd and Start -echo -e "${BLUE}Reloading systemd and restarting service... (May require password)${NC}" +# 7. Reload and Start +echo -e "${BLUE}Reloading systemd and restarting service...${NC}" sudo systemctl daemon-reload sudo systemctl enable promdatapanel sudo systemctl restart promdatapanel -# 9. Check Status +# 8. Check Status echo -e "${BLUE}Checking service status...${NC}" sleep 2 if sudo systemctl is-active --quiet promdatapanel; then - echo -e "${GREEN}SUCCESS: Service is now running.${NC}" + echo -e "${GREEN}SUCCESS: PromdataPanel is now running.${NC}" PORT=$(grep "^PORT=" .env | cut -d'=' -f2) PORT=${PORT:-3000} - echo -e "Dashboard URL: ${YELLOW}http://localhost:${PORT}${NC}" - echo -e "View logs: ${BLUE}journalctl -u promdatapanel -f${NC}" + IP_ADDR=$(hostname -I | awk '{print $1}') + echo -e "Dashboard URL: ${YELLOW}http://${IP_ADDR}:${PORT}${NC}" else echo -e "${RED}FAILED: Service failed to start.${NC}" echo -e "Check logs with: ${BLUE}journalctl -u promdatapanel -xe${NC}" fi -# 10. Reverse Proxy Configuration -echo -ne "${YELLOW}Do you want to configure a reverse proxy (Nginx/Caddy)? (y/n): ${NC}" -read -r CONF_PROXY -if [[ "$CONF_PROXY" =~ ^[Yy]$ ]]; then - echo -e "${BLUE}=== Reverse Proxy Configuration ===${NC}" - - # Get Domain - echo -ne "Enter your domain name (e.g., monitor.example.com): " - read -r DOMAIN - if [ -z "$DOMAIN" ]; then - echo -e "${RED}Error: Domain cannot be empty. Skipping proxy configuration.${NC}" - else - # Get Port from .env - PORT=$(grep "^PORT=" .env | cut -d'=' -f2) - PORT=${PORT:-3000} - - # Choose Proxy - echo -e "Select Proxy Type:" - echo -e " 1) Caddy (Automatic SSL, easy to use)" - echo -e " 2) Nginx (Advanced, manual SSL)" - echo -ne "Choose (1/2): " - read -r PROXY_TYPE - - # Enable HTTPS? - echo -ne "Enable HTTPS (SSL)? (y/n): " - read -r ENABLE_HTTPS - - if [ "$PROXY_TYPE" == "1" ]; then - # Caddy Config - CADDY_FILE="Caddyfile" - echo -e "${BLUE}Generating Caddyfile...${NC}" - - if [[ "$ENABLE_HTTPS" =~ ^[Yy]$ ]]; then - cat < "$CADDY_FILE" -$DOMAIN { - reverse_proxy localhost:$PORT -} -EOF - else - cat < "$CADDY_FILE" -http://$DOMAIN { - reverse_proxy localhost:$PORT -} -EOF - fi - echo -e "${GREEN}Caddyfile generated at $PROJECT_DIR/$CADDY_FILE${NC}" - echo -e "${YELLOW}Tip: Ensure Caddy is installed and pointing to this file.${NC}" - - elif [ "$PROXY_TYPE" == "2" ]; then - # Nginx Config - echo -ne "Enter Nginx configuration export path (default: ./${DOMAIN}.conf): " - read -r NGINX_PATH - NGINX_PATH=${NGINX_PATH:-"./${DOMAIN}.conf"} - - echo -e "${BLUE}Generating Nginx configuration...${NC}" - - if [[ "$ENABLE_HTTPS" =~ ^[Yy]$ ]]; then - echo -ne "Enter SSL Certificate Path: " - read -r SSL_CERT - echo -ne "Enter SSL Key Path: " - read -r SSL_KEY - - cat < "$NGINX_PATH" -server { - listen 80; - server_name $DOMAIN; - return 301 https://\$host\$request_uri; -} - -server { - listen 443 ssl http2; - server_name $DOMAIN; - - ssl_certificate $SSL_CERT; - ssl_certificate_key $SSL_KEY; - - location / { - proxy_pass http://localhost:$PORT; - proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - } -} -EOF - else - cat < "$NGINX_PATH" -server { - listen 80; - server_name $DOMAIN; - - location / { - proxy_pass http://localhost:$PORT; - proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto \$scheme; - } -} -EOF - fi - echo -e "${GREEN}Nginx config generated at $NGINX_PATH${NC}" - echo -e "${YELLOW}Tip: You can symlink this to /etc/nginx/sites-enabled/ to activate.${NC}" - else - echo -e "${YELLOW}Unknown proxy type selected. Skipping.${NC}" - fi - fi -fi - echo -e "${BLUE}================================================${NC}" -echo -e "${GREEN}Setup completed successfully!${NC}" +echo -e "${GREEN}Installation completed!${NC}" +echo -e "${BLUE}================================================${NC}" diff --git a/package.json b/package.json index 3752419..62b122b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "data-visualization-display-wall", + "name": "promdatapanel", "version": "1.0.0", "description": "Data Visualization Display Wall - Multi-Prometheus Monitoring Dashboard", "main": "server/index.js",