首页
/ Beszel告警系统与通知集成

Beszel告警系统与通知集成

2026-02-04 05:19:14作者:翟江哲Frasier

Beszel告警系统采用智能化的阈值检测和时间窗口聚合机制,支持多种监控指标(CPU、内存、磁盘、网络带宽、温度传感器和负载平均值等),有效避免瞬时波动导致的误报。系统通过Shoutrrr库集成30+种通知服务(如Discord、Slack、即时通讯工具等),提供灵活可靠的多通道告警通知解决方案。

告警规则配置与触发机制

Beszel的告警系统采用了智能化的阈值检测和时间窗口聚合机制,能够有效避免瞬时波动导致的误报,同时确保重要异常能够及时被发现。该系统支持多种监控指标,包括CPU使用率、内存使用率、磁盘空间、网络带宽、温度传感器和负载平均值等。

告警规则配置结构

每个告警规则包含以下核心配置参数:

参数名 类型 描述 示例值
name string 监控指标名称 "CPU", "Memory", "Disk"
value float64 阈值数值 80.0 (表示80%)
min uint8 持续时间(分钟) 5 (需要持续5分钟)
system string 关联的系统ID "system123"
user string 创建告警的用户ID "user456"
triggered bool 当前触发状态 false

支持的监控指标类型包括:

  • CPU: CPU使用率百分比
  • Memory: 内存使用率百分比
  • Disk: 磁盘使用率百分比(自动检测所有分区)
  • Bandwidth: 网络带宽使用率(MB/s)
  • Temperature: 温度传感器数值(°C)
  • LoadAvg1/5/15: 1分钟/5分钟/15分钟平均负载

触发机制工作原理

Beszel的告警触发机制采用时间窗口聚合算法,确保告警的准确性和可靠性:

flowchart TD
    A[系统数据更新] --> B[获取系统所有告警规则]
    B --> C{检查每个告警规则}
    C --> D[计算当前指标值]
    D --> E{触发条件判断}
    E -->|min=1| F[立即发送告警]
    E -->|min>1| G[收集历史统计数据]
    G --> H[计算时间窗口平均值]
    H --> I{平均值 > 阈值?}
    I -->|是| J[标记为触发状态]
    I -->|否| K[标记为恢复状态]
    J --> L[发送告警通知]
    K --> M[发送恢复通知]

时间窗口聚合算法

对于需要持续监测的告警规则(min > 1),Beszel采用以下算法:

  1. 数据收集: 从系统统计记录中获取指定时间范围内的历史数据
  2. 数值聚合: 对每个时间点的指标值进行累加求和
  3. 平均值计算: 根据数据点数量计算时间窗口内的平均值
  4. 阈值比较: 将平均值与预设阈值进行比较
// 算法核心代码示例
func (am *AlertManager) HandleSystemAlerts(systemRecord *core.Record, data *system.CombinedData) error {
    // 获取系统所有告警规则
    alertRecords, err := am.hub.FindAllRecords("alerts",
        dbx.NewExp("system={:system} AND name!='Status'", dbx.Params{"system": systemRecord.Id}),
    )
    
    for _, alertRecord := range alertRecords {
        // 计算当前指标值
        var val float64
        switch alertRecord.GetString("name") {
        case "CPU":
            val = data.Info.Cpu
        case "Memory":
            val = data.Info.MemPct
        // ... 其他指标类型
        }
        
        // 时间窗口聚合计算
        if alertRecord.GetUint8("min") > 1 {
            // 收集历史统计数据
            systemStats := am.getHistoricalStats(systemRecord.Id, alertRecord.GetUint8("min"))
            // 计算平均值
            averageValue := calculateAverage(systemStats, alertRecord.GetString("name"))
            // 触发判断
            if averageValue > alertRecord.GetFloat("value") {
                am.triggerAlert(alertRecord, averageValue)
            }
        }
    }
    return nil
}

多分区磁盘监控

对于磁盘使用率告警,Beszel智能检测所有分区并选择使用率最高的分区作为判断依据:

