Files
Arch1Panel/apps/glance-agent/README.md
arch3rPro e021bdcf9e feat(glance-agent): 添加对官方agent的支持并更新文档
添加官方glance-agent的0.1.0和latest版本配置
保留原有custom版本配置
更新README说明版本差异和配置方法
2025-12-14 16:29:52 +08:00

242 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Glance 远程服务器监控 Agent
## 项目简介
本项目为 Glance Dashboard 提供远程服务器监控数据采集,使用 Python3 + FastAPI 实现,兼容 Glance `server-stats` 组件前端展示。支持 Docker 部署,适合多服务器统一监控。
## 更新说明
Glance官方已经发布了agent项目地址[glance-agent](https://github.com/glanceapp/agent)
本次更新后,保留本人使用 Python3 + FastAPI 实现的版本,同时新增了对 Glance 官方 agent 的支持。
因为原生支持官方的agent所以更推荐使用官方版本
## 版本说明
- 0.1.0 官方稳定版本 推荐
- latest 官方最新版本
- custom 作者自己写的版本 项目保留
## 功能特性
- 采集主机名、平台、启动时间、CPU 负载/温度、内存、磁盘等信息
- 提供 `/api/sysinfo/all` HTTP API返回 Glance 兼容 JSON
- 支持 Docker 镜像和 docker-compose 一键部署
- 可多实例部署,适配多服务器场景
- **主机名自动识别**:容器内自动优先读取宿主机 `/etc/hostname`,无需手动配置
## 配置方法
在配置文件中添加以下内容:
- type: server-stats
servers:
- type: remote
name: Custom Server Name
url: http://<server IP or domain>:27973
token: <token from above, if set>
## API 说明
- 路径:`/api/sysinfo/all`
- 方法GET
- 返回:
```json
{
"Hostname": "server1",
"Platform": "Linux-5.15.0-1051-azure-x86_64-with-glibc2.29",
"BootTime": 1710000000,
"HostInfoIsAvailable": true,
"CPU": {
"Load1Percent": 12.5,
"Load15Percent": 8.2,
"TemperatureC": 45.0,
"LoadIsAvailable": true,
"TemperatureIsAvailable": true
},
"Memory": {
"IsAvailable": true,
"UsedPercent": 55.3,
"UsedMB": 2048,
"TotalMB": 4096,
"SwapIsAvailable": true,
"SwapUsedMB": 256,
"SwapTotalMB": 1024,
"SwapUsedPercent": 25.0
},
"Mountpoints": [
{
"Name": "/dev/sda1",
"Path": "/",
"UsedMB": 10240,
"TotalMB": 20480,
"UsedPercent": 50.0
}
]
}
```
## Glance 集成方法
1.`agent/custom-api-example.yaml` 内容合并到 Glance 的主配置文件(如 `glance.yml`)对应 widgets 区域。
2. 每台服务器部署一个 agent配置对应的 API 地址。
3. 前端展示效果与本地 server-stats 一致。
### custom-api 配置示例
```yaml
- type: custom-api
title: 远程服务器A
url: http://192.168.1.200:8000/api/sysinfo/all ## 请修改为实际的IP地址
cache: 15s
template: |
<div class="server">
<div class="server-info">
<div class="server-details">
<div class="server-name color-highlight size-h3">
{{ .JSON.String "Hostname" }}
</div>
<div>
{{ if .JSON.Bool "HostInfoIsAvailable" }}
<span {{ .JSON.Int "BootTime" | printf "%d" | parseTime "unix" | toRelativeTime }}></span> uptime
{{ else }}unknown uptime{{ end }}
</div>
</div>
<div class="shrink-0" data-popover-type="html" data-popover-margin="0.2rem" data-popover-max-width="400px">
<div data-popover-html>
<div class="size-h5 text-compact">PLATFORM</div>
<div class="color-highlight">
{{ if .JSON.Bool "HostInfoIsAvailable" }}
{{ .JSON.String "Platform" }}
{{ else }}Unknown{{ end }}
</div>
</div>
<!-- 服务器logo -->
<svg class="server-icon" stroke="var(--color-positive)" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 0 0-.12-1.03l-2.268-9.64a3.375 3.375 0 0 0-3.285-2.602H7.923a3.375 3.375 0 0 0-3.285 2.602l-2.268 9.64a4.5 4.5 0 0 0-.12 1.03v.228m19.5 0a3 3 0 0 1-3 3H5.25a3 3 0 0 1-3-3m19.5 0a3 3 0 0 0-3-3H5.25a3 3 0 0 0-3 3m16.5 0h.008v.008h-.008v-.008Zm-3 0h.008v.008h-.008v-.008Z" />
</svg>
</div>
</div>
<div class="server-stats">
<!-- CPU -->
<div class="flex-1{{ if not (.JSON.Bool "CPU.LoadIsAvailable") }} server-stat-unavailable{{ end }}">
<div class="flex items-end size-h5">
<div>CPU</div>
{{ if and (.JSON.Bool "CPU.TemperatureIsAvailable") (ge (.JSON.Float "CPU.TemperatureC") 80.0) }}
<svg class="server-spicy-cpu-icon" fill="var(--color-negative)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
<path fill-rule="evenodd" d="M8.074.945A4.993 4.993 0 0 0 6 5v.032c.004.6.114 1.176.311 1.709.16.428-.204.91-.61.7a5.023 5.023 0 0 1-1.868-1.677c-.202-.304-.648-.363-.848-.058a6 6 0 1 0 8.017-1.901l-.004-.007a4.98 4.98 0 0 1-2.18-2.574c-.116-.31-.477-.472-.744-.28Zm.78 6.178a3.001 3.001 0 1 1-3.473 4.341c-.205-.365.215-.694.62-.59a4.008 4.008 0 0 0 1.873.03c.288-.065.413-.386.321-.666A3.997 3.997 0 0 1 8 8.999c0-.585.126-1.14.351-1.641a.42.42 0 0 1 .503-.235Z" clip-rule="evenodd" />
</svg>
{{ end }}
<div class="color-highlight margin-left-auto text-very-compact">
{{ if .JSON.Bool "CPU.LoadIsAvailable" }}
{{ .JSON.Float "CPU.Load1Percent" }} <span class="color-base">%</span>
{{ else }}n/a{{ end }}
</div>
</div>
<div data-popover-type="html">
<div data-popover-html>
<div class="flex">
<div class="size-h5">1M AVG</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">{{ .JSON.Float "CPU.Load1Percent" }} <span class="color-base size-h5">%</span></div>
</div>
<div class="flex margin-top-3">
<div class="size-h5">15M AVG</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">{{ .JSON.Float "CPU.Load15Percent" }} <span class="color-base size-h5">%</span></div>
</div>
{{ if .JSON.Bool "CPU.TemperatureIsAvailable" }}
<div class="flex margin-top-3">
<div class="size-h5">TEMP C</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">{{ .JSON.Float "CPU.TemperatureC" }} <span class="color-base size-h5">°</span></div>
</div>
{{ end }}
</div>
<div class="progress-bar progress-bar-combined">
{{ if .JSON.Bool "CPU.LoadIsAvailable" }}
<div class="progress-value{{ if ge (.JSON.Float "CPU.Load1Percent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ .JSON.Float "CPU.Load1Percent" }}"></div>
<div class="progress-value{{ if ge (.JSON.Float "CPU.Load15Percent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ .JSON.Float "CPU.Load15Percent" }}"></div>
{{ end }}
</div>
</div>
</div>
<!-- RAM -->
<div class="flex-1{{ if not (.JSON.Bool "Memory.IsAvailable") }} server-stat-unavailable{{ end }}">
<div class="flex justify-between items-end size-h5">
<div>RAM</div>
<div class="color-highlight text-very-compact">
{{ if .JSON.Bool "Memory.IsAvailable" }}
{{ .JSON.Float "Memory.UsedPercent" }} <span class="color-base">%</span>
{{ else }}n/a{{ end }}
</div>
</div>
<div data-popover-type="html">
<div data-popover-html>
<div class="flex">
<div class="size-h5">RAM</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">
{{ .JSON.Float "Memory.UsedGB" }}GB <span class="color-base size-h5">/</span> {{ .JSON.Float "Memory.TotalGB" }}GB
</div>
</div>
{{ if .JSON.Bool "Memory.SwapIsAvailable" }}
<div class="flex margin-top-3">
<div class="size-h5">SWAP</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">
{{ .JSON.Float "Memory.SwapUsedGB" }}GB <span class="color-base size-h5">/</span> {{ .JSON.Float "Memory.SwapTotalGB" }}GB
</div>
</div>
{{ end }}
</div>
<div class="progress-bar progress-bar-combined">
{{ if .JSON.Bool "Memory.IsAvailable" }}
<div class="progress-value{{ if ge (.JSON.Float "Memory.UsedPercent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ .JSON.Float "Memory.UsedPercent" }}"></div>
{{ if .JSON.Bool "Memory.SwapIsAvailable" }}
<div class="progress-value{{ if ge (.JSON.Float "Memory.SwapUsedPercent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ .JSON.Float "Memory.SwapUsedPercent" }}"></div>
{{ end }}
{{ end }}
</div>
</div>
</div>
<!-- DISK -->
<div class="flex-1{{ if not ((.JSON.Array "Mountpoints" | len)) }} server-stat-unavailable{{ end }}">
<div class="flex justify-between items-end size-h5">
<div>DISK</div>
<div class="color-highlight text-very-compact">
{{ if gt (.JSON.Array "Mountpoints" | len) 0 }}
{{ (index (.JSON.Array "Mountpoints") 0).Float "UsedPercent" }} <span class="color-base">%</span>
{{ else }}n/a{{ end }}
</div>
</div>
<div data-popover-type="html">
<div data-popover-html>
<ul class="list list-gap-2">
{{ range .JSON.Array "Mountpoints" }}
<li class="flex">
<div class="size-h5">{{ if .String "Name" }}{{ .String "Name" }}{{ else }}{{ .String "Path" }}{{ end }}</div>
<div class="value-separator"></div>
<div class="color-highlight text-very-compact">
{{ .Float "UsedGB" }}GB <span class="color-base size-h5">/</span> {{ .Float "TotalGB" }}GB
</div>
</li>
{{ end }}
</ul>
</div>
<div class="progress-bar progress-bar-combined">
{{ if gt (.JSON.Array "Mountpoints" | len) 0 }}
<div class="progress-value{{ if ge ((index (.JSON.Array "Mountpoints") 0).Float "UsedPercent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ (index (.JSON.Array "Mountpoints") 0).Float "UsedPercent" }}"></div>
{{ if gt (.JSON.Array "Mountpoints" | len) 1 }}
<div class="progress-value{{ if ge ((index (.JSON.Array "Mountpoints") 1).Float "UsedPercent") 85.0 }} progress-value-notice{{ end }}" style="--percent: {{ (index (.JSON.Array "Mountpoints") 1).Float "UsedPercent" }}"></div>
{{ end }}
{{ end }}
</div>
</div>
</div>
</div>
</div>
```
## 参考
- [Glance-Agent](https://github.com/glanceapp/agent)
- [Glance-Monitor](https://github.com/arch3rPro/Glance-Monitor)
- [Document文档](https://github.com/arch3rPro/Glance-Monitor/blob/main/server-status-agent/README.md)