Gatus 配置参数详解

逐参数讲解 Gatus v5.37.0 主配置文件的核心段(web/ui/storage/alerting/maintenance/security/metrics/endpoints 等),每个关键参数均按修改配置、重启、行为对比回显完成实测验证,含生产配置模板、条件表达式速查与热重载停摆等故障实录。

GatusGatus2026/10/18

Gatus 配置参数详解

目标:逐参数讲解 Gatus v5.37.0 主配置文件(gatus.yml / config.yaml)的核心段与参数,每个关键参数均按「修改配置 → 重启 → 行为对比回显」完成实测验证。已在 Ubuntu 22.04(x86_64,Gatus v5.37.0 二进制 + systemd 托管)实测通过。

一、环境信息

本篇实测环境与文件布局(所有回显均为实测照抄):

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Gatus 版本:v5.37.0(go version -m /usr/local/bin/gatus 实测确认)
  • 托管方式:systemd 服务 gatus.service(Environment=GATUS_CONFIG_PATH=/opt/data/gatus-server/config.yaml)
  • 主配置文件:/opt/data/gatus-server/config.yaml
  • 数据文件:/opt/data/gatus-server/data/data.db(SQLite)
  • 服务端口:8080
  • 拨测目标:本地 HTTP 服务(/health 返回 {"status":"UP"},其余路径 404)+ 外网 HTTPS 站点
  • 辅助工具:sqlite3(数据核对)、htpasswd(生成 bcrypt 口令,来自 apache2-utils 包)

二、前置条件

按以下步骤确认环境可复现本篇实测:

  1. Gatus 已部署并可访问(部署流程见《Gatus 介绍与选型指南》快速开始或《Gatus Docker Compose 部署指南》):
systemctl is-active gatus

实测输出:

active
  1. 准备 sqlite3 用于核对存储行为(Ubuntu 22.04):
apt-get install -y sqlite3
  1. 确认服务日志可读(本篇多处用 journalctl 观察行为):
journalctl -u gatus --no-pager -n 5

实测输出(节选):

Oct 17 20:25:35 gatus[3173]: 2026/10/17 20:25:35 [watchdog.executeEndpoint] Monitored group=core; endpoint=nginx-health; key=core_nginx-health; success=true; errors=0; duration=0s

三、参数查看与修改方式

3.1 查看当前生效配置的三个途径