flowchart LR
    A[磁盘监控] --> B[检测根分区]
    A --> C[检测额外文件系统]
    B --> D[计算使用率]
    C --> E[计算使用率]
    D --> F[选择最大值]
    E --> F
    F --> G[与阈值比较]

温度传感器监控

温度告警支持多个传感器,系统会自动选择温度最高的传感器作为监控目标:

// 温度传感器处理逻辑
case "Temperature":
    if alert.mapSums == nil {
        alert.mapSums = make(map[string]float32, len(stats.Temperatures))
    }
    for key, temp := range stats.Temperatures {
        alert.mapSums[key] += temp
    }
    // 选择最高温度传感器
    maxTemp := float32(0)
    for key, value := range alert.mapSums {
        sumTemp := value / float32(alert.count)
        if sumTemp > maxTemp {
            maxTemp = sumTemp
            alert.descriptor = fmt.Sprintf("Highest sensor %s", key)
        }
    }
    alert.val = float64(maxTemp)

状态恢复机制

Beszel不仅能够检测异常状态,还能智能识别状态恢复:

  • 当指标值从高于阈值变为低于阈值时,自动发送恢复通知
  • 恢复通知包含相同的上下文信息,便于用户了解系统状态变化
  • 支持配置不同的恢复阈值(可选)

配置示例

以下是一个完整的告警规则配置示例:

{
  "name": "CPU",
  "value": 85.0,
  "min": 5,
  "system": "sys-123456",
  "user": "user-789012",
  "triggered": false
}

这个配置表示:当CPU使用率在5分钟内持续超过85%时触发告警,当使用率回落到85%以下时发送恢复通知。

Beszel的告警规则配置灵活且强大,通过时间窗口聚合算法有效过滤瞬时波动,确保告警的准确性和可靠性,为系统监控提供了专业级的告警解决方案。

Shoutrrr通知服务集成

Beszel通过集成Shoutrrr库提供了强大的通知服务支持,允许用户将告警信息推送到多种流行的消息平台和服务。Shoutrrr是一个通用的通知库,支持超过30种不同的通知服务,包括Discord、Slack、即时通讯工具、Email、Pushover等。

Shoutrrr配置格式

Beszel使用标准的Shoutrrr URL格式来配置通知服务。URL的基本结构如下:

scheme://[username[:password]@]host[:port][/path][?query=value[&query2=value2]]

以下是一些常见的配置示例:

# Discord Webhook
discord://webhook_id/webhook_token

# Slack Webhook
slack://token-a/token-b/token-c

# 即时通讯工具 Bot
im://bot_token@im/?chats=channel_id

# Pushover
pushover://shoutrrr:token@userkey/?devices=device1,device2

# Generic Webhook
generic://webhook.site/your-unique-id

支持的协议和服务

Beszel通过Shoutrrr支持以下主要通知协议:

协议 服务 配置示例
discord Discord discord://webhook_id/webhook_token
slack Slack slack://token-a/token-b/token-c
im 即时通讯工具 im://bot_token@im/?chats=channel_id
pushover Pushover pushover://shoutrrr:token@userkey/?devices=device1,device2
gotify Gotify gotify://gotify.example.com/token
matrix Matrix matrix://user:password@matrix.org/?rooms=!room_id
ntfy ntfy.sh ntfy://ntfy.sh/topic
generic 通用Webhook generic://webhook.site/your-id

消息格式定制

Beszel的告警系统会根据不同的通知服务自动调整消息格式:

flowchart TD
    A[告警触发] --> B{解析Shoutrrr URL}
    B --> C[识别服务类型]
    C --> D{支持标题的服务?}
    D -->|是| E[添加title参数]
    D -->|否| F[标题嵌入消息体]
    E --> G[格式化消息内容]
    F --> G
    G --> H[发送通知]

对于支持标题的服务(如Discord、Slack、即时通讯工具等),Beszel会使用URL查询参数添加标题:

