返回首页

Go 上的 Pusk 16 MB 告警服务器

Pusk — Go 上的紧凑自托管告警服务器,大小 16 MB。支持 Telegram 机器人迁移、Alertmanager 中的 ACK 和静默、NAT 的 WebSocket。无需外部数据库,支持 PWA 和推送通知。

Pusk:无依赖的 16 MB 告警服务器
Advertisement 728x90

Pusk:一款仅16 MB的Go语言自托管告警服务器

Pusk是一款自托管解决方案,无需依赖外部消息平台进行监控。单个16 MB可执行文件支持13种Telegram Bot API方法、WebSocket、Web Push和PWA客户端。它无需PostgreSQL或其他数据库,仅使用纯Go编写的SQLite。专为因限制、封锁或隔离导致外部API不可用的场景设计。

架构上排除了外部服务。选择Go语言是因为其快速构建(7秒)和内置的net/http。数据库使用modernc.org/sqlite,无需CGO,启动时RSS约为4 MB。日志通过slog以JSON或文本格式处理。

为何不选用标准消息平台?

替代方案需要迁移、数据库和大量资源:

Google AdInline article slot

| 平台 | 依赖项 | 机器人兼容性 | ACK | 内存 |

|-----------|-------------|---------------------|-----|-----|

| Mattermost | PostgreSQL、SMTP | 需重写 | 插件 | 500+ MB |

Google AdInline article slot

| Matrix | Synapse、PostgreSQL | 需重写 | 否 | 500+ MB |

| Telegram | 云端 | — | 否 | — |

Gotify/ntfy仅提供推送通知,无聊天或ACK功能。使用VPN连接Telegram会增加故障点。Pusk模拟Bot API:只需更改机器人中的base_url,即可与您的基础设施协同工作。

Google AdInline article slot

二进制结构

pusk (16 MB,约6600行Go代码,110个测试)
├── Bot API    — /bot/<token>/<method>  (支持13种Telegram Bot API方法,共80+种)
├── Client API — /api/*                 (PWA后端)
├── WebSocket  — /api/ws                (实时状态、输入提示)
├── Web Push   — FCM / Mozilla          (无需轮询的通知)
├── Files      — /file/<id>             (媒体文件)
├── PWA        — /                      (Web客户端)
└── SQLite     — data/orgs/*/pusk.db    (每个组织独立的数据库)

支持的方法:sendMessage、editMessageText、deleteMessage、answerCallbackQuery、sendPhoto、sendDocument、sendVoice、sendVideo、setWebhook、deleteWebhook、getWebhookInfo、getMe、getUpdates。

兼容性中间件:

func TelegramCompat(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        p := r.URL.Path
        if strings.HasPrefix(p, "/bot") && !strings.HasPrefix(p, "/bot/") {
            r.URL.Path = "/bot/" + p[4:]
        }
        next.ServeHTTP(w, r)
    })
}

从python-telegram-bot迁移:

# 之前:
app = ApplicationBuilder().token(TOKEN).build()

# 之后:
app = ApplicationBuilder().token(TOKEN).base_url("https://pusk.internal/bot").build()

长轮询与更新推送

/getUpdates在超时秒数内保持连接,考虑偏移量,使用内存队列(每个机器人100条更新)。重启后,机器人可接收后续告警,无需持久化。

对于NAT后的机器人——WebSocket中继:

import websockets, json, asyncio

async def relay():
    async with websockets.connect("wss://pusk.internal/bot/TOKEN/relay") as ws:
        async for msg in ws:
            update = json.loads(msg)
            print(update["message"]["text"])

asyncio.run(relay())

自动选择:webhook(带SSRF防护)、中继(限速30条/分钟)或getUpdates。

按组织SQLite与热备份

每个组织在WAL模式下有独立的pusk.db。写入时不阻塞读取。备份:sqlite3 pusk.db ".backup backup.db"。适用于每分钟数十条消息的场景,无需PostgreSQL JOIN。

工作流程

  • 管理员启动服务器(docker run或二进制文件),创建组织——生成#general频道和系统机器人。
  • 通过链接邀请(7天有效期,最多50人),聊天中自动通知。
  • 创建#alerts频道,从Zabbix/Grafana/Alertmanager设置webhook(?format=alertmanager)。
  • 值班:推送/WebSocket、ACK按钮,整个团队可见状态。

角色:

  • 管理员:完全权限 + 用户/频道管理。
  • 成员:聊天、ACK、文件、@提及。

告警增强功能

  • ACK → 静默:通过PUSK_ALERTMANAGER_URL向Alertmanager发送POST /api/v2/silences。
  • 颜色标识:红色/绿色条纹表示触发/已解决。
  • 推送优化:如果WebSocket活跃且频道开放,跳过推送。
  • 隔离:前端嵌入,无CDN。Web Push需要FCM/Mozilla。

核心特性

  • 单个16 MB二进制文件,无外部依赖,Go语言SQLite。
  • 部分模拟Telegram Bot API,迁移无需重写。
  • ACK带自动静默Alertmanager,颜色编码状态指示器。
  • WebSocket中继支持NAT、速率限制、SSRF防护。
  • PWA带推送、管理员/成员角色、按组织隔离。

— Editorial Team

Advertisement 728x90

继续阅读