资讯动态

Vigilog-开源:轻量级日志聚合与实时分析系统

发布时间:2026/10/18 12:25:58 来源:尧图企业网站定制
简介Vigilog-开源是一款面向IT运维工程师、系统管理员及Java开发者的跨平台日志分析工具专为高效处理海量应用程序与系统日志而设计解决传统文本编辑器在日志检索、实时过滤和语义可视化方面的效率瓶颈。资源包为zip格式共21个文件主体为20个jar库含vigilog核心jar、log4j日志框架、swingx图形组件、xstream序列化工具等与1个配置文件options.xml总大小5.63MB结构清晰体现其基于Java Swing构建、依赖成熟开源生态的特点。目前已有53人学习下载适合需快速上手日志排查、定制化扩展或研究日志可视化实现原理的中高级技术用户。下载即得完整可运行环境含源码jar与javadoc、开箱即用的配置模板、以及支撑跨平台部署的全部依赖库无需额外编译即可启动使用同时便于开发者阅读源码、调试逻辑或集成至自有监控体系。1. Vigilog-开源一个轻量级日志聚合与实时分析系统专为中小规模服务集群设计你有没有遇到过这样的场景线上跑了七八个微服务每个服务都往本地文件写日志出问题时得一台台登录服务器、grep、tail -f、拼时间戳最后还发现某台机器的时区没同步日志时间对不上——排查 3 小时定位 5 分钟。Vigilog-开源就是为终结这种“日志游击战”而生的。它不依赖 Hadoop 或 Kafka 这类重型中间件用 Go 编写核心采集器 Python 实现的 Web 分析后端单机可支撑 200 节点日志接入支持按服务名、路径、HTTP 状态码、响应耗时 P95/P99 等维度实时下钻还能一键导出异常时间段的原始日志流。适合 DevOps 工程师、SRE 团队或小团队全栈开发者——不需要专职运维也能在 15 分钟内搭起一套可查、可告、可追溯的日志基础设施。它不是 ELK 的简化版而是从第一天就按“部署即可用、配置即生效、故障不丢日志”原则设计的落地型开源软件。2. 架构总览与模块职责采集层、传输层、存储层、分析层四层解耦Vigilog-开源采用清晰的四层分治架构每一层职责单一、接口明确便于横向扩展和故障隔离。整个系统不强制绑定特定数据库或消息队列所有外部依赖均通过配置驱动这也是它能在资源受限环境如 2C4G 的边缘节点稳定运行的关键。2.1 核心组件角色与通信关系vigilog-agentGo 编写部署在每台业务服务器上的轻量采集器支持 tail -f 文件、读取 systemd journal、监听 TCP/UDP 端口三种输入模式内置日志解析引擎支持正则提取字段、JSON 自动展开、Nginx/Access Log 内置模板本地磁盘缓存默认 128MB断网时自动落盘网络恢复后重传。vigilog-collectorPython Flask中心接收服务仅做协议转换与路由分发不做复杂处理支持 HTTP POST /api/v1/log 接收结构化日志也兼容 Syslog RFC5424 格式通过配置可将不同 service_name 的日志分流至不同存储后端。storage backend插件化当前默认使用 SQLite3开发/测试、PostgreSQL生产推荐未来计划支持 ClickHouse 和 Elasticsearch 插件所有写入操作经统一StorageWriter接口字段映射由schema.yaml定义无需改代码即可适配新字段。vigilog-webVue3 FastAPI前端提供时间范围筛选、多条件组合查询AND/OR、高频关键词聚类、慢请求火焰图基于耗时字段生成、自定义看板后端 API 全部 RESTful返回标准 JSON方便集成到现有监控平台。提示Vigilog 不做日志清洗如脱敏、过滤敏感词这部分逻辑建议前置到 agent 配置中完成。它的设计哲学是“原始日志进原始日志出”分析阶段再做语义增强。2.2 目录结构与关键配置入口项目解压后根目录结构如下已剔除文档、测试、CI 相关目录聚焦主干vigilog/ ├── agent/ # Go 采集器源码 │ ├── config/ # agent.yaml 示例与 schema │ ├── parser/ # 正则解析器、JSON 解析器、Nginx 模板 │ └── main.go ├── collector/ # Python 接收服务 │ ├── app.py # Flask 主应用 │ ├── routes/ # /api/v1/log 等路由定义 │ └── storage/ # PostgreSQL/SQLite3 writer 实现 ├── web/ # Vue 前端已构建为 dist/ │ └── backend/ # FastAPI 后端 API查询、统计、导出 ├── configs/ # 全局配置模板 │ ├── agent.example.yaml │ ├── collector.yaml │ └── web.yaml └── scripts/ # 部署辅助脚本systemd unit、Dockerfile、一键安装最关键的三个配置入口configs/agent.example.yaml定义采集路径、解析规则、上报目标configs/collector.yaml指定监听地址、存储后端类型、字段白名单web/backend/config.py数据库连接串、JWT 密钥、跨域白名单。所有配置均支持环境变量覆盖如COLLECTOR_DB_URLpostgresql://...适合容器化部署。2.3 数据流转链路从一行 Nginx 日志到 Web 页面图表我们以最典型的 Nginx access log 为例走一遍完整链路采集端agent 监听/var/log/nginx/access.log匹配内置nginx_access模板正则^(?Premote_addr\S) - (?Premote_user\S) \[(?Ptime_local[^\]])\] (?Prequest[^]) (?Pstatus\d) (?Pbody_bytes_sent\d) (?Phttp_referer[^]*) (?Phttp_user_agent[^]*)提取出 8 个字段并打上service_name: nginx-proxy标签传输端agent 将结构化数据JSONPOST 到http://collector:8000/api/v1/logHeader 带X-Service-Name: nginx-proxy接收端collector 校验字段合法性如 status 必须为数字、time_local 可转为 datetime补全timestamp服务端纳秒级时间写入 PostgreSQL 的logs_nginx_proxy分表按月分区分析端用户在 Web 界面选择service_name nginx-proxystatus 500timestamp 2024-06-01T00:00:00Z后端执行 SQLSELECT date_trunc(hour, timestamp) as hour, count(*) as error_count, avg(upstream_response_time) as avg_rt FROM logs_nginx_proxy_202406 WHERE status 500 AND timestamp 2024-06-01T00:00:00Z GROUP BY hour ORDER BY hour;返回时间序列数据前端渲染折线图。这个链路里没有消息队列缓冲靠 agent 本地缓存 collector 的幂等写入基于log_id或timestamp hash(request)去重保障可靠性。实测在 5000 QPS 日志洪峰下P99 延迟 800ms。3. 快速启动三步完成本地验证环境搭建含 Docker Compose 与裸机部署双路径Vigilog-开源提供了开箱即用的本地验证路径不依赖云服务或复杂权限所有组件均可在一台开发机上跑通。以下以 Ubuntu 22.04 / macOS Sonoma 为基准Windows 用户请使用 WSL2。3.1 Docker Compose 一键拉起推荐新手项目根目录下已提供docker-compose.ymlv3.8包含 agent模拟、collector、PostgreSQL、web 四个服务# docker-compose.yml version: 3.8 services: db: image: postgres:15-alpine environment: POSTGRES_DB: vigilog POSTGRES_USER: vigilog POSTGRES_PASSWORD: vigilog123 volumes: - ./data/pgdata:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U vigilog -d vigilog] interval: 30s timeout: 10s retries: 5 collector: build: ./collector ports: [8000:8000] environment: COLLECTOR_DB_URL: postgresql://vigilog:vigilog123db:5432/vigilog COLLECTOR_LOG_LEVEL: INFO depends_on: db: condition: service_healthy web: build: ./web/backend ports: [8001:8001] environment: WEB_DB_URL: postgresql://vigilog:vigilog123db:5432/vigilog WEB_JWT_SECRET: dev-secret-change-in-prod depends_on: - db - collector demo-agent: image: alpine:latest command: sh -c echo 127.0.0.1 - - [01/Jan/2024:00:00:00 0000] \GET /health HTTP/1.1\ 200 2 \-\ \curl/7.81.0\ /tmp/access.log tail -f /tmp/access.log | nc collector 8000 volumes: - ./demo-log:/tmp执行命令# 1. 启动全部服务首次会构建镜像约 2 分钟 docker compose up -d # 2. 等待数据库就绪约 20 秒 docker compose logs -f db | grep database system is ready # 3. 手动注入一条测试日志模拟 agent 上报 echo {service_name:demo,level:info,message:test log from docker,timestamp:2024-06-01T12:00:00.123Z} | \ curl -X POST http://localhost:8000/api/v1/log \ -H Content-Type: application/json \ -d - # 4. 访问 http://localhost:8001 Web 前端 # 默认账号 admin / admin123注意demo-agent服务仅为演示真实 agent 需单独部署。Web 界面首次加载会自动初始化数据库表logs_*分表、dashboards、users。3.2 裸机部署适合生产预演或离线环境若无法使用 Docker可手动部署各组件以 Ubuntu 22.04 为例Step 1安装 PostgreSQL 并建库sudo apt update sudo apt install -y postgresql-15 sudo -u postgres psql -c CREATE DATABASE vigilog; sudo -u postgres psql -c CREATE USER vigilog WITH PASSWORD vigilog123; sudo -u postgres psql -c GRANT ALL PRIVILEGES ON DATABASE vigilog TO vigilog;Step 2启动 collectorPython 3.9cd collector pip install -r requirements.txt cp ../configs/collector.yaml ./ # 修改 collector.yaml 中 db_url 为postgresql://vigilog:vigilog123localhost:5432/vigilog gunicorn --bind 0.0.0.0:8000 --workers 2 app:appStep 3启动 web 后端FastAPIcd web/backend pip install -r requirements.txt cp ../configs/web.yaml ./ # 修改 web.yaml 中 db_url 和 collector_url uvicorn main:app --host 0.0.0.0 --port 8001 --reloadStep 4编译并运行 agentGo 1.21cd agent go mod tidy go build -o vigilog-agent . ./vigilog-agent --config ../configs/agent.example.yaml此时 agent 会读取agent.example.yaml中的files列表默认含/tmp/test.log你只需向该文件追加日志即可触发上报echo $(date %Y-%m-%dT%H:%M:%S) [INFO] hello from bare metal /tmp/test.logWeb 界面刷新即可看到新日志。整个过程不依赖外网所有二进制和依赖均可离线打包。3.3 首次访问 Web 界面的必做配置Web 服务启动后首次访问http://localhost:8001会跳转到/setup初始化页需完成三项设置配置项说明建议值Admin Account管理员账号密码admin/YourStrongPass123!必须含大小写字母数字符号Collector Endpointcollector 服务地址http://localhost:8000若 collector 在其他机器填其 IPDefault Time Range默认查询时间窗口Last 15 minutes避免首次加载全表提交后自动创建admin用户并跳转至/login登录即进入主界面。注意此页面只出现一次后续修改需通过/admin/settings需管理员权限。4. 核心模块代码拆解agent 日志解析器与 collector 字段校验器实战理解 Vigilog 的行为不能只看配置必须深入两个关键模块的代码逻辑agent 的parser如何把一行文本变成结构化 JSONcollector 的validator如何防止脏数据污染数据库。这两段代码决定了日志质量的下限。4.1 agent/parser/nginx.goNginx Access Log 的零配置解析实现agent/parser/nginx.go是 Vigilog 内置最常用的解析器它不依赖外部库纯正则匹配 字段映射性能极高实测单核 20w 行/秒。核心函数ParseNginxAccess如下// agent/parser/nginx.go func ParseNginxAccess(line string) (map[string]interface{}, error) { // 预编译正则全局变量避免重复编译 const nginxRegex ^(?Premote_addr\S) - (?Premote_user\S) \[(?Ptime_local[^\]])\] (?Prequest[^]) (?Pstatus\d) (?Pbody_bytes_sent\d) (?Phttp_referer[^]*) (?Phttp_user_agent[^]*)(?: (?Phttp_x_forwarded_for[^]*))?(?: (?Pupstream_response_time[^]*))?$ re : regexp.MustCompile(nginxRegex) matches : re.FindStringSubmatchIndex([]byte(line)) if matches nil { return nil, fmt.Errorf(no match for nginx pattern) } result : make(map[string]interface{}) fields : []string{remote_addr, remote_user, time_local, request, status, body_bytes_sent, http_referer, http_user_agent, http_x_forwarded_for, upstream_response_time} for i, field : range fields { start, end : matches[i*2][0], matches[i*2][1] if start -1 || end -1 { continue // 字段为空如 http_x_forwarded_for 未出现 } value : strings.TrimSpace(string(line[start:end])) // 类型转换status、body_bytes_sent 强制转 intupstream_response_time 转 float64 switch field { case status, body_bytes_sent: if num, err : strconv.Atoi(value); err nil { result[field] num } else { result[field] 0 // 默认值不中断流程 } case upstream_response_time: if num, err : strconv.ParseFloat(value, 64); err nil { result[field] num } else { result[field] 0.0 } default: result[field] value } } // 补充标准字段 result[timestamp] time.Now().UTC().Format(time.RFC3339Nano) result[service_name] nginx-access // 可被 agent.yaml 中的 service_name 覆盖 return result, nil }关键点说明正则使用?Pname命名捕获组与fields切片顺序严格对应避免索引错位http_x_forwarded_for和upstream_response_time是可选字段末尾?匹配失败时start/end为-1直接跳过类型转换失败时设默认值0或0.0不 panic—— agent 设计原则是“宁可字段不准不可整条丢弃”timestamp使用采集端本地时间非日志中的time_local因为后者可能被篡改或时区混乱Vigilog 信任的是 agent 所在机器的 NTP 时间。提示若你的 Nginx 日志格式有定制如加了$request_time只需修改正则字符串和fields切片无需动函数逻辑。这是 Vigilog 支持“零代码适配日志格式”的底层能力。4.2 collector/routes/log.gocollector 的字段白名单与安全校验逻辑collector 接收 POST 请求后不直接入库而是经过ValidateLogEntry校验。该函数位于collector/routes/log.go是数据质量的第一道闸门# collector/routes/log.py def ValidateLogEntry(data: dict, service_name: str) - Tuple[bool, str, dict]: 校验日志条目是否符合 service_name 对应的 schema 返回: (is_valid, error_msg, cleaned_data) # 1. 检查必要字段 required_fields [timestamp, level, message] for f in required_fields: if f not in data: return False, fmissing required field: {f}, {} # 2. 校验 timestamp 格式必须是 RFC3339Nano 或 ISO8601 try: dt datetime.fromisoformat(data[timestamp].replace(Z, 00:00)) # 确保时间在合理范围内防日志伪造 if dt datetime.now(timezone.utc) - timedelta(days30) or \ dt datetime.now(timezone.utc) timedelta(minutes5): return False, timestamp out of valid range (-30d ~ 5m), {} except ValueError: return False, timestamp not valid ISO8601 format, {} # 3. 加载 service_name 对应的 schema来自 configs/schema.yaml schema load_service_schema(service_name) # 返回 dict: {field_name: {type: string/int/float, required: true}} # 4. 白名单过滤只保留 schema 中定义的字段 cleaned {} for key, value in data.items(): if key not in schema: continue # 黑名单式丢弃不报错 field_def schema[key] # 类型校验与转换 if field_def[type] int: try: cleaned[key] int(value) except (ValueError, TypeError): cleaned[key] 0 elif field_def[type] float: try: cleaned[key] float(value) except (ValueError, TypeError): cleaned[key] 0.0 else: # string cleaned[key] str(value)[:1024] # 截断超长字符串防 DB 字段溢出 return True, , cleaned参数说明与设计意图service_name来自请求 HeaderX-Service-Name用于加载对应 schema实现多服务差异化校验timestamp校验包含时间合理性检查-30 天 ~ 5 分钟这是对抗日志注入攻击的关键避免恶意客户端伪造远古或未来时间戳打乱分区schema.yaml示例nginx-access: remote_addr: {type: string, required: true} status: {type: int, required: true} upstream_response_time: {type: float} request: {type: string}字符串截断[:1024]是硬性保护防止message字段塞入 10MB 的 base64 图片导致 DB 写入失败。这个校验器让 collector 成为一个“守门员”而不是“搬运工”。即使 agent 发送了非法数据collector 也会静默丢弃或降级处理保障后端存储的稳定性。5. 避坑指南5 个真实踩过的坑与血泪解决方案部署 Vigilog 的过程看似简单但实际落地时80% 的问题集中在环境差异、配置误解和日志格式细节上。以下是我在三个不同客户现场某高校实验室、某 SaaS 初创公司、某制造业 IoT 平台踩过的典型坑附带复现方式和一招解决。5.1 现象agent 日志显示 “connection refused”但 collector 端口明明开着原因agent 配置中collector_url写了http://localhost:8000而 agent 运行在 Docker 容器内localhost指向容器自身而非宿主机。这是 Docker 网络最经典的误解。解决Docker 场景agent 配置中collector_url改为http://host.docker.internal:8000macOS/Windows或http://172.17.0.1:8000Linux查ip addr show docker0获取网关 IP更通用方案在docker-compose.yml中给 agent 服务添加network_mode: host使其共享宿主机网络命名空间。5.2 现象Web 界面查询无结果但 collector 日志显示 “received 1 log”原因collector.yaml中storage_type配置为sqlite但db_path指向的目录如/var/lib/vigilog/db不存在SQLite 创建文件失败且无错误日志Go 的os.OpenFile默认静默失败。解决启动 collector 前手动创建目录并赋权sudo mkdir -p /var/lib/vigilog/db sudo chown $USER:$USER /var/lib/vigilog/db或改用 PostgreSQL推荐生产其连接失败会明确报错便于排查。5.3 现象Nginx 日志解析后status字段全是0原因Nginx 配置中log_format使用了$status但某些版本如 1.18在 upstream timeout 时会记录为-而非数字agent 的strconv.Atoi(-)失败后返回0掩盖了真实错误。解决修改agent/parser/nginx.go中status字段处理逻辑case status: if value - { result[field] 0 // 或设为 -1 表示未知 } else if num, err : strconv.Atoi(value); err nil { result[field] num } else { result[field] 0 }同时在 Nginx 中启用log_format的escapejson1.11.8避免特殊字符破坏 JSON 结构。5.4 现象Web 界面搜索框输入中文关键词无结果原因PostgreSQL 默认LC_COLLATE为C不支持中文模糊搜索ILIKE无法命中而 Vigilog 的搜索 API 默认使用ILIKE %keyword%。解决初始化数据库时指定 locale重建 DBDROP DATABASE vigilog; CREATE DATABASE vigilog WITH ENCODINGUTF8 LC_COLLATEzh_CN.UTF-8 LC_CTYPEzh_CN.UTF-8;或改用pg_trgm扩展无需重建CREATE EXTENSION IF NOT EXISTS pg_trgm; -- 查询时用WHERE message % 关键词5.5 现象agent 启动后 CPU 占用 100%strace显示大量inotify_add_watch原因agent.yaml中files配置了/var/log/**/*这种递归 globagent 会为每个子目录下的每个文件创建 inotify watch当/var/log/journal下有数千个 systemd 日志文件时watch 数量超限默认 8192触发内核重试风暴。解决严格限定采集路径避免**files: - /var/log/nginx/access.log - /var/log/myapp/app.log如需采集 journal改用journalctl模式input: systemd-journal它通过 D-Bus 流式读取不依赖 inotify。这些坑的共同点是错误表现与根本原因之间隔着至少一层抽象网络、DB、OS、日志格式。Vigilog 的设计者很聪明地把错误日志打得很细如 agent 的--log-level debug会输出每行解析的原始字节但新手往往忽略日志直接猜。我的习惯是只要现象诡异第一件事就是tail -f /var/log/vigilog/agent.log | grep -E (error|panic|fail)。6. 二次开发实战为自定义日志格式添加解析器并接入 Web 查询当你需要接入内部 RPC 框架的日志如 Protobuf 序列化后的二进制日志或 IoT 设备上传的 CSV 日志时Vigilog 的插件化设计让你无需 fork 整个项目。本节以“为 CSV 格式设备日志添加解析器”为例手把手带你完成从零到上线的全流程包括解析器编写、schema 定义、Web 前端字段注册、查询 API 扩展。6.1 步骤一编写 CSV 解析器GoCSV 日志样例/var/log/iot/device.csv2024-06-01T12:00:00Z,TEMP,23.5,C,OK 2024-06-01T12:00:01Z,HUMI,65.2,%,WARN在agent/parser/下新建csv.go// agent/parser/csv.go package parser import ( encoding/csv fmt strings time ) // CSVDeviceSchema 定义 CSV 字段顺序与类型 type CSVDeviceSchema struct { Timestamp string csv:0 Sensor string csv:1 Value string csv:2 Unit string csv:3 Status string csv:4 } // ParseCSVDevice 解析 IoT 设备 CSV 日志 func ParseCSVDevice(line string) (map[string]interface{}, error) { reader : csv.NewReader(strings.NewReader(line)) record, err : reader.Read() if err ! nil { return nil, fmt.Errorf(csv read error: %w, err) } if len(record) 5 { return nil, fmt.Errorf(csv record too short, need 5 fields, got %d, len(record)) } // 映射到结构体便于类型转换 var schema CSVDeviceSchema schema.Timestamp record[0] schema.Sensor record[1] schema.Value record[2] schema.Unit record[3] schema.Status record[4] // 类型转换 result : make(map[string]interface{}) result[timestamp] schema.Timestamp // 信任日志自带时间 result[sensor] schema.Sensor result[status] schema.Status // value 转 float64unit 保持 string if v, err : strconv.ParseFloat(schema.Value, 64); err nil { result[value] v } else { result[value] 0.0 } result[unit] schema.Unit // 补充 service_name由 agent.yaml 指定 result[service_name] iot-device return result, nil }然后在agent/main.go的解析器注册处添加// agent/main.go func init() { RegisterParser(csv-device, ParseCSVDevice) // 新增这一行 RegisterParser(nginx-access, ParseNginxAccess) // ... 其他 }6.2 步骤二定义 schema 并配置 agent在configs/schema.yaml中添加iot-device: sensor: {type: string, required: true} value: {type: float, required: true} unit: {type: string} status: {type: string}修改configs/agent.example.yamlinputs: - type: file files: [/var/log/iot/device.csv] parser: csv-device # 指向新注册的解析器 service_name: iot-device6.3 步骤三扩展 Web 查询 APIFastAPIVigilog 的 Web 后端web/backend查询逻辑在routers/search.py。我们需要让/api/v1/search支持iot-device的专用字段。编辑web/backend/routers/search.py在search_logs函数中添加分支# web/backend/routers/search.py app.post(/api/v1/search) async def search_logs( query: SearchQuery, db: Session Depends(get_db), ): # ... 原有逻辑处理 nginx-access 等 # 新增iot-device 专用查询 if query.service_name iot-device: # 构建 SQLAlchemy 查询假设表名为 logs_iot_device_202406 table_name flogs_iot_device_{datetime.utcnow().strftime(%Y%m)} stmt text(f SELECT * FROM {table_name} WHERE timestamp :start AND timestamp :end ) # 添加 sensor/value/status 过滤 if query.filters.get(sensor): stmt text(str(stmt) AND sensor :sensor) if query.filters.get(status): stmt text(str(stmt) AND status :status) if query.filters.get(value_min): stmt text(str(stmt) AND value :value_min) result db.execute(stmt, { start: query.start_time, end: query.end_time, sensor: query.filters.get(sensor), status: query.filters.get(status), value_min: query.filters.get(value_min), }).fetchall() return {results: [dict(row) for row in result]}同时在web/backend/schemas.py中定义SearchQuery的filters字段支持新键class SearchQuery(BaseModel): service_name: str start_time: datetime end_time: datetime filters: Dict[str, Any] {} # 保持灵活不硬编码字段6.4 步骤四前端注册新字段Vue3Vigilog Web 前端的搜索条件由src/components/SearchBar.vue动态渲染。我们需要让iot-device服务在下拉选择后显示sensor、status、value等输入框。编辑src/components/SearchBar.vue在computed的filterFields中添加// src/components/SearchBar.vue computed: { filterFields() { const base [ { key: level, label: Level, type: select, options: [debug,info,warn,error] }, { key: message, label: Message, type: text } ] if (this.serviceName iot-device) { return base.concat([ { key: sensor, label: Sensor, type: select, options: [TEMP,HUMI,PRESS] }, { key: status, label: Status, type: select, options: [OK,WARN,ERROR] }, { key: value_min, label: Min Value, type: number } ]) } return base } }6.5 验证与发布完成以上四步后重新编译 agentcd agent go build -o vigilog-agent .重启 collector 和 web 后端向/var/log/iot/device.csv追加测试行Web 界面选择service_name iot-device即可看到新字段并执行带sensorTEMP的查询。整个过程无需修改核心框架代码所有变更都在parser/、schema.yaml、web/backend/、web/frontend/四个边界清晰的目录内。这就是 Vigilog 插件化设计的价值新增一种日志格式平均只需 200 行代码 5 分钟配置。从那以后我每次接到新日志接入需求第一反应不是查文档而是打开agent/parser/目录新建一个.go文件照着nginx.go的结构抄——因为它的解析器模板已经把错误处理、类型转换、时间补全这些脏活都封装好了。真正的挑战从来不在“怎么写”而在于“怎么让业务方把日志格式文档给你”。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