// 在SendShoutrrrAlert方法中的标题处理逻辑
if _, ok := supportsTitle[scheme]; ok {
    queryParams.Add("title", title)
} else if scheme == "mattermost" {
    message = "##### " + title + "\n\n" + message
} else {
    message = title + "\n\n" + message
}

链接处理机制

不同的通知服务对链接的处理方式各不相同,Beszel针对每种服务进行了优化:

sequenceDiagram
    participant A as AlertManager
    participant S as Shoutrrr Service
    A->>S: 解析URL scheme
    Note right of S: 识别服务类型
    alt ntfy服务
        S->>S: 添加Actions参数
    else lark服务
        S->>S: 添加link参数
    else bark服务
        S->>S: 添加url参数
    else 其他服务
        S->>S: 链接附加到消息末尾
    end
    S->>S: 发送格式化消息

配置验证和测试

Beszel提供了完整的配置验证和测试功能:

// 前端验证逻辑
const NotificationSchema = v.object({
    emails: v.array(v.pipe(v.string(), v.email())),
    webhooks: v.array(v.pipe(v.string(), v.url())),
})

// 测试通知发送API
async function sendTestNotification(url: string) {
    const res = await pb.send("/api/beszel/test-notification", {
        method: "POST",
        body: { url }
    })
    return res
}

用户可以在设置界面直接测试每个Webhook配置:

  1. 在通知设置页面添加Shoutrrr URL
  2. 点击"Test URL"按钮发送测试通知
  3. 查看目标服务是否收到测试消息
  4. 根据测试结果调整配置

多服务同时通知

Beszel支持配置多个通知服务,当告警触发时会向所有配置的服务发送通知:

// 多服务发送逻辑
for _, webhook := range userAlertSettings.Webhooks {
    if err := am.SendShoutrrrAlert(webhook, data.Title, data.Message, data.Link, data.LinkText); err != nil {
        am.hub.Logger().Error("Failed to send shoutrrr alert", "err", err)
    }
}

这种设计确保了告警信息的高可靠性传递,即使某个服务暂时不可用,其他服务仍然能够接收通知。

错误处理和日志记录

系统提供了完善的错误处理和日志记录机制:

err = shoutrrr.Send(parsedURL.String(), message)
if err == nil {
    am.hub.Logger().Info("Sent shoutrrr alert", "title", title)
} else {
    am.hub.Logger().Error("Error sending shoutrrr alert", "err", err)
    return err
}

所有发送操作都会记录详细的日志,包括成功发送的通知和遇到的错误,便于运维人员监控通知系统的状态。

通过Shoutrrr集成,Beszel为用户提供了灵活、可靠的通知解决方案,能够满足各种监控场景下的告警需求。用户可以根据自己的偏好选择最适合的通知服务,确保重要告警信息能够及时送达。

多通道告警通知实现

Beszel的告警系统采用了高度灵活的多通道通知机制,通过集成Shoutrrr库实现了对30+种通知服务的原生支持。这种设计让用户可以根据自己的偏好和工作流程选择最适合的通知方式,确保关键告警信息能够及时送达。

通知通道架构设计

Beszel的多通道通知系统采用模块化设计,核心组件包括:

flowchart TD
    A[告警触发] --> B[AlertManager]
    B --> C{获取用户设置}
    C --> D[邮件通知]
    C --> E[Webhook通知]
    D --> F[SMTP服务器]
    E --> G[Shoutrrr路由]
    G --> H[30+种通知服务]

支持的通信协议和服务

Beszel通过Shoutrrr库支持广泛的通信协议和通知服务:

协议类型 支持的服务 特点
即时消息 Discord, Slack, 即时通讯工具, Matrix, Lark, Zulip 实时推送,支持富文本格式
推送通知 Pushbullet, Pushover, Ntfy, Bark, Gotify 移动设备推送,支持自定义声音
企业工具 Teams, Opsgenie, Mattermost 企业级集成,支持工作流
Webhook Generic webhooks, IFTTT, Join 高度自定义,支持任意系统集成
邮件 SMTP协议 传统可靠,支持多收件人

