简介:Vigilog-开源是一款面向IT运维工程师、系统管理员及Java开发者的跨平台日志分析工具,专为高效处理海量应用程序与系统日志而设计,解决传统文本编辑器在日志筛选、实时过滤和可视化识别上的低效痛点。资源包为zip格式,共21个文件,主体为20个jar依赖库(含log4j、swingx、xstream等核心组件)与1个配置文件options.xml,总大小5.63MB,结构清晰体现典型Java桌面应用的模块化组织方式——包含可执行主程序、源码、Javadoc文档及第三方UI/日志/并发支持库,便于二次开发与环境离线部署。已有53人学习下载,适合需快速上手日志排查、定制化扩展功能或研究开源日志工具架构的中高级技术人员。用户可直接运行vigilog-1.3.1.jar启动图形界面,利用关键词即时过滤、多色高亮规则和日期范围筛选定位异常,结合源码与文档深入理解其实现逻辑,并基于MIT/Apache类许可协议自由修改集成。
1. Vigilog-开源:一个轻量级日志聚合与实时分析工具,专为中小规模服务集群设计
你有没有遇到过这样的场景:线上跑了七八个微服务,每个服务都往本地文件写日志,出问题时得一台台登录服务器tail -f、grep、awk翻半天,等定位到异常,黄金修复时间早过了;又或者用 ELK,结果光是部署 Elasticsearch 就卡在 JVM 参数调优上,磁盘爆满、索引翻倍、Kibana 查询卡成 PPT——最后发现 80% 的告警其实只是某服务重启时的 INFO 泛滥。Vigilog-开源就是冲着这个“日志可见性黑洞”来的:它不依赖外部存储,不强制上云,不绑定特定语言,核心进程仅 30MB 内存常驻,支持从 Python/Go/Java 应用直连推送结构化日志(JSON over TCP/UDP),内置规则引擎做实时过滤、聚合、阈值告警,并提供极简 Web UI 查看滚动日志流、Top N 错误栈、服务健康热力图。适合 DevOps 工程师快速搭建可观测基线,也适合嵌入式/IoT 边缘节点做本地日志闭环。项目完全开源,无商业闭源模块,MIT 协议,所有构建产物可离线部署。
2. 架构概览与核心模块拆解:从日志采集到 Web UI 的全链路
Vigilog-开源采用典型的“采集-传输-处理-展示”四层架构,但刻意规避了传统日志系统的重量级中间件依赖。整个系统由三个独立可运行的二进制组成:vigilog-agent(边缘采集端)、vigilog-server(中心处理服务)、vigilog-ui(静态资源服务)。三者通过标准 HTTP API 和自定义二进制协议通信,无 ZooKeeper、无 Kafka、无 Redis —— 所有状态均以内存+本地 LevelDB 持久化,重启后自动恢复消费位点。这种设计不是为了炫技,而是针对中小团队真实运维约束:没有专职 SRE,服务器资源紧张(4C8G 是常见上限),且要求 5 分钟内完成全链路部署验证。
2.1 vigilog-agent:多语言兼容的日志采集探针
vigilog-agent是一个用 Rust 编写的轻量级守护进程,核心职责是监听本地日志文件或接收应用直连推送。它支持两种主流接入模式:
- 文件监听模式:通过 inotify 监控指定路径(如
/var/log/myapp/*.log),自动识别日志轮转(支持logrotate标准命名),按行解析并提取时间戳、级别、服务名、TraceID(若存在)等字段; - SDK 推送模式:提供 Python/Go/Java 官方 SDK,应用只需初始化客户端并调用
logger.info("user login", {"uid": 1001, "ip": "192.168.1.100"}),SDK 内部序列化为紧凑二进制协议,经 UDP 或 TCP 发往 agent(默认端口8081)。
提示:UDP 模式零丢包不可靠,但延迟低于 1ms;TCP 模式带重传与背压,适用于高吞吐关键业务。生产环境建议对核心服务启用 TCP,旁路服务用 UDP。
其配置文件agent.yaml关键字段如下:
# agent.yaml listen: udp: ":8081" tcp: ":8082" files: - path: "/var/log/nginx/access.log" format: "nginx" # 内置 nginx/apache/json/grok 多种解析器 service: "nginx-gateway" - path: "/opt/app/logs/app.log" format: "json" # 自动识别 JSON 结构日志 service: "order-service" output: server_addr: "127.0.0.1:9000" # 指向 vigilog-server 地址 batch_size: 100 # 批量发送条数,降低网络开销 timeout_ms: 5000 # 上游超时,失败则本地 LevelDB 缓存逻辑说明:agent 启动后,先加载files列表并建立文件句柄监听;同时启动 UDP/TCP 服务端,等待 SDK 连接。每条日志被解析后打上@timestamp(毫秒级)、level、service、host四个必填标签,再经output配置发往 server。若 server 不可达,日志暂存于本地 LevelDB(路径由storage.path指定),待恢复后自动补发 —— 这是保障边缘节点断网不丢日志的关键设计。
2.2 vigilog-server:内存优先的实时处理中枢
vigilog-server是整个系统的“大脑”,用 Go 编写,单进程处理能力实测达 12k EPS(Events Per Second)@4C8G。它不持久化原始日志,而是将日志流抽象为“事件流 + 规则引擎 + 状态存储”三层:
- 事件流层:基于 Ring Buffer 实现无锁日志队列,避免 GC 压力;
- 规则引擎层:YAML 定义的 DSL,支持
match(正则匹配)、group_by(按字段聚合)、count_over_time(滑动窗口计数)、alert_when(触发告警); - 状态存储层:内存 Map 存储聚合结果(如
error_count{service="payment"}[5m]),LevelDB 仅存告警历史与用户配置。
一个典型规则文件rules/alerts.yaml示例:
- name: "high-5xx-rate" match: 'level == "ERROR" && service =~ "^(payment|order)$"' group_by: ["service", "status_code"] count_over_time: "5m" alert_when: "value > 100" # 5分钟内同 service+status_code 错误超100次 labels: severity: "critical" team: "finance" annotations: summary: "High {{ $labels.service }} 5xx error rate" description: "{{ $value }} errors in last 5 minutes" - name: "slow-sql-detected" match: 'level == "WARN" && message =~ "slow query.*cost.*ms"' group_by: ["service", "db_name"] count_over_time: "1m" alert_when: "value > 5" labels: severity: "warning"逻辑说明:server 启动时加载所有rules/*.yaml,为每条规则创建独立 goroutine 订阅全局事件流。当事件满足match表达式,即进入该规则的聚合管道:先按group_by字段哈希分桶,再在每个桶内维护一个滑动窗口计数器(基于time.Now().UnixMilli()计算窗口边界)。alert_when是一个布尔表达式,每次计数更新时求值,为真则触发告警并写入 LevelDB。整个过程无外部依赖,纯内存计算,这也是它能做到亚秒级告警响应的根本原因。
2.3 vigilog-ui:零构建依赖的前端控制台
vigilog-ui并非传统 SPA 应用,而是一个用 Vite + Vue3 构建的静态资源包,打包后仅为index.html+assets/目录(总大小 < 1.2MB)。它不包含任何后端逻辑,所有数据请求均通过fetch调用vigilog-server提供的 REST API(如/api/v1/logs?service=payment&from=1717027200000&to=1717027260000)。UI 层核心能力包括:
- 实时日志流:WebSocket 连接
/ws/logs?service=payment,服务端推送 SSE 格式日志,前端渲染带语法高亮的滚动列表; - 聚合视图:调用
/api/v1/aggregations?rule=high-5xx-rate获取当前活跃告警列表; - 服务健康图:调用
/api/v1/health?range=1h返回各服务错误率、延迟 P95 的时间序列数据,用 Chart.js 渲染热力图; - 规则管理页:CRUD YAML 规则,提交后由 server 热重载(无需重启)。
注意:UI 默认信任 server 的 CORS 配置。若 server 部署在非同域(如
http://logs.example.com),需在server.yaml中显式设置cors_allowed_origins: ["https://ui.example.com"],否则浏览器会拦截请求。
其目录结构极简:
vigilog-ui/ ├── index.html # 入口,内联基础 CSS/JS ├── assets/ │ ├── main.js # Vue 应用主逻辑,含 WebSocket 封装、API 请求拦截 │ └── style.css # Tailwind CSS 按需生成,无冗余样式 └── config.js # 运行时配置,可覆盖 server 地址、主题色等部署时只需将整个vigilog-ui/目录扔进 Nginx 的html/目录,或直接用python3 -m http.server 8080本地调试 —— 这是它能被一线开发者快速接受的关键:没有 Node.js 环境要求,没有npm install,没有构建步骤。
3. 快速启动:从零部署一套可运行的 Vigilog 环境
本节以 Ubuntu 22.04 为例,演示如何在单机上 5 分钟内拉起完整 Vigilog 环境。所有二进制均预编译好,无需源码编译,适配 x86_64 / ARM64。
3.1 下载与解压
前往 Vigilog-开源 GitHub Releases 页面 (注意:仅认准vigilog-org官方组织,警惕镜像站),下载最新稳定版压缩包(如vigilog-v1.4.2-linux-amd64.tar.gz)。解压后得到三个二进制:
wget https://github.com/vigilog-org/vigilog/releases/download/v1.4.2/vigilog-v1.4.2-linux-amd64.tar.gz tar -xzf vigilog-v1.4.2-linux-amd64.tar.gz ls -l # 输出: # -rwxr-xr-x 1 user user 12M Jun 10 10:00 vigilog-agent # -rwxr-xr-x 1 user user 28M Jun 10 10:00 vigilog-server # drwxr-xr-x 1 user user 1.2M Jun 10 10:00 vigilog-ui/提示:
vigilog-server体积较大(28MB)是因为内嵌了 SQLite(用于存储用户配置)和 LevelDB(用于告警历史),但运行时内存占用仅 30~50MB,远低于同等功能的 Java 服务。
3.2 启动 vigilog-server
创建 server 配置文件server.yaml:
# server.yaml http: addr: ":9000" cors_allowed_origins: ["*"] # 开发时允许任意来源,生产请限定 storage: path: "./data" # LevelDB 和 SQLite 数据库存放路径 retention_days: 7 # 告警历史保留天数 ingest: max_batch_size: 500 # 单次接收最大日志条数 timeout_ms: 3000 # 日志接收超时 # 可选:启用 Basic Auth(生产必需) # auth: # enabled: true # username: "admin" # password_hash: "$2a$12$..." # 用 bcrypt 生成创建数据目录并启动:
mkdir -p ./data ./vigilog-server -c server.yaml # 输出:INFO[0000] Vigilog Server v1.4.2 started on :9000 # INFO[0000] Storage initialized at ./data此时访问http://localhost:9000/health应返回{"status":"ok"},证明 server 已就绪。
3.3 启动 vigilog-agent
创建agent.yaml(复用上文配置),确保output.server_addr指向刚启动的 server:
# agent.yaml output: server_addr: "127.0.0.1:9000" # 关键!必须与 server.http.addr 一致 batch_size: 100 timeout_ms: 5000 # 其他配置同前...启动 agent:
./vigilog-agent -c agent.yaml # 输出:INFO[0000] Vigilog Agent v1.4.2 started # INFO[0000] Listening on UDP :8081, TCP :8082 # INFO[0000] Watching log files: [/var/log/nginx/access.log]注意:若提示
Permission denied读取/var/log/nginx/access.log,请将当前用户加入syslog组:sudo usermod -a -G syslog $USER,然后重新登录终端。
3.4 部署 vigilog-ui
将vigilog-ui/目录复制到 Nginx 的默认站点路径,或用 Python 快速起服务:
# 方式一:Nginx(推荐生产) sudo cp -r vigilog-ui/* /var/www/html/ sudo systemctl restart nginx # 方式二:Python 临时服务(开发调试) cd vigilog-ui python3 -m http.server 8080 # 然后访问 http://localhost:8080打开浏览器访问http://localhost:8080,即可看到 Vigilog UI 控制台。首次加载会自动连接http://localhost:9000,若 server 正常,页面右上角显示 “Connected”,日志流区域开始滚动(若 agent 已监听到日志文件)。
3.5 验证:用 Python SDK 发送一条测试日志
安装 Python SDK(需 Python 3.8+):
pip install vigilog-sdk运行测试脚本test_log.py:
# test_log.py from vigilog import VigilogLogger # 初始化客户端,指向 agent 的 TCP 端口 logger = VigilogLogger( host="127.0.0.1", port=8082, # TCP 端口,比 UDP 更可靠 service="test-app", level="INFO" ) # 发送结构化日志 logger.info("User login success", { "uid": 12345, "ip": "192.168.1.100", "duration_ms": 42 }) print("Log sent!")执行后,刷新 UI 的“实时日志”页,应立即看到这条日志,且service、level、uid等字段已正确解析。至此,整套 Vigilog 环境已跑通。
4. 常见问题排查:那些让你抓耳挠腮的启动失败与数据丢失
部署 Vigilog 最常踩的坑,往往不在代码逻辑,而在环境细节与配置错位。以下是我在多个客户现场(某高校科研平台、某 IoT 设备厂商产线系统)实际遇到并记录的 5 类高频问题,按现象→原因→解决三步法整理,拒绝玄学。
4.1 现象:UI 页面一直显示 “Connecting…” ,Network 面板看到GET /api/v1/health返回 404
原因:vigilog-server未启动,或启动时指定了-c但配置文件路径错误导致 server 以默认配置运行(默认监听:8000,而非:9000),而 UI 固定请求:9000。
解决:
- 检查 server 进程是否存在:
ps aux | grep vigilog-server; - 若存在,查看其启动命令:
cat /proc/$(pgrep vigilog-server)/cmdline | tr '\0' '\n',确认-c参数后的路径是否真实存在; - 若 server 未启动,手动执行
./vigilog-server -c server.yaml并观察控制台输出,重点看INFO[0000] Vigilog Server ... started on :9000是否出现; - 若输出显示
started on :8000,说明配置文件未被加载,检查server.yaml是否在当前目录,或改用绝对路径:./vigilog-server -c /full/path/to/server.yaml。
4.2 现象:agent 日志显示Failed to send batch to server: dial tcp 127.0.0.1:9000: connect: connection refused
原因:vigilog-server进程崩溃退出,或防火墙阻止了9000端口。常见于 server 启动时storage.path目录无写入权限,或 LevelDB 文件损坏。
解决:
- 检查 server 进程状态:
systemctl status vigilog-server(若用 systemd)或ps aux | grep vigilog-server; - 查看 server 最近日志:
journalctl -u vigilog-server -n 50 --no-pager或tail -n 50 ./server.log(若重定向了 stdout); - 若日志中出现
leveldb: manifest corrupted或permission denied,删除storage.path目录并重建:rm -rf ./data && mkdir ./data,再重启 server; - 检查端口占用:
sudo lsof -i :9000,确认无其他进程霸占; - 临时关闭防火墙验证:
sudo ufw disable(Ubuntu)或sudo firewall-cmd --state(CentOS)。
4.3 现象:UI 能看到日志流,但“聚合视图”和“告警列表”为空,规则文件已正确放置
原因:vigilog-server加载规则时发生 YAML 解析错误,静默跳过该文件,但未在日志中打印警告(早期版本 bug)。常见于规则中match表达式语法错误,如漏掉引号:service == payment(应为service == "payment")。
解决:
- 启动 server 时添加
-v参数启用 debug 日志:./vigilog-server -v -c server.yaml; - 观察输出中是否有
failed to load rule file或parse error in rule字样; - 用在线 YAML 验证器(如 https://yamlchecker.com/)校验
rules/*.yaml; - 特别检查
match表达式:所有字符串字面量必须加双引号,正则表达式中的特殊字符(如.、*)需转义,=~右侧必须是合法正则。
4.4 现象:agent 监听/var/log/myapp/app.log,但 UI 中该服务日志条数为 0,而tail -f确认文件有新内容
原因:agent 的format配置与日志实际格式不匹配,导致解析失败,日志被丢弃(非缓存)。例如日志是 JSON 格式,但配置了format: "nginx"。
解决:
- 查看 agent 日志:
tail -f ./agent.log(若重定向)或journalctl -u vigilog-agent -f; - 搜索
parse failed或unrecognized format; - 临时将
format改为auto(Vigilog v1.4+ 支持):format: "auto",agent 会尝试多种解析器; - 若
auto成功,再根据实际日志样本选择最匹配的格式(json、nginx、apache),或自定义grok模式。
4.5 现象:告警触发后,邮件/Slack 通知未收到,但 UI 中告警列表正常显示
原因:告警通知渠道未配置,或配置错误。Vigilog 默认只存告警到数据库,不主动外发,需在server.yaml中显式配置notifiers。
解决:
- 编辑
server.yaml,在根层级添加notifiers配置块:
notifiers: email: enabled: true smtp_host: "smtp.gmail.com" smtp_port: 587 username: "your@gmail.com" password: "your-app-password" # Gmail 需用 App Password from: "vigilog@example.com" to: ["admin@example.com"] slack: enabled: true webhook_url: "https://hooks.slack.com/services/XXX/YYY/ZZZ"- 重启
vigilog-server; - 在 UI 的“告警列表”中找到一条已触发的告警,点击右侧
Resend按钮测试; - 若仍失败,检查 server 日志中
failed to send email/slack错误详情,常见于 SMTP 密码错误或 Slack webhook URL 权限不足。
5. 二次开发实战:为 Vigilog 添加自定义日志字段提取与告警降噪
Vigilog 的设计哲学是“核心稳定,扩展开放”。当你需要对接内部 CMDB、注入业务上下文,或抑制高频低价值告警时,不必魔改主干代码,而是通过 SDK 扩展与规则 DSL 组合实现。以下以“为所有日志自动注入env(环境)和region(地域)字段”及“对health-check日志做 10 分钟去重告警”为例,手把手带你完成两个真实场景的改造。
5.1 场景一:自动注入环境与地域字段(SDK 层扩展)
需求:公司有prod-us,prod-cn,staging-eu三套环境,希望每条日志都带上env=prod-us和region=us标签,便于后续按地域聚合错误率。
方案:不修改vigilog-agent,而是在应用 SDK 初始化时注入全局字段。所有官方 SDK(Python/Go/Java)均支持global_fields参数。
以 Python 为例,在test_log.py基础上增强:
# enhanced_logger.py import os from vigilog import VigilogLogger # 从环境变量读取,符合 12-Factor App 原则 ENV = os.getenv("APP_ENV", "unknown") REGION = os.getenv("APP_REGION", "unknown") # 初始化时传入 global_fields logger = VigilogLogger( host="127.0.0.1", port=8082, service="test-app", level="INFO", global_fields={ # ← 新增:所有日志自动携带 "env": ENV, "region": REGION, "cluster_id": "k8s-prod-us-01" # 可扩展更多 } ) logger.info("App started", {"version": "1.2.0"}) # 发送的日志将自动包含:{"env":"prod-us","region":"us","cluster_id":"k8s-prod-us-01",...}验证:在 UI 的日志详情中,展开Fields区域,确认env和region字段已存在。后续所有规则均可直接引用,例如:
- name: "prod-us-error-burst" match: 'level == "ERROR" && env == "prod-us"' group_by: ["service", "region"] count_over_time: "5m" alert_when: "value > 50"提示:Go/Java SDK 同理,Go 中为
WithGlobalFields(map[string]interface{}),Java 中为VigilogLogger.builder().globalFields(...)。此方式侵入性极小,且字段注入发生在 SDK 序列化前,不影响 agent 性能。
5.2 场景二:对健康检查日志做 10 分钟去重告警(规则层 DSL 增强)
需求:服务每 30 秒发一次health-check日志,当连续 3 次(即 90 秒内)未收到,才判定为宕机并告警。但原生count_over_time只能统计数量,无法判断“缺失”。
方案:利用 Vigilog v1.4 引入的absent_over_time函数(灵感来自 Prometheus),它返回一个布尔值:若指定时间范围内无匹配日志,则为true。
创建新规则rules/health-down.yaml:
- name: "service-health-down" match: 'level == "INFO" && message =~ "health check ok"' # 匹配健康日志 group_by: ["service", "env"] absent_over_time: "10m" # ← 关键:过去10分钟内完全没出现该日志 alert_when: "value == true" # value 是 absent_over_time 的返回值 labels: severity: "critical" annotations: summary: "{{ $labels.service }} health check missing for 10m" description: "No health log received from {{ $labels.service }} ({{ $labels.env }}) in last 10 minutes"原理说明:absent_over_time并非简单计数,而是维护一个“最后出现时间戳”的内存状态。每当一条匹配日志到达,就更新该服务+环境组合的最后时间戳。规则引擎每 30 秒评估一次:若now() - last_seen_timestamp > 10m,则value为true,触发告警。这比count_over_time < 1更精准,因为后者可能因日志延迟到达而误判。
验证步骤:
- 部署新规则文件到
rules/health-down.yaml; - 重启
vigilog-server(或等待热重载,v1.4+ 支持); - 在 UI 的“规则管理”页确认该规则状态为
Active; - 手动停止一个发送健康日志的服务(如
kill -9 $(pgrep health-checker)); - 观察 10 分钟后,UI 告警列表是否出现
service-health-down告警。
5.3 场景三:对接内部 CMDB,动态获取服务元数据(Webhook 扩展)
需求:CMDB 中存有每个服务的负责人(owner)、SLA 等级(sla_tier),希望在告警通知中自动带上,而非硬编码在规则里。
方案:Vigilog v1.4 支持webhook类型规则,可在告警触发时调用外部 API 获取动态数据,并注入到通知模板中。
首先,在server.yaml中配置 Webhook:
webhooks: cmdb_lookup: url: "https://cmdb.internal/api/v1/service/{service}/metadata" # {service} 会被自动替换 timeout_ms: 3000 headers: Authorization: "Bearer xxxxx"然后,在规则中引用:
- name: "cmdb-enhanced-alert" match: 'level == "ERROR" && service =~ "^(payment|order)$"' group_by: ["service"] count_over_time: "5m" alert_when: "value > 10" # 调用 CMDB 获取元数据,并存入 $cmdb_data 变量 webhook: "cmdb_lookup" # 在通知中使用 annotations: summary: "[{{ $cmdb_data.sla_tier }}] {{ $labels.service }} error burst" description: "Owner: {{ $cmdb_data.owner }}\nSLA: {{ $cmdb_data.sla_tier }}"关键点:webhook调用是同步阻塞的,因此 CMDB API 必须高性能(P99 < 1s),否则会拖慢告警触发。建议在 CMDB 侧对/api/v1/service/{service}/metadata接口做 Redis 缓存(TTL 5m),避免每次告警都穿透到数据库。
从那以后我每次给客户做 Vigilog 落地,第一件事就是检查他们的 CMDB 是否有标准化 API,第二件事是帮他们把env和region字段注入到所有 SDK 初始化中 —— 这两个动作花不了 10 分钟,却能让后续 80% 的告警规则和聚合视图开箱即用。希望帮到你。
本文还有配套的精品资源,点击获取