首页
/ Homepage 集成 Technitium DNS Server 监控 Widget 配置指南

Homepage 集成 Technitium DNS Server 监控 Widget 配置指南

2026-09-09 10:26:41作者:翟江哲Frasier

本指南讲解如何在 Homepage(gethomepage.dev)中通过 technitium 类型 Widget 接入 Technitium DNS Server,将 DNS 服务的查询总量、缓存命中、递归解析、拦截/丢弃等核心统计以一目了然的小部件形式呈现在个人起始页上。读完本文,你将掌握 Widget 的完整配置语法、noderange 参数的语义、可展示字段清单与默认值,以及这些配置在源码层面如何被解析并调用 Technitium 的 Dashboard API。

Widget 是什么:一次快速配置概览

Technitium DNS Server 是一个自托管的 DNS 服务器,支持多节点集群、权威/递归/缓存/拦截等多种查询处理路径。Homepage 的 technitium Widget 会调用 Technitium 的 Dashboard 统计 API,拉取一段时间窗口内的查询统计数据并渲染为数值卡片。

在 Homepage 的 services.yaml 中,为某个服务配置 Widget 的最小示例(源自 docs/widgets/services/technitium.md)如下:

widget:
  type: technitium
  url: <url to dns server>
  key: biglongapitoken
  node: <node dns name or cluster> # optional, defaults to current node
  range: LastDay # optional, defaults to LastHour

四个字段的职责:

字段 必填 说明
type 固定为 technitium,用于在 src/widgets/widgets.js 的 Widget 注册表中匹配实现(见其中 technitium, 条目)
url Technitium DNS Server 的访问地址
key 调用 API 所用的 Token
node 指定统计来自哪个集群节点,默认返回当前执行 API 的节点
range 统计时间窗口,默认 LastHour

可展示字段与默认值

Widget 允许配置 fields 来定制展示哪些统计项,最多 4 个,可选项为:

fields:
  - totalQueries      # 查询总数
  - totalNoError      # 成功(无错误)查询数
  - totalServerFailure # 服务器故障数
  - totalNxDomain     # NXDOMAIN(域名不存在)数
  - totalRefused      # 被拒绝的查询数
  - totalAuthoritative # 权威解析数
  - totalRecursive    # 递归解析数
  - totalCached       # 缓存命中数
  - totalBlocked      # 被拦截(如广告拦截)数
  - totalDropped      # 被丢弃的查询数
  - totalClients      # 活跃客户端数

若未配置 fields,默认展示以下 4 项:

fields:
  - totalQueries
  - totalAuthoritative
  - totalCached
  - totalServerFailure

这两个行为在组件源码中有明确体现:src/widgets/technitium/component.jsx 第 7 行定义了 MAX_ALLOWED_FIELDS = 4,第 9 行导出了 technitiumDefaultFields 数组;组件渲染时,若用户未提供 fields 则回退到默认 4 项,若超过 4 项则通过 widget.fields.slice(0, MAX_ALLOWED_FIELDS) 截断。

字段的展示标签来自 public/locales/en/common.jsontechnitium 一段的翻译映射(如 totalQueries → "Queries"、totalNoError → "Success"、totalBlocked → "Blocked"),因此在不同语言环境下会显示对应的本地化文案。

API Key 的获取

key 需要从 Technitium DNS Dashboard 中生成。需要注意:应该从专门的 API 专用用户(a special API specific user)生成,而不是使用管理员账号的 Token。在 Technitium 的管理界面中创建独立用户并为其签发 API Token,可以有效缩小权限暴露面,避免常规 Web 登录凭据被用于 API 调用。

Node 参数:决定统计来自哪个节点

node 决定 Widget 返回的是哪个集群节点的统计数据,取值有三种情况:

  • 不填:返回 API 请求所执行的那台节点的统计数据(默认行为);
  • cluster:返回整个集群所有节点的聚合(aggregate)统计;
  • 节点域名:例如填写某个节点的域名,返回该特定节点的统计。

该参数在请求层面直接透传给 Technitium 的 Dashboard API。从源码看,组件在构造 API 参数时将其作为 node 查询参数传递(src/widgets/technitium/component.jsx 第 16-19 行):

const params = {
  node: widget.node ?? "",
  type: widget.range ?? "LastHour",
};

Range 参数:统计时间窗口

