diff --git a/src/metric/grafana/build/Dockerfile b/src/metric/grafana/build/Dockerfile new file mode 100644 index 0000000..640d40c --- /dev/null +++ b/src/metric/grafana/build/Dockerfile @@ -0,0 +1,65 @@ +FROM grafana/grafana:11.1.0 + +USER root + +# 安装必要的工具 +RUN apk add --no-cache \ + supervisor \ + net-tools \ + iputils \ + vim \ + bash + +# supervisor 日志目录 +RUN mkdir -p /var/log/supervisor + +# 设置 Grafana 基础路径环境变量 +ENV GRAFANA_BASE_PATH=/private/argus/metric/grafana + +# 设置用户和组ID环境变量 +ARG GRAFANA_UID=2133 +ARG GRAFANA_GID=2015 +ENV GRAFANA_UID=${GRAFANA_UID} +ENV GRAFANA_GID=${GRAFANA_GID} + +# 创建基本目录结构 +RUN mkdir -p /private/argus/etc \ + && mkdir -p /private/argus/metric/grafana/data \ + && mkdir -p /private/argus/metric/grafana/logs \ + && mkdir -p /private/argus/metric/grafana/plugins \ + && mkdir -p /private/argus/metric/grafana/provisioning/datasources \ + && mkdir -p /private/argus/metric/grafana/provisioning/dashboards \ + && mkdir -p /private/argus/metric/grafana/data/sessions \ + && mkdir -p /private/argus/metric/grafana/data/dashboards \ + && mkdir -p /private/argus/metric/grafana/config \ + && mkdir -p /etc/grafana \ + && mkdir -p /var/lib/grafana \ + && mkdir -p /var/log/grafana + +# 修改 Grafana 用户 UID/GID 并授权 +RUN deluser grafana && \ + addgroup -g ${GRAFANA_GID} grafana && \ + adduser -u ${GRAFANA_UID} -G grafana -s /bin/sh -D grafana && \ + chown -R grafana:grafana /var/lib/grafana /etc/grafana /var/log/grafana /private/argus + +# 复制配置文件到容器内临时位置 +COPY grafana.ini /tmp/grafana.ini +COPY datasources/datasources.yml /tmp/datasources.yml +COPY dashboards/dashboards.yml /tmp/dashboards.yml +COPY dashboards/default_dashboard.json /tmp/default_dashboard.json + +# supervisor 配置 +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf + +# 启动脚本 +COPY start-grafana-supervised.sh /usr/local/bin/start-grafana-supervised.sh +RUN chmod +x /usr/local/bin/start-grafana-supervised.sh + +# 确保配置文件权限正确 +RUN chown -R grafana:grafana /etc/grafana + +USER root + +EXPOSE 3000 + +ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf", "-n"] diff --git a/src/metric/grafana/build/README.md b/src/metric/grafana/build/README.md new file mode 100644 index 0000000..91ce864 --- /dev/null +++ b/src/metric/grafana/build/README.md @@ -0,0 +1,100 @@ +# Grafana 构建配置 + +基于 `grafana/grafana:11.1.0` 构建的自定义镜像,主要做了用户 ID 适配和配置自动化。 + +## 快速开始 + +```bash +# 构建镜像 +docker build -t argus-metric-grafana:1.0.0 . + +# 启动容器(主机网络模式) +docker run -d \ + --name grafana \ + --network=host \ + -v /private/argus:/private/argus \ + argus-metric-grafana:1.0.0 +``` + +访问:`http://localhost:3001/private/argus/metric/grafana/` +默认账号:`admin` / `admin` + +## 用户 ID 配置 + +镜像默认使用特殊的用户 ID 以适配主机权限: +- `GRAFANA_UID=2133` +- `GRAFANA_GID=2015` + +如果需要修改,构建时传入参数: + +```bash +docker build \ + --build-arg GRAFANA_UID=1000 \ + --build-arg GRAFANA_GID=1000 \ + -t argus-metric-grafana:1.0.0 . +``` + +## 配置说明 + +### 数据源配置 + +修改 `datasources/datasources.yml` 中的 Prometheus 地址: + +```yaml +datasources: + - name: Prometheus + type: prometheus + url: http://10.211.55.5:9090 # 改成你的 Prometheus 地址 + isDefault: true +``` + +**注意**:确保 Grafana 容器能访问到 Prometheus 服务,网络要通。 + +### Dashboard 导入 + +配置好数据源后,手动导入默认 dashboard: + +1. 登录 Grafana +2. 左侧菜单 → Dashboards → Import +3. 上传 `dashboards/default_dashboard.json` +4. 选择 Prometheus 数据源 +5. Import + +或者直接把 dashboard 放到持久化目录: + +```bash +cp dashboards/default_dashboard.json /private/argus/metric/grafana/provisioning/dashboards/ +``` + +重启容器会自动加载(因为 `dashboards.yml` 配置了自动扫描该目录)。 + +## 目录结构 + +持久化目录都在 `/private/argus` 下: + +``` +/private/argus/ +├── etc/ +│ └── grafana.metric.argus.com # 容器 IP 记录 +└── metric/grafana/ + ├── config/ + │ └── grafana.ini # 主配置文件 + ├── data/ # 数据库、会话等 + ├── logs/ # 日志 + ├── plugins/ # 插件 + └── provisioning/ + ├── datasources/ + │ └── datasources.yml # 数据源配置 + └── dashboards/ + ├── dashboards.yml # dashboard 配置 + └── *.json # dashboard JSON 文件 +``` + +## 启动流程 + +容器启动时 `start-grafana-supervised.sh` 会: + +1. 记录容器 IP 到 `/private/argus/etc/grafana.metric.argus.com` +2. 创建必要的目录 +3. 从 `/tmp/` 复制配置文件到持久化目录(首次启动或配置不存在时) +4. 用 `grafana:grafana` (UID:GID=2133:2015) 启动 Grafana 服务 \ No newline at end of file diff --git a/src/metric/grafana/build/dashboards/dashboards.yml b/src/metric/grafana/build/dashboards/dashboards.yml new file mode 100644 index 0000000..2fdff96 --- /dev/null +++ b/src/metric/grafana/build/dashboards/dashboards.yml @@ -0,0 +1,15 @@ +# 仪表板配置文件 +# 这个文件定义了仪表板的自动配置 + +apiVersion: 1 + +providers: + - name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + updateIntervalSeconds: 10 + allowUiUpdates: true + options: + path: /private/argus/metric/grafana/provisioning/dashboards diff --git a/src/metric/grafana/build/dashboards/default_dashboard.json b/src/metric/grafana/build/dashboards/default_dashboard.json new file mode 100644 index 0000000..416e8f8 --- /dev/null +++ b/src/metric/grafana/build/dashboards/default_dashboard.json @@ -0,0 +1,628 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 9, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Load", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 101, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "expr": "node_load1{instance=\"$instance\"}", + "legendFormat": "{{instance}} load1", + "refId": "A" + }, + { + "expr": "node_load5{instance=\"$instance\"}", + "legendFormat": "{{instance}} load5", + "refId": "B" + }, + { + "expr": "node_load15{instance=\"$instance\"}", + "legendFormat": "{{instance}} load15", + "refId": "C" + } + ], + "title": "System Load", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "expr": "100 * (1 - avg by(instance) (irate(node_cpu_seconds_total{mode=\"idle\",instance=\"$instance\"}[5m])))", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "%", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 70 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "expr": "100 * (1 - (node_memory_MemAvailable_bytes{instance=\"$instance\"} / node_memory_MemTotal_bytes{instance=\"$instance\"}))", + "legendFormat": "{{instance}}", + "refId": "B" + } + ], + "title": "Node Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Bytes/s", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "expr": "sum by(instance) (rate(node_disk_read_bytes_total{device!~\"^(loop|ram|sr0).*\",instance=\"$instance\"}[5m]))", + "legendFormat": "{{instance}} read", + "refId": "A" + }, + { + "expr": "sum by(instance) (rate(node_disk_written_bytes_total{device!~\"^(loop|ram|sr0).*\",instance=\"$instance\"}[5m]))", + "legendFormat": "{{instance}} write", + "refId": "B" + } + ], + "title": "Node Disk I/O (Bytes/s)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Bytes/s", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 102, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "expr": "sum by(instance)(rate(node_network_receive_bytes_total{device!~\"^(lo|docker.*)\",instance=\"$instance\"}[5m]))", + "legendFormat": "{{instance}} RX", + "refId": "A" + }, + { + "expr": "sum by(instance)(rate(node_network_transmit_bytes_total{device!~\"^(lo|docker.*)\",instance=\"$instance\"}[5m]))", + "legendFormat": "{{instance}} TX", + "refId": "B" + } + ], + "title": "Network Traffic", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Processes", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 200 + }, + { + "color": "red", + "value": 500 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 104, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "expr": "node_procs_running{instance=\"$instance\"}", + "legendFormat": "{{instance}} Running", + "refId": "A" + }, + { + "expr": "node_procs_blocked{instance=\"$instance\"}", + "legendFormat": "{{instance}} Blocked", + "refId": "B" + } + ], + "title": "Node Process Count", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "node-exporter-A1", + "value": "node-exporter-A1" + }, + "datasource": { + "type": "prometheus" + }, + "definition": "label_values(node_cpu_seconds_total,instance)", + "hide": 0, + "includeAll": false, + "label": "instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(node_cpu_seconds_total,instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "2025-09-30T02:47:28.390Z", + "to": "2025-09-30T07:33:49.405Z" + }, + "timepicker": {}, + "timezone": "", + "title": "Node and GPU Metrics", + "uid": "node_gpu_metrics", + "weekStart": "" + } \ No newline at end of file diff --git a/src/metric/grafana/build/datasources/datasources.yml b/src/metric/grafana/build/datasources/datasources.yml new file mode 100644 index 0000000..fb277cc --- /dev/null +++ b/src/metric/grafana/build/datasources/datasources.yml @@ -0,0 +1,26 @@ +# 数据源配置文件 +# 这个文件定义了所有数据源的配置 + +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + uid: eezk1zvkie4g0a + url: http://10.211.55.5:9090 + isDefault: true + editable: true + jsonData: + httpMethod: POST + manageAlerts: true + prometheusType: Prometheus + prometheusVersion: 2.40.0 + cacheLevel: 'High' + disableRecordingRules: false + incrementalQueryOverlapWindow: 10m + incrementalQuerying: false + queryTimeout: 60s + timeInterval: 15s + secureJsonData: {} + version: 1 diff --git a/src/metric/grafana/build/grafana.ini b/src/metric/grafana/build/grafana.ini new file mode 100644 index 0000000..fea2ada --- /dev/null +++ b/src/metric/grafana/build/grafana.ini @@ -0,0 +1,96 @@ +# Grafana 配置文件 +# 这个配置文件定义了 Grafana 的基本设置和 Prometheus 数据源配置 + +[paths] +data = /private/argus/metric/grafana/data +logs = /private/argus/metric/grafana/logs +plugins = /private/argus/metric/grafana/plugins +provisioning = /private/argus/metric/grafana/provisioning + +[server] +http_port = 3000 +domain = localhost +root_url = %(protocol)s://%(domain)s:%(http_port)s +serve_from_sub_path = true + +[database] +type = sqlite3 +path = /private/argus/metric/grafana/data/grafana.db + +[session] +provider = file +provider_config = /private/argus/metric/grafana/data/sessions +cookie_name = grafana_sess +cookie_secure = false +session_life_time = 86400 + +[analytics] +reporting_enabled = false +check_for_updates = false + +[security] +admin_user = admin +admin_password = admin +secret_key = SW2YcwTIb9zpOOhoPsMm + +[snapshots] +external_enabled = true + +[users] +allow_sign_up = false +auto_assign_org = true +auto_assign_org_role = Viewer +verify_email_enabled = false + +[log] +mode = console +level = info + +[log.console] +level = info +format = console + +[log.file] +level = info +format = text +log_rotate = true +max_lines = 1000000 +max_size_shift = 28 +daily_rotate = true +max_days = 7 +filename = /private/argus/metric/grafana/logs/grafana.log + +[quota] +enabled = false + +[unified_alerting] +enabled = true + +[explore] +enabled = true + +[panels] +disable_sanitize_html = false + +[plugins] +enable_alpha = false +app_tls_skip_verify_insecure = false + +[enterprise] +license_path = + +[feature_toggles] +enable = + +[date_formats] +default_timezone = browser +full_date = YYYY-MM-DD HH:mm:ss +interval_second = HH:mm:ss +interval_minute = HH:mm +interval_hour = MM/DD HH:mm +interval_day = MM/DD +interval_month = YYYY-MM +interval_year = YYYY + +[expressions] +enabled = true diff --git a/src/metric/grafana/build/start-grafana-supervised.sh b/src/metric/grafana/build/start-grafana-supervised.sh new file mode 100644 index 0000000..5d4b8a1 --- /dev/null +++ b/src/metric/grafana/build/start-grafana-supervised.sh @@ -0,0 +1,97 @@ +#!/bin/bash +set -euo pipefail + +echo "[INFO] Starting Grafana under supervisor..." + +DOMAIN=grafana.metric.argus.com + +# 记录容器 IP +IP=$(ifconfig | awk '/inet / && $2 != "127.0.0.1" {print $2; exit}') +echo "current IP: ${IP}" +echo "${IP}" > /private/argus/etc/${DOMAIN} + +# 确保必要目录存在(权限已在 Dockerfile 中设置) +mkdir -p /private/argus/metric/grafana/data +mkdir -p /private/argus/metric/grafana/logs +mkdir -p /private/argus/metric/grafana/plugins +mkdir -p /private/argus/metric/grafana/provisioning/datasources +mkdir -p /private/argus/metric/grafana/provisioning/dashboards +mkdir -p /private/argus/metric/grafana/data/sessions +mkdir -p /private/argus/metric/grafana/data/dashboards +mkdir -p /private/argus/metric/grafana/config +mkdir -p /var/log/grafana +mkdir -p /etc/grafana/provisioning/datasources +mkdir -p /var/lib/grafana + +# 复制主配置文件到持久化目录 +if [ -f "/tmp/grafana.ini" ]; then + echo "[INFO] Copying grafana.ini to /private/argus/metric/grafana/config/" + cp /tmp/grafana.ini /private/argus/metric/grafana/config/grafana.ini + chown grafana:grafana /private/argus/metric/grafana/config/grafana.ini + echo "[INFO] Grafana configuration copied successfully" +fi + +# 检查配置文件来源(优先级:挂载目录 > 容器内配置 > 默认配置) +if [ -f "/private/argus/metric/grafana/config/grafana.ini" ]; then + echo "[INFO] Using grafana.ini from /private/argus/metric/grafana/config/" + CONFIG_FILE="--config=/private/argus/metric/grafana/config/grafana.ini" +elif [ -f "/etc/grafana/grafana.ini" ]; then + echo "[INFO] Using custom grafana.ini from /etc/grafana/" + CONFIG_FILE="--config=/etc/grafana/grafana.ini" +else + echo "[INFO] Using default configuration" + CONFIG_FILE="" +fi + +# 复制数据源配置文件到挂载目录 +if [ -f "/tmp/datasources.yml" ]; then + echo "[INFO] Copying datasource configuration to /private/argus/metric/grafana/provisioning/datasources/" + cp /tmp/datasources.yml /private/argus/metric/grafana/provisioning/datasources/datasources.yml + chown grafana:grafana /private/argus/metric/grafana/provisioning/datasources/datasources.yml + echo "[INFO] Datasource configuration copied successfully" +elif [ -d "/private/argus/metric/grafana/provisioning/datasources" ] && [ "$(ls -A /private/argus/metric/grafana/provisioning/datasources)" ]; then + echo "[INFO] Found existing datasource provisioning files in /private/argus/metric/grafana/provisioning/datasources" + # 确保数据源配置目录权限正确 + chown -R grafana:grafana /private/argus/metric/grafana/provisioning/datasources +elif [ -d "/etc/grafana/provisioning/datasources" ] && [ "$(ls -A /etc/grafana/provisioning/datasources)" ]; then + echo "[INFO] Found datasource provisioning files in /etc/grafana/provisioning/datasources" + # 确保数据源配置目录权限正确 + chown -R grafana:grafana /etc/grafana/provisioning/datasources +else + echo "[INFO] No datasource provisioning files found, using manual configuration" +fi + +# 复制仪表板配置文件到挂载目录 +if [ -f "/tmp/dashboards.yml" ]; then + echo "[INFO] Copying dashboard configuration to /private/argus/metric/grafana/provisioning/dashboards/" + cp /tmp/dashboards.yml /private/argus/metric/grafana/provisioning/dashboards/dashboards.yml + chown grafana:grafana /private/argus/metric/grafana/provisioning/dashboards/dashboards.yml + echo "[INFO] Dashboard configuration copied successfully" +fi + +# 复制默认仪表板到挂载目录 +if [ -f "/tmp/default_dashboard.json" ]; then + echo "[INFO] Copying default dashboard to /private/argus/metric/grafana/provisioning/dashboards/" + cp /tmp/default_dashboard.json /private/argus/metric/grafana/provisioning/dashboards/default_dashboard.json + chown grafana:grafana /private/argus/metric/grafana/provisioning/dashboards/default_dashboard.json + echo "[INFO] Default dashboard copied successfully" +fi + +# 确保所有配置目录权限正确 +chown -R grafana:grafana /private/argus/metric/grafana/provisioning/ + +# 启动 Grafana +if [ -n "$CONFIG_FILE" ]; then + echo "[INFO] Starting Grafana with custom configuration..." + exec /usr/share/grafana/bin/grafana server \ + --homepath=/usr/share/grafana \ + --packaging=docker \ + $CONFIG_FILE +else + echo "[INFO] Starting Grafana with default configuration..." + exec /usr/share/grafana/bin/grafana server \ + --homepath=/usr/share/grafana \ + --packaging=docker \ + cfg:default.log.mode=console \ + cfg:default.log.level=info +fi diff --git a/src/metric/grafana/build/supervisord.conf b/src/metric/grafana/build/supervisord.conf new file mode 100644 index 0000000..6b39c1d --- /dev/null +++ b/src/metric/grafana/build/supervisord.conf @@ -0,0 +1,28 @@ +[supervisord] +nodaemon=true +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid +user=root +sockfile=/var/run/supervisor.sock + +[program:grafana] +command=/usr/local/bin/start-grafana-supervised.sh +user=grafana +stdout_logfile=/var/log/supervisor/grafana.log +stderr_logfile=/var/log/supervisor/grafana_error.log +autorestart=true +startretries=3 +startsecs=30 +stopwaitsecs=30 +killasgroup=true +stopasgroup=true + +[unix_http_server] +file=/var/run/supervisor.sock +chmod=0700 + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface