Homepage 集成 Pangolin:站点、资源与流量统计 Widget 配置与实现原理指南
2026/9/11 14:05:54 网站建设 项目流程

Homepage 集成 Pangolin:站点、资源与流量统计 Widget 配置与实现原理指南

【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage

Pangolin 是一款支持 Docker 部署的反向代理与隧道管理平台,在 Homepage 中可以通过pangolin类型 Widget 直接展示某个组织(Organization)下的站点在线状态、资源与目标健康度以及累计流量。本文基于 官方 Widget 文档 并结合仓库源码(widget.js、component.jsx、组件测试 等),完整讲解配置方法、字段含义、统计口径与底层认证/代理实现,帮助你在自托管或云托管 Pangolin 上快速落地这块状态面板。

Widget 功能概览

pangolinWidget 面向一个组织(Organization)维度展示四类核心指标:

  • Sites(站点):在线站点数 / 站点总数;
  • Resources(资源):健康资源数 / 资源总数;
  • Targets(目标):健康目标数 / 目标总数;
  • Traffic(流量):所有站点的累计流量统计,并可细分为 In(入站)与 Out(出站)。

其中「资源健康」的判定规则为:一个资源只要其至少一个目标处于健康状态,即视为健康;如果该资源没有任何目标,同样视为健康。这一规则与 component.jsx 中的过滤逻辑完全一致:

const resourcesHealthy = resources.filter( (r) => r.targets?.some((t) => t.healthStatus !== "unhealthy") || !r.targets?.length, ).length;

也就是说,只有当资源存在目标且所有目标都不健康时,该资源才被计入不健康。

快速开始:最小配置示例

在 Homepage 的services.yaml(参考 docs/configs/services.md)中为服务添加如下 Widget 配置:

widget: type: pangolin url: https://api.pangolin.net key: your-api-key org: your-org-id
参数必填说明
type固定为pangolin
urlPangolinAPI 服务地址(通常是https://api.你的域名,而非 Web 控制台地址)
key具备相应权限的 API Key(见下文「API Key 配置」)
org目标组织 ID,用于定位站点与资源数据

提示:keyurl等敏感字段仅在后端代理请求时使用,前端渲染前会被脱敏处理,详见 widget-helpers.js 中的cleanWidgetGroups

获取组织 ID(org)

组织 ID 不需要在配置里手工维护——直接登录 Pangolin Web 控制台后从浏览器地址栏 URL 中读取即可。登录后的地址形如:

https://app.pangolin.net/{org-id}/...

其中路径中紧随域名后的第一段{org-id}就是本 Widget 需要的org参数值。

API Key 配置

Widget 通过 Pangolin 的 Integration API 读取数据,因此需要预先创建 API Key。创建时至少需要勾选以下两项权限

  • List Sites:读取站点列表(用于站点在线状态与流量统计);
  • List Resources:读取资源列表(用于资源与目标的健康统计)。

自托管部署(Self-Hosted)需要额外注意:Pangolin 的 Integration API 默认不开启,必须在 Pangolin 自身的配置中启用 Integration API 后,API Key 才会生效;云端托管版无需此步骤。

可显示字段(fields)与默认值

该 Widget 支持以下六个字段,最多同时显示 4 个

["sites", "resources", "targets", "traffic", "in", "out"]
  • 不配置fields时,默认显示sitesresourcestargetstraffic四项;
  • 配置的字段超过 4 个时,只会保留前 4 个。

上述默认值与截断行为在 component.jsx 中有明确实现:

const MAX_ALLOWED_FIELDS = 4; if (!widget.fields) { widget.fields = ["sites", "resources", "targets", "traffic"]; } else if (widget.fields?.length > MAX_ALLOWED_FIELDS) { widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS); }

对应测试 component.test.jsx 也验证了「传入 5 个字段时最终只剩前 4 个」的截断逻辑。示例如下:

widget: type: pangolin url: https://api.pangolin.net key: your-api-key org: your-org-id fields: - sites - resources - in - out

各字段的统计口径与换算规则

结合 component.jsx,六个字段的精确统计口径如下:

字段统计口径展示形式
sites在线站点数 / 站点总数,即sites.filter(s => s.online).length比上sites.length在线 / 总数
resources健康资源数 / 资源总数(健康判定见上文)健康 / 总数
targets健康目标数 / 目标总数,遍历所有资源的targets汇总健康 / 总数
traffic所有站点megabytesInmegabytesOut之和(按字节显示)格式化字节数
in所有站点megabytesIn之和格式化字节数
out所有站点megabytesOut之和格式化字节数