range 决定拉取多长历史窗口的统计数据,取值直接取自 Technitium 官方 API 文档(Dashboard API Calls)中定义的 "type" 字段,可选值为:

  • LastHour(默认)
  • LastDay
  • LastWeek
  • LastMonth
  • LastYear

例如,想查看最近 24 小时的 DNS 运行概况,可将 range 设为 LastDay,即本篇开头示例中的用法。

源码视角:Widget 如何调用 Technitium API

请求构造与响应映射

Widget 的 API 行为定义在 src/widgets/technitium/widget.js

const widget = {
  api: "{url}/api/{endpoint}?token={key}&utc=true",
  proxyHandler: genericProxyHandler,
  mappings: {
    stats: {
      endpoint: "dashboard/stats/get",
      validate: ["response", "status"],
      params: ["node", "type"],
      map: (data) => asJson(data).response?.stats,
    },
  },
};

可以拆解出三条关键事实:

  1. 接口端点:实际请求的 URL 形如 {url}/api/dashboard/stats/get?token={key}&utc=true&node=...&type=...,即调用 Technitium 的 dashboard/stats/get 统计接口,并固定附加 utc=true 表示使用 UTC 时间。
  2. 参数透传params: ["node", "type"] 声明了可透传的查询参数,正好对应配置文件中的 noderangerange 在请求层以 type 为名传递)。
  3. 响应提取:接口返回的 JSON 中,统计主体位于 response.stats 字段,map 函数将其提取出来交给前端渲染;validate 声明了需要校验 responsestatus 字段,配合 genericProxyHandlersrc/utils/proxy/handlers/generic.js)完成代理与数据校验。

配置解析链路

配置项 noderange 在服务配置解析阶段被专门处理。在 src/utils/config/service-helpers.js 中,range 被列入 widgetData 的解构清单(第 431-432 行),并在第 668-671 行针对 technitium 类型做条件赋值:

if (type === "technitium") {
  if (node !== undefined) widget.node = node;
  if (range !== undefined) widget.range = range;
}

即:只有用户显式填写了 noderange,它们才会进入最终的 widget 配置对象;未填写时由组件层使用默认值(空字符串与 LastHour)。

数据渲染:数值与占比

组件拿到 stats 数据后,用统一翻译函数格式化数值,并为大多数指标计算占 totalQueries 的百分比(src/widgets/technitium/component.jsx 第 55-60 行的 toPercent 函数,通过 common.percent 翻译模板输出,最多保留两位小数)。因此界面上会呈现类似 50 (50) 的「数值 + 百分比」形式,便于直观判断成功率、失败率与缓存命中率;totalQueriestotalClients 则只显示绝对值。加载中状态会展示各字段的占位块,出错时则通过 Container 的错误态展示错误信息。

测试验证:行为有据可依

该 Widget 的行为由两层测试保障:

完整配置示例

将上述知识组合起来,一个面向多节点集群的完整配置如下:

- Technitium DNS:
    icon: sh-technitium
    href: http://dns.example.com:5380
    widget:
      type: technitium
      url: http://dns.example.com:5380
      key: biglongapitoken
      node: cluster            # 聚合所有节点统计
      range: LastDay           # 查看最近 24 小时
      fields:
        - totalQueries
        - totalBlocked
        - totalNoError
        - totalServerFailure

若只关心单节点、使用默认时间窗口,也可以简化为只填 urlkey 两项必填字段。相关配置文件的更多上下文可参考 docs/configs/services.mdsrc/skeleton/services.yaml,Widget 列表总览见 docs/widgets/services/index.md

常见问题与注意事项

  • 403 / Token 无效:确认 key 来自 Technitium Dashboard 中专门签发的 API Token(建议使用 API 专用用户),而不是普通 Web 登录会话;
  • 统计不更新range 仅支持文档列出的五个枚举值,非法值会被 Technitium 端拒绝;同时注意 utc=true 是固定附加参数,统计窗口按 UTC 计算;
  • 集群节点不匹配node 填写的必须是 Technitium 集群中实际的节点域名,或使用字面量 cluster 获取聚合数据;
  • 字段不生效fields 最多 4 项,超出部分会被源码自动截断;拼写需与允许字段清单完全一致,否则无法匹配对应统计项。

借助这个 Widget,你可以在 Homepage 起始页上一屏掌握自建 DNS 的查询负载、缓存效果与拦截情况,无需频繁登录 Technitium 管理面板即可完成日常巡检。

热门项目推荐
相关项目推荐

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.15 K
2.77 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
929
1.85 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
534
603
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23