配置管理实现

用户通知设置通过统一的JSON结构进行管理:

type UserNotificationSettings struct {
    Emails   []string `json:"emails"`
    Webhooks []string `json:"webhooks"`
}

前端界面提供直观的配置面板,支持动态添加和测试通知URL:

// 前端配置组件
const [webhooks, setWebhooks] = useState(userSettings.webhooks ?? [])
const [emails, setEmails] = useState<string[]>(userSettings.emails ?? [])

function addWebhook() {
    setWebhooks([...webhooks, ""])
}

智能消息路由机制

Beszel实现了智能的消息路由机制,根据不同服务的特性自动调整消息格式:

func (am *AlertManager) SendShoutrrrAlert(notificationUrl, title, message, link, linkText string) error {
    parsedURL, _ := url.Parse(notificationUrl)
    scheme := parsedURL.Scheme
    queryParams := parsedURL.Query()

    // 智能标题处理
    if _, ok := supportsTitle[scheme]; ok {
        queryParams.Add("title", title)
    } else if scheme == "mattermost" {
        message = "##### " + title + "\n\n" + message
    }

    // 智能链接处理
    if scheme == "ntfy" {
        queryParams.Add("Actions", fmt.Sprintf("view, %s, %s", linkText, link))
    } else if scheme == "lark" {
        queryParams.Add("link", link)
    }
    
    return shoutrrr.Send(parsedURL.String(), message)
}

服务特定优化

针对不同通知服务,Beszel实现了特定的优化策略:

Discord/Slack集成

  • 支持Markdown格式渲染
  • 自动嵌入系统信息和跳转链接
  • 支持@提及和频道选择

Ntfy推送

  • 原生支持操作按钮
  • 优先级和标签设置
  • 离线消息队列

邮件通知

  • 多收件人支持
  • HTML和纯文本双格式
  • 自定义发件人信息

测试与验证机制

为确保通知配置的正确性,Beszel提供了完整的测试功能:

const sendTestNotification = async (url: string) => {
    const res = await pb.send("/api/beszel/test-notification", {
        method: "POST",
        body: { url }
    })
    // 显示测试结果反馈
}

测试流程包括:

  1. URL格式验证(Valibot库)
  2. 服务连通性检查
  3. 消息格式验证
  4. 发送状态反馈

错误处理与重试机制

多通道通知系统实现了完善的错误处理:

for _, webhook := range userAlertSettings.Webhooks {
    if err := am.SendShoutrrrAlert(webhook, data.Title, data.Message, data.Link, data.LinkText); err != nil {
        am.hub.Logger().Error("Failed to send shoutrrr alert", "err", err)
        // 记录失败但继续尝试其他通道
    }
}

性能优化策略

为保障大规模部署下的性能,系统采用:

  • 异步消息队列处理
  • 连接池和超时控制
  • 批量消息发送优化
  • 失败通知的指数退避重试

这种多通道通知架构确保了Beszel在各种环境下的可靠运行,从个人服务器到企业级部署都能提供稳定及时的通知服务。用户可以根据实际需求灵活组合不同的通知方式,构建最适合自己工作流程的告警体系。

告警历史记录与状态管理

Beszel的告警系统不仅提供实时监控和通知功能,还具备完整的告警历史记录与状态管理机制。这一机制确保了告警信息的持久化存储、状态追踪以及历史数据分析能力,为用户提供了全面的告警生命周期管理。

告警历史记录架构

Beszel采用PocketBase作为后端数据存储,告警历史记录存储在专门的alerts_history集合中。每个告警历史记录包含以下核心字段:

字段名 类型 描述
alert_id string 关联的告警规则ID
user string 用户ID
system string 系统ID
name string 告警名称(如CPU、内存等)
value float64 触发时的指标值
created datetime 告警触发时间
resolved datetime 告警解决时间(可为空)
classDiagram
    class AlertHistoryRecord {
登录后查看全文
热门项目推荐
相关项目推荐