值得注意的细节是流量单位的换算:Pangolin API 返回的megabytesIn/megabytesOutMB(兆字节)为单位,而 Homepage 组件在渲染前统一乘以1_000_000转换为字节,再交给多语言格式化函数t("common.bytes", ...)展示,见 component.jsx:

const trafficIn = sites.reduce((sum, s) => sum + (s.megabytesIn || 0), 0) * 1_000_000; const trafficOut = sites.reduce((sum, s) => sum + (s.megabytesOut || 0), 0) * 1_000_000; const trafficTotal = trafficIn + trafficOut;

组件测试 同样按该换算断言:输入 1MB 与 3MB 入站、2MB 与 4MB 出站时,traffic展示为10_000_000字节。

界面文案(Sites / Resources / Targets / Traffic / In / Out)由多语言文件定义,例如英文翻译位于 public/locales/en/common.json 的pangolin命名空间下,中文等其他语言在对应 locale 目录中同样可用。

底层实现:API 映射与数据请求链路

API 端点映射

Widget 的 API 定义在 src/widgets/pangolin/widget.js,它声明了基础 URL 模板与两个数据端点:

const widget = { api: "{url}/v1/{endpoint}", proxyHandler: credentialedProxyHandler, mappings: { sites: { endpoint: "org/{org}/sites", }, resources: { endpoint: "org/{org}/resources?pageSize=200", }, }, };

可以看到:

  • 所有请求统一走/v1/前缀,拼接后实际请求为{url}/v1/org/{org}/sites{url}/v1/org/{org}/resources?pageSize=200
  • resources端点固定带上pageSize=200分页参数,最多取回 200 条资源;
  • {url}{org}占位符分别由配置中的urlorg字段填充。

组件在加载时会通过useWidgetAPI同时请求sitesresources两个端点(见 component.jsx),任一请求失败都会在容器中呈现错误状态;两数据均未返回时先渲染占位区块。

Bearer Token 认证

pangolin指定使用credentialedProxyHandler(src/utils/proxy/handlers/credentialed.js)。在该处理器中,pangolin被归类到使用Bearer Token认证的 Widget 名单中(credentialed.js):

} else if ( [ "argocd", "authentik", "cloudflared", ... "pangolin", ... ].includes(widget.type) ) { headers.Authorization = `Bearer ${widget.key}`; }

即每次请求都会携带Authorization: Bearer {key}请求头,key即配置中的 API Key。这也解释了为什么 API Key 必须包含 List Sites 与 List Resources 权限——只有具备这两项权限,两个端点才能正常返回数据。

完整请求链路

从配置到界面渲染,完整的数据流为:

  1. services.yaml中的 Widget 配置被加载并注入useWidgetAPI(use-widget-api.js);
  2. 前端向 Homepage 自身代理接口发起请求;
  3. credentialedProxyHandler根据widget.type === "pangolin"注入 Bearer Token,拼接出{url}/v1/org/{org}/...完整 URL 后转发给 Pangolin API(http.js 执行实际 HTTP 调用);
  4. 响应数据经过 validate-widget-data.js 的基础校验后回传前端;
  5. component.jsx 消费数据并计算上述各项统计,最终由Container/Block组件渲染为服务卡片上的状态块。

组件通过 src/widgets/components.js 中的dynamic(() => import("./pangolin/component"))按需懒加载,不影响其他 Widget 的首次加载性能。

常见问题排查

  • 接口返回 401/403:多为 API Key 权限不足或无效。请确认 Key 已勾选List SitesList Resources;自托管环境请先确认已启用Integration API
  • 显示「资源全部健康但实际有故障」:检查目标健康判定——资源无任何目标(targets为空数组)时会被直接视为健康,这是设计规则而非 Bug(component.jsx)。
  • 数据不刷新或为空:确认url填写的是 PangolinAPI 地址api.*子域),且网络可达;resources端点最多拉取 200 条资源,超大规模组织可关注是否存在截断。
  • 字段顺序与预期不符fields数组最多保留前 4 项,超出部分会被静默丢弃,请按展示优先级排序。

小结

通过pangolinWidget,你可以把 Pangolin 组织的站点在线率、资源/目标健康度与出入站流量直接聚合到 Homepage 服务面板,实现「网络基础设施状态一屏总览」。配置只需typeurlkeyorg四个字段,配合正确的 API Key 权限即可运行;其统计口径、Bearer 认证与端点映射均有明确的源码实现可查(widget.js、component.jsx、credentialed.js),便于在出现异常时快速定位问题。更多服务 Widget 的完整清单见 docs/widgets/services/index.md。

【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询