diff --git a/README.md b/README.md index 49fdab8..b96c68a 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,9 @@ cookies: ![image](https://github.com/hr3lxphr6j/bililive-go/raw/master/docs/dashboard.webp) +增加说明 +[grafana](docs/grafana.md) + ## 依赖 * [ffmpeg](https://ffmpeg.org/) diff --git a/dashbord.json b/contrib/grafana/dashboard.json similarity index 100% rename from dashbord.json rename to contrib/grafana/dashboard.json diff --git a/contrib/grafana/provisioning/dashboards/bilipanel.json b/contrib/grafana/provisioning/dashboards/bilipanel.json new file mode 100644 index 0000000..b6482c2 --- /dev/null +++ b/contrib/grafana/provisioning/dashboards/bilipanel.json @@ -0,0 +1,415 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "yellow", + "index": 1, + "text": "摸" + }, + "1": { + "color": "green", + "index": 0, + "text": "播" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 0 + }, + "hideTimeOverride": true, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value_and_name" + }, + "pluginVersion": "10.0.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "bgo_live_status{instance=~\"$instance\", live_host_name=~\"$anchor\"}", + "instant": true, + "interval": "", + "legendFormat": "{{live_host_name}}", + "refId": "A" + } + ], + "timeFrom": "1m", + "title": "Live Status", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 16, + "x": 8, + "y": 0 + }, + "hideTimeOverride": true, + "id": 8, + "interval": "1m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value_and_name" + }, + "pluginVersion": "10.0.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": false, + "expr": "sum by(live_host_name)(increase(bgo_live_duration_seconds{instance=~\"$instance\", live_host_name=~\"$anchor\"}[30d]))", + "interval": "", + "legendFormat": "{{live_host_name}}", + "refId": "A" + } + ], + "timeFrom": "30d", + "title": "Length of live stream in the past 30 days", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 3, + "x": 0, + "y": 10 + }, + "hideTimeOverride": true, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value_and_name" + }, + "pluginVersion": "10.0.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "bgo_recorder_total_bytes{instance=~\"$instance\", live_host_name=~\"$anchor\"}", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "{{live_host_name}}", + "refId": "A" + } + ], + "title": "Output File Size", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 21, + "x": 3, + "y": 10 + }, + "hideTimeOverride": false, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "irate(bgo_recorder_total_bytes{instance=~\"$instance\", live_host_name=~\"$anchor\"}[$__interval])", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{live_host_name}}", + "refId": "A" + } + ], + "title": "Live Bitrate", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": ".*", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "definition": "bgo_live_status", + "description": "bililive instance name", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "instance", + "options": [], + "query": { + "query": "bgo_live_status", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "/instance=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "definition": "bgo_live_status", + "description": "anchor name", + "hide": 0, + "includeAll": true, + "label": "", + "multi": true, + "name": "anchor", + "options": [], + "query": { + "query": "bgo_live_status", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "/live_host_name=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Bililive Dashboards", + "uid": "iXqlPlBnkp", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/contrib/grafana/provisioning/dashboards/dashboard.yml b/contrib/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 0000000..d83b43c --- /dev/null +++ b/contrib/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: + - name: 'Prometheus' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + allowUiUpdates: true + options: + path: /etc/grafana/provisioning/dashboards \ No newline at end of file diff --git a/contrib/grafana/provisioning/datasources/datasource.yml b/contrib/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000..bb37f13 --- /dev/null +++ b/contrib/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: true + editable: true \ No newline at end of file diff --git a/contrib/prometheus/prometheus.yml b/contrib/prometheus/prometheus.yml new file mode 100644 index 0000000..92978bd --- /dev/null +++ b/contrib/prometheus/prometheus.yml @@ -0,0 +1,25 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: "bililive" + static_configs: + - targets: ["bililive-go:8080"] + metrics_path: "/api/metrics" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..63549b6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +version: "3.7" + +volumes: + prometheus_data: {} +services: + bililive-go: + image: chigusa/bililive-go + restart: unless-stopped + container_name: bililive-go + volumes: + - ./Videos:/srv/bililive + ports: + - 8080:8080 + + prometheus: + image: quay.io/prometheus/prometheus + restart: unless-stopped + container_name: bililive-prom + volumes: + - prometheus_data:/prometheus + - ./contrib/prometheus:/etc/prometheus + command: + # retention 建议大于30天 + - '--storage.tsdb.retention.time=30d' + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + - '--web.console.templates=/usr/share/prometheus/consoles' + ports: + - 9090:9090 + + grafana: + image: grafana/grafana-oss + restart: unless-stopped + container_name: bililive-graf + volumes: + - ./contrib/grafana/provisioning:/etc/grafana/provisioning + environment: + - GF_SECURITY_ADMIN_USER=${ADMIN_USER} + - GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD} + - GF_USERS_ALLOW_SIGN_UP=false + - GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH=/etc/grafana/provisioning/dashboards/bilipanel.json + ports: + - 3000:3000 diff --git a/docs/grafana.md b/docs/grafana.md new file mode 100644 index 0000000..8a90c95 --- /dev/null +++ b/docs/grafana.md @@ -0,0 +1,40 @@ +# 三合一简化安装,原本的文档太晦涩了。 + +## 安装 +1. clone repo +>$ git clone https://github.com/hr3lxphr6j/bililive-go.git + +2. 编辑 .env +自定义账户密码,将example.env保存为.env +默认账户密码 `admin admin` +不改网页里也会提醒你去改。 + +3. 命令行输入 +>$ docker compose up + +假如docker 版本低于20,需要安装docker-compose。新的版本是直接内置的 + +4. 浏览器打开 http://localhost:3000 。 + +tips +- 使用默认端口和别的端口冲突时,修改相关ports: +- `./Videos:/srv/bililive` 默认保存路径需要自定义 + + +bibliography +1. [Docker-Compose-Prometheus-and-Grafana](https://github.com/Einsteinish/Docker-Compose-Prometheus-and-Grafana) + +# 手动安装笔记 +没有 docker 或者想在其他机器配置监控也可以选择手动安装。 +虽然API.md里面没有写,但是路径应该是`/api/metrics` 。`prometheus.yml` 需要写成以下形式 +``` yml +global: + scrape_interval: 15s +scrape_configs: + - job_name: "bililive" + metrics_path: "/api/metrics" + scheme: http + static_configs: + - targets: ["bililive-go:8080"] #自行修改ip端口 +``` +grafana 需要打开浏览器,然后复制[面板内容](/contrib/grafana/dashboard.json)导入 diff --git a/example.env b/example.env new file mode 100644 index 0000000..47d14ec --- /dev/null +++ b/example.env @@ -0,0 +1,2 @@ +ADMIN_USER=admin +ADMIN_PASSWORD=admin