Gatus 不提供"导出配置"命令,实测确认三种查看方式:

  1. 读配置文件:直接查看 GATUS_CONFIG_PATH 指向的文件(systemd 场景用 systemctl cat gatus 先确认路径);
  2. 读 Web 首页内嵌配置:Gatus 把 UI 相关配置以 JSON 形式内嵌在首页 HTML 的 window.config 中(实测 curl -s http://127.0.0.1:8080/ | grep -oE 'window.config = .{0,200}' 可见 title、header 等当前值);
  3. 读启动日志:每次启动与热重载都打印 Reading configuration from configFile=<路径> 与端点校验结果 Validated N endpoints。

3.2 修改与生效:热重载 vs 重启

Gatus 监听配置文件变更,大多数参数修改后自动热重载生效。本篇实测的热重载行为:

# 修改配置后(以编辑器或 sed 修改 config.yaml),数秒内观察日志
journalctl -u gatus --no-pager -n 3

热重载时实测日志会重新打印初始化序列(ValidateAlertingConfig、initializeStorage 等),且进程 PID 不变:

Oct 17 20:22:11 gatus[3059]: 2026/10/17 20:22:11 [config.ValidateAlertingConfig] configuredProviders=[custom]; ignoredProviders=[aws-ses clickup datadog discord email github gitlab gitea googlechat gotify homeassistant ifttt ilert incident-io line matrix mattermost messagebird n8n newrelic ntfy opsgenie pagerduty plivo pushover rocketchat sendgrid signal signl4 slack splunk squadcast teams teams-workflows telegram twilio vonage webex zapier zulip]
Oct 17 20:22:11 gatus[3059]: 2026/10/17 20:22:11 [main.initializeStorage] Loaded 1 persisted triggered alerts

(这段日志同时实测确认:热重载列出全部 40+ 告警提供方,configuredProviders=[custom] 表示当前只启用 custom;触发中的告警会从存储恢复,不会重复通知)

需要重启才能生效的场景(实测归纳):Gatus 程序本身的运行参数,如 systemd 单元里的 GATUS_CONFIG_PATH、GATUS_LOG_LEVEL 等环境变量。

3.3 配置文件路径与多文件合并

GATUS_CONFIG_PATH 指向目录时,Gatus 会合并目录及其子目录下所有 *.yaml/*.yml 文件,合并规则(官方文档,实测验证单文件行为一致):

  • 对象(map)深度合并:可在 A 文件写 alerting.slack、B 文件写 alerting.pagerduty;
  • 数组追加:endpoints 可分散在多个文件,最终合并为一张端点清单;
  • 标量参数只能定义一次,重复定义直接报错,避免歧义。

💡 技术拓展:配置管理业界常见的三种拆分策略——单文件集中式(小规模最直观)、按域拆分多文件合并式(Gatus 原生支持,中大型团队按 endpoints/alerting/security 分文件)、模板+变量渲染式(Helm/Kustomize 等,适合多环境交付)。Gatus 的多文件合并覆盖前两种,第三种通常配合外部工具完成。本篇实测采用单文件,端点规模上百时建议按域拆分。

3.4 配置内引用环境变量

配置文件里可引用环境变量($DOMAIN 或 ${DOMAIN} 形态),配置内容中字面 $ 用 $$ 转义。systemd 场景在单元文件里注入:

Environment=DOMAIN=www.quzuo.net

配置中即可写 url: https://${DOMAIN}。此机制适合把随环境变化的值(域名、Webhook 地址)从配置中抽出。

四、参数总览

主配置文件顶层参数一览(默认值来自官方文档,标注「实测」的为本环境验证过):

参数类型默认值说明
metricsboolfalse是否在 /metrics 暴露 Prometheus 指标(实测)
webobject{}Web 服务配置(实测)
uiobject{}界面文案配置(实测)
storageobject{}存储配置,默认 memory(实测 sqlite 路径)
alertingobject{}告警渠道配置(实测 custom 渠道)
endpointslist必填 []拨测端点清单(实测 7 端点)
external-endpointslist[]外部推送端点(实测 token 推送)
securityobject{}访问认证(实测 basic 认证)
concurrencyint3并发拨测上限,0 表示不限
disable-monitoring-lockboolfalse已废弃,用 concurrency: 0 替代
skip-invalid-config-updateboolfalse忽略无效的配置热更新(实测两态行为)
maintenanceobject{}维护窗口(实测不暂停检测)
announcementslist[]状态页顶部公告

日志级别不走配置文件,用环境变量 GATUS_LOG_LEVEL(默认 INFO,可选 DEBUG/WARN/ERROR/FATAL;实测启动日志首行即打印 Log Level is set to INFO)。

五、核心参数分类详解

5.1 web:服务监听

web 段控制 HTTP 服务监听行为,核心参数 web.port(默认 8080)。

实测:把端口从 8080 改为 8081 并重启:

sed -i 's/port: 8080/port: 8081/' /opt/data/gatus-server/config.yaml
systemctl restart gatus && sleep 5

验证新旧端口(实测输出):

curl -s -o /dev/null -w '8081: %{http_code}\n' http://127.0.0.1:8081/
curl -s -o /dev/null -w '8080: %{http_code}\n' --max-time 3 http://127.0.0.1:8080/ || echo '8080: 拒绝连接'
8081: 200
8080: 拒绝连接
ss -tlnp | grep gatus

实测输出:

LISTEN 0 4096 *:8081 *:* users:(("gatus",pid=3173,fd=7))

改回 8080 并重启后实测恢复 8080: 200。结论:web.port 完全控制监听端口,重启即切换,无残留监听。

5.2 ui:界面文案

ui 段控制状态页文案,实测验证了三个参数的生效方式差异:

ui:
  title: "生产拨测平台 ǀ Gatus"
  header: "生产监控台"
  dashboard-heading: "生产服务拨测面板"
参数默认值实测行为
ui.titleGatus浏览器标签页 <title>;实测修改后热重载不改 title,重启后生效(实测重启后 `curl -s ...
ui.header空页面顶部大标题;热重载即生效(实测首页 HTML 中出现 生产监控台)
ui.dashboard-headingHealth仪表盘区块标题;热重载即生效(实测首页出现 生产服务拨测面板)

实测对比流程(先热重载后重启):

# 热重载阶段(编辑配置文件保存即触发)
curl -s http://127.0.0.1:8080/ | grep -oE 'window.config = \{[^}]+\}' | head -c 400

实测输出(节选,header/dashboard-heading 已更新):

window.config = {...,"header":"生产监控台","dashboard-heading":"生产服务拨测面板",...}
# 重启后再看 title
systemctl restart gatus && sleep 5
curl -s http://127.0.0.1:8080/ | grep -oE '<title>[^<]+</title>'

实测输出:

<title>生产拨测平台 ǀ Gatus</title>

⚠️ 注意:title 是浏览器标签标题,页面首次加载时注入,热重载场景下已打开的页面不会主动刷新它——不是配置不生效,是浏览器侧不刷新。核对以重启后或新开页面为准。

5.3 storage:存储引擎

storage 段决定历史数据的持久性。三种引擎:memory(默认,重启即失)、sqlite(单文件)、postgres。

实测采用的 SQLite 配置:

storage:
  type: sqlite
  path: /opt/data/gatus-server/data/data.db
  caching: true
  maximum-number-of-results: 500
  maximum-number-of-events: 50

逐参数实测说明:

参数默认值实测行为
storage.typememory改为 sqlite 后落盘生效:ls -lh 实测生成 data.db(96 KB),服务重启后历史结果完整保留(API 连续返回历史数据)
storage.path空sqlite 类型必填;实测文件含 8 张表(.tables 实测:endpoint_results、endpoint_events、endpoint_uptimes、endpoint_alerts_triggered、endpoints、endpoint_result_conditions、suites、suite_results)
storage.cachingfalse写穿透缓存;实测开启后读写正常,官方定位是加速大面板加载
storage.maximum-number-of-results100每端点保留的最大结果条数。实测改为 5 后:既有数据不会立即收缩——重启后仍为 12/13 条(SQLite 实测 SELECT endpoint_name, COUNT(*) ... GROUP BY 输出 `quzuo-homepage
storage.maximum-number-of-events50每端点保留的最大事件数,机制同上

核对数据条数的实测命令:

sqlite3 /opt/data/gatus-server/data/data.db \
  "SELECT e.endpoint_name, COUNT(*) c FROM endpoint_results r JOIN endpoints e ON r.endpoint_id=e.endpoint_id GROUP BY r.endpoint_id ORDER BY c DESC LIMIT 8;"

实测输出:

quzuo-homepage|13
nginx-health|12
nginx-missing|7
ext-agent|2

💡 提示:磁盘规划按「端点数 × maximum-number-of-results × 单条约 1 KB」估算并留倍余量;本环境 5 端点数小时数据文件仅 96 KB,中小规模 SQLite 完全够用。

5.4 alerting:告警渠道

alerting 段配置通知渠道,支持 Slack、Teams、Discord、Telegram、PagerDuty 等 40+ 提供方(热重载日志实测列出全部清单,见 3.2)。任意内部系统可用 custom 自定义 Webhook 对接。

实测配置(custom 渠道 + 默认告警参数):

alerting:
  custom:
    url: "http://192.168.16.2/alert"
    method: "POST"
    body: |
      {"text": "[ALERT_TRIGGERED_OR_RESOLVED]: [ENDPOINT_GROUP] - [ENDPOINT_NAME] - [ALERT_DESCRIPTION] - [RESULT_ERRORS]"}
    default-alert:
      enabled: true
      failure-threshold: 1
      send-on-resolved: true

配套的端点侧声明(必须显式写 alerts,default-alert 只是参数模板):

endpoints:
  - name: nginx-health
    group: core
    url: http://192.168.16.2/health
    interval: 15s
    conditions:
      - "[STATUS] == 200"
    alerts:
      - type: custom
        description: "Nginx 健康检查失败"

实测完整闭环(故意把条件改为 [STATUS] == 201 触发失败):

  1. 触发(gatus 日志实测):
Oct 17 20:21:10 gatus[3059]: 2026/10/17 20:21:10 [watchdog.handleAlertsToTrigger] Sending custom alert because alert for endpoint with key=core_nginx-health with description='Nginx 健康检查失败' has been TRIGGERED
  1. 接收端(nginx 访问日志实测):
192.168.16.4 - - [17/Oct/2026:20:21:10 +0000] "POST /alert HTTP/1.1" 200 2 "-" "Go-http-client/1.1" "-"
  1. 恢复条件后自动发送 RESOLVED(实测):
Oct 17 20:22:26 gatus[3059]: 2026/10/17 20:22:26 [watchdog.handleAlertsToResolve] Sending custom alert because alert for endpoint with key=core_nginx-health with description='Nginx 健康检查失败' has been RESOLVED

关键参数说明:

参数默认值实测说明
alerting.custom.url必填Webhook 地址,支持 [ALERT_TRIGGERED_OR_RESOLVED] 等占位符(body 内可用)
default-alert.failure-threshold3连续失败多少次才触发;实测 1 时单次失败立即触发
default-alert.send-on-resolvedfalse恢复时是否补发通知;实测开启后 TRIGGERED/RESOLVED 成对出现
endpoints[].alerts[].type必填渠道类型;实测不写时 default-alert 不生效(告警完全不触发),这是最高频的配置坑
触发态持久化—实测重启后日志 Loaded 1 persisted triggered alerts:未恢复的告警重启后不会重复触发通知

5.5 maintenance:维护窗口

maintenance 段配置全局维护窗口,窗口内的失败不触发告警:

maintenance:
  enabled: true
  start: 20:20
  duration: 30m
  timezone: "UTC"

实测确认了两个关键语义(当前 UTC 20:23~20:24 处于窗口内验证):

  1. 拨测不暂停:窗口内 SQLite 持续写入新结果(实测 18 秒窗口内新增 1 条结果记录,拨测周期照常);
  2. 抑制的是告警:官方语义即"维护期不想被告警打扰"(If you have maintenance windows, you may not want to be annoyed by alerts)。
参数默认值说明
maintenance.enabledtrue是否启用
maintenance.start必填开始时间 hh:mm
maintenance.duration必填持续时长(1h、30m)
maintenance.timezoneUTCIANA 时区名(如 Asia/Shanghai)
maintenance.every[]生效的星期列表,空为每天

端点级维护窗口用 endpoints[].maintenance-windows(参数结构同上),适合只对部分服务设窗口。规划维护策略时按「窗口内检测照跑、只静音告警」设计,不要指望它省探测流量。

5.6 security:访问认证

security 段配置 UI 与 API 的访问控制,支持 basic(HTTP Basic)与 oidc 两种方式。默认无认证,公网部署必须配置。

实测 Basic 认证全流程。第一步生成 bcrypt 哈希并 base64 编码(实测命令):

htpasswd -bnBC 10 "" "q1w2e3r4" | tr -d ":\n" > /tmp/hash.txt
base64 -w0 /tmp/hash.txt; echo

实测输出:

$2y$10$LXBHeaZ4VDniMjqqHLtdvuwuO34QrKPUhv7/nzh0gwLUhCe7cc2b6
JDJ5JDEwJExYQkhlYVo0VkRuaU1qbnFITHRkdnV3dU8zNFFyS1BVaHY3L256aDBnd0xVaENlN2NjMmI2

第二步写入配置并重启:

security:
  basic:
    username: admin
    password-bcrypt-base64: "JDJ5JDEwJExYQkhlYVo0VkRuaU1qbnFITHRkdnV3dU8zNFFyS1BVaHY3L256aDBnd0xVaENlN2NjMmI2"

第三步验证(实测输出):

# 无凭据
curl -s -D - "http://127.0.0.1:8080/api/v1/endpoints/statuses" -o /dev/null | head -3
curl -s "http://127.0.0.1:8080/api/v1/endpoints/statuses"; echo
# 错误凭据
curl -s -D - -u admin:badpass "http://127.0.0.1:8080/api/v1/endpoints/statuses" -o /dev/null | head -1
# 正确凭据
curl -s -D - -u admin:q1w2e3r4 "http://127.0.0.1:8080/api/v1/endpoints/statuses" -o /dev/null | head -1
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{"error":"Not Authenticated"}
HTTP/1.1 401 Unauthorized
HTTP/1.1 200 OK

认证行为实测结论:启用后 UI 页面与全部 API 一体拦截(401 + JSON 错误体),curl 用 -u admin:q1w2e3r4 通过;浏览器访问会弹出标准 Basic 认证框。

参数默认值说明
security.basic.username必填登录用户名
security.basic.password-bcrypt-base64必填bcrypt 哈希后 base64 编码的口令(不落明文)
security.oidc.*{}OIDC 配置(issuer-url/redirect-url/client-id/client-secret/scopes/session-ttl 默认 8h)

bcrypt cost 选型:cost 越高校验越慢(每次请求都要校验),官方建议 9~10,实测用 10。

5.7 metrics:Prometheus 指标

metrics: true 开启 /metrics。实测 HTTP 头与指标输出:

HTTP/1.1 200 OK
Content-Type: text/plain; version=0.0.4; charset=utf-8; escaping=underscores
Content-Length: 11302

实测指标全量(16 条 gatus_ 前缀指标):

gatus_results_certificate_expiration_seconds{group="external",key="external_quzuo-homepage",name="quzuo-homepage",type="HTTP"} 7.035649907032556e+06
gatus_results_code_total{code="200",group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 44
gatus_results_code_total{code="200",group="external",key="external_quzuo-homepage",name="quzuo-homepage",type="HTTP"} 3
gatus_results_code_total{code="404",group="core",key="core_nginx-missing",name="nginx-missing",type="HTTP"} 11
gatus_results_connected_total{group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 44
gatus_results_connected_total{group="core",key="core_nginx-missing",name="nginx-missing",type="HTTP"} 11
gatus_results_connected_total{group="external",key="external_quzuo-homepage",name="quzuo-homepage",type="HTTP"} 3
gatus_results_duration_seconds{group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 0.000216646
gatus_results_duration_seconds{group="core",key="core_nginx-missing",name="nginx-missing",type="HTTP"} 0.001265084
gatus_results_duration_seconds{group="external",key="external_quzuo-homepage",name="quzuo-homepage",type="HTTP"} 0.175257058
gatus_results_endpoint_success{group="core",key="core_nginx-health",name="nginx-health",type="HTTP"} 1
gatus_results_endpoint_success{group="core",key="core_nginx-missing",name="nginx-missing",type="HTTP"} 1
gatus_results_endpoint_success{group="external",key="external_quzuo-homepage",name="quzuo-homepage",type="HTTP"} 1
gatus_results_total{group="core",key="core_nginx-health",name="nginx-health",success="true",type="HTTP"} 44
gatus_results_total{group="core",key="core_nginx-missing",name="nginx-missing",type="HTTP"} 11
gatus_results_total{group="external",key="external_quzuo-homepage",name="quzuo-homepage",success="true",type="HTTP"} 3

指标语义:gatus_results_total(总探测次数,按 success 分维)、gatus_results_code_total(状态码计数)、gatus_results_duration_seconds(平均耗时)、gatus_results_endpoint_success(最近一次是否健康)、gatus_results_certificate_expiration_seconds(证书剩余秒数)。标签含 group/key/name/type,Prometheus 侧可直接按端点聚合告警规则。

5.8 concurrency:并发拨测上限

concurrency(默认 3)限制同时探测的端点数量,防止大量端点同时发起探测造成瞬时压力。0 表示不限制。本环境 7 端点/低频场景下默认值无感知;当端点数上百且 interval 很短时,若探测周期内跑不完所有端点(日志出现周期拖长),调大该值即可。配套的已废弃参数 disable-monitoring-lock 不要再用,等价写法是 concurrency: 0。

5.9 skip-invalid-config-update:热更新保护

该参数的官方语义是"热重载遇到无效配置时忽略之(true)或终止进程(false)"。本环境用语义冲突配置(重复的 group+name 端点)与 YAML 语法错误分别做了实测,得到一条比官方语义更关键的热重载时序结论(journalctl 完整实测回显):

Oct 17 20:46:56 gatus[3433]: [main.listenToConfigurationFileChanges] Configuration file has been modified
Oct 17 20:46:56 gatus[3433]: [controller.Handle] Server has shut down successfully
Oct 17 20:46:56 gatus[3433]: [watchdog.monitorEndpoint] Canceling current execution of group=core; endpoint=nginx-health; key=core_nginx-health
Oct 17 20:46:56 gatus[3433]: [main.listenToConfigurationFileChanges] Failed to load new configuration: error parsing config: invalid external endpoint external_tls-badssl: name and group combination must be unique
Oct 17 20:46:56 gatus[3433]: [main.listenToConfigurationFileChanges] The configuration file was updated, but it is not valid. The old configuration will continue being used.

实测行为链(v5.37.0):

  1. 配置文件变更被监听到后,Gatus 先关闭 Web 服务(Server has shut down successfully)并取消进行中的探测;
  2. 校验失败时打印明确原因(本例:name and group combination must be unique;YAML 语法错误时打印形如 yaml: unmarshal errors: line 76: mapping key "group" already defined at line 74 的具体行号);
  3. 失败后保留旧配置继续拨测,但 Web 服务不会自动重启——实测 8080 端口持续 Connection refused,而进程与 systemd 状态仍为 active(systemctl is-active 输出 active,端口却不通);
  4. 修复配置(无需重启进程)后热重载成功,实测服务自动恢复:日志重现启动横幅,curl 恢复 200。

运维结论(实测归纳):

  • 改配置务必先在别处校验 YAML 与参数语义,一次失败就会让 UI/API 停摆(拨测与告警仍在跑,但你看不到面板也调不了 API);
  • 失败后第一修复手段是把配置改对,Gatus 监听到正确文件后自愈,不必重启进程;
  • 自监控与外部探活(拨测 Gatus 自己的 API)因此成为必需,见《Gatus 运维手册》巡检章节;
  • 实测中 skip-invalid-config-update 的 true/false 两态在上述行为链上无差异(失败同样停摆 Web),不要指望该开关兜底。

5.10 endpoints:拨测端点

endpoints 是 Gatus 的主角,每端点决定「探什么、多久探一次、怎么算健康、失败了告警给谁」。端点级核心参数:

参数默认值说明
name必填端点名,与 group 组合成唯一 key({group}_{name})
group空分组名,仪表盘按组分区展示
url必填探测目标;协议头决定类型(http(s)://、tcp://、icmp://,DNS 用 dns 段)
methodGETHTTP 请求方法
conditions[]健康条件列表,全部满足才 UP
interval60s拨测周期
body / headers / graphql空/{}/false请求体/请求头/GraphQL 包装
client{}每端点独立的 HTTP 客户端参数(超时/TLS/代理)
alerts[]该端点的告警绑定
maintenance-windows[]端点级维护窗口
ui.*{}端点级 UI 控制(hide-url 隐藏含 token 的 URL 等)

interval 实测:把 nginx-health 从 30s 改为 15s 并热重载,SQLite 时间戳实测(SELECT endpoint_name, success, timestamp FROM endpoint_results ORDER BY endpoint_result_id DESC LIMIT 6 输出节选):

nginx-health|1|2026-10-17 20:24:43.578307581 +0000 UTC
nginx-health|1|2026-10-17 20:24:28.578762147 +0000 UTC
nginx-missing|1|2026-10-17 20:24:13.799372597 +0000 UTC
nginx-health|1|2026-10-17 20:24:13.578642989 +0000 UTC

相邻两条 nginx-health 间隔 15.0004 秒,新 interval 即时生效。

conditions 失败实测:把条件改为 [STATUS] == 201 后,API 返回的结果带逐条件判定(实测节选,注意没有 errors 键——条件失败不走 errors,errors 只在传输层失败时写入;失败的 condition 会被渲染为 [STATUS] (实际值) == 期望值 形式):

{
  "status": 200,
  "hostname": "gatus-5370-target-nginx",
  "duration": 221275,
  "conditionResults": [
    {
      "condition": "[STATUS] (200) == 201",
      "success": false
    },
    {
      "condition": "[BODY].status == UP",
      "success": true
    }
  ],
  "success": false,
  "timestamp": "2026-10-17T20:53:46.181148016Z"
}

(完整响应结构见《Gatus API 使用详解》)

client 段(每端点覆盖全局 HTTP 客户端):

参数默认值说明
client.timeout10s请求超时
client.insecurefalse跳过 TLS 证书校验(自签证书场景)
client.ignore-redirectfalse不跟随重定向
client.proxy-url空该端点走指定代理
client.dns-resolver系统自定义 DNS 解析器(tcp://1.1.1.1:53 形态)

external-endpoints(外部推送端点,Gatus 不主动探测、由外部程序调用 API 推送状态):

参数默认值说明
external-endpoints[].name / group必填/空同 endpoints,组合成推送 key
external-endpoints[].token必填推送凭据(Bearer Token),实测错误 token 返回 401
external-endpoints[].heartbeat.interval0(禁用)心跳超时:超过该间隔没收到推送自动判失败并告警(最小 10s)

推送接口与实测回显(成功推送、失败推送、错误凭据)见《Gatus API 使用详解》。

5.11 endpoints 常用条件表达式速查

实测验证过的条件表达式汇总(操作符支持 ==、!=、<、>、<=、>=,==/!= 可对字符串):

表达式适用类型实测示例
[STATUS] == 200HTTP状态码断言
[BODY].status == UPHTTP(JSON)响应体 JSON 字段断言
[RESPONSE_TIME] < 1000HTTP响应时间毫秒上限
[CERTIFICATE_EXPIRATION] > 720hHTTPS证书剩余有效期下限
[CONNECTED] == trueTCP/ICMP连通性
[DNS_RCODE] == NOERRORDNS应答状态

此外 [LENGTH](响应长度)、[IP]、[DOMAIN_EXPIRATION] 等占位符可按需组合;body 中可用 [ENDPOINT_NAME]、[RANDOM_STRING_N](防缓存)等占位符。

六、生产配置模板

适用于「16 GB 内存、SSD 磁盘、50~200 个端点、分钟级拨测、单实例」的典型生产场景,全部参数取值依据本篇实测结论:

# /opt/data/gatus-server/config.yaml —— 生产模板(50~200 端点)
metrics: true

web:
  port: 8080

ui:
  title: "服务拨测平台"
  header: "运维监控台"

storage:
  type: sqlite
  path: /opt/data/gatus-server/data/data.db
  caching: true
  maximum-number-of-results: 720        # 每端点保留 12 天 × 60 次/天 的量级
  maximum-number-of-events: 50

concurrency: 16                          # 端点较多时提高并发,避免周期拖长

skip-invalid-config-update: true

alerting:
  custom:
    url: "http://192.168.1.10/alert"     # 对接内部告警网关
    method: "POST"
    body: |
      {"text": "[ALERT_TRIGGERED_OR_RESOLVED]: [ENDPOINT_GROUP] - [ENDPOINT_NAME] - [ALERT_DESCRIPTION] - [RESULT_ERRORS]"}
    default-alert:
      enabled: true
      failure-threshold: 3               # 连续 3 次失败才告警,抗抖动
      send-on-resolved: true

maintenance:
  enabled: true
  start: 03:00
  duration: 1h
  timezone: "Asia/Shanghai"

security:
  basic:
    username: admin
    password-bcrypt-base64: "JDJ5JDEwJExYQkhlYVo0VkRuaU1qbnFITHRkdnV3dU8zNFFyS1BVaHY3L256aDBnd0xVaENlN2NjMmI2"  # admin / q1w2e3r4

endpoints:
  - name: portal-homepage
    group: core
    url: https://www.example.com
    interval: 60s
    client:
      timeout: 10s
    conditions:
      - "[STATUS] == 200"
      - "[CERTIFICATE_EXPIRATION] > 720h"
      - "[RESPONSE_TIME] < 2000"
    alerts:
      - type: custom
        description: "门户首页拨测失败"

模板要点:sqlite+caching 保数据与性能;maximum-number-of-results 按保留天数×频率算;failure-threshold: 3 避免网络抖动误报;证书有效期与响应时间双条件覆盖最常见生产风险;维护窗口避开业务高峰;Basic 认证兜底访问安全。端点超过 200 或需多实例时把 storage.type 换成 postgres。

七、常见问题

Q1:改了配置之后 UI/API 打不开了(8080 连接拒绝)

这是热重载失败的典型现场(实测 5.9):Gatus 收到文件变更会先关 Web 服务再校验,校验失败后 UI/API 停摆但拨测继续。修复:journalctl -u gatus --no-pager -n 20 找 Failed to load new configuration 行确认原因(YAML 语法错误会精确到行号),把配置改对后服务自动恢复,无需重启进程。

按序排查其他不生效场景:① 文件路径不对——systemctl cat gatus 确认 GATUS_CONFIG_PATH 指向的是你改的那个文件;② 改的是环境变量类参数(GATUS_LOG_LEVEL),必须重启;③ ui.title 热重载不刷新已打开页面的标签标题(实测 5.2),重启或新开页面核对。

Q2:default-alert 配了但收不到告警

实测确认:alerting.*.default-alert 只是参数模板,端点侧必须显式声明 alerts: - type: custom(渠道类型),否则告警完全不触发(实测 5.4 的踩坑回放)。

Q3:maximum-number-of-results 改小了,旧数据为什么还在

实测确认旧数据由 Gatus 后台周期性清理,改小/重启都不会立即收缩(实测 5.3),等待清理周期完成即可;若要立刻释放磁盘,停服务后手工 DELETE FROM endpoint_results WHERE ... 并 VACUUM(先备份,见《Gatus 运维手册》)。

Q4:HTTPS 端点报 TLS 校验失败但浏览器能打开

实测案例:拨测自签证书站点 self-signed.badssl.com,API 返回的 errors 精确文本为:

Get "https://self-signed.badssl.com": tls: failed to verify certificate: x509: certificate signed by unknown authority

x509: certificate signed by unknown authority 即系统 CA 库不信任该证书链:若目标是公共站点,说明服务器系统 CA 过旧,升级 CA 包并重启 Gatus(完整排障实录见《Gatus 运维手册》);若是内部自签证书服务,直接给该端点加 client: {insecure: true} 跳过校验(仅限内网可信目标)。

Q5:维护窗口内还在拨测,是不是没生效

这是正常语义(实测 5.5):维护窗口只抑制告警,检测照常执行。

Q6:ICMP 端点全部失败

服务进程需要原始套接字权限:root 运行天然满足(本篇 systemd 实测通过);非 root 运行需 setcap cap_net_raw+ep /usr/local/bin/gatus 或改用 root。

八、参考链接