Golang Go语言 + Mongodb 小巧,高性能,低成本日志服务
Qelog是一款小巧低成本轻运维的日志服务。其诞生的目的就是为了解决中小团队多服务群日志和报警问题。
已经稳定运行 2 年+,滚动写入超过 100+TB 数据。
后台示例地址 账号:admin 密码:111111
日志系统特性:
Client
- qelog 是项目的 Go 版本 Client 。Wrap Uber-zap ,扩展功能,对 WriteSyncer 进行本地和远程的实现。
- 本地扩展:日志的切割,压缩,保留期,动态切换等级等。
- 远程扩展:缓冲打包压缩传输日志数据,异常备份重试保证不丢失,支持 GRPC(默认) HTTP 协议,IO 控制保证带宽占用可控,内存占用低等特点。
Log receiver server
- Receiver 进程可横向扩展,保证高可用,高性能。
- 通过对 Receiver 配置多存储实例,提高集群存储容量和写入性能。
- 报警模块,对每条日志进行报警规则检测。命中后可以根据规则和不同的报警方式送达。目前支持 DingTalk | Telegram
- 实现数据分片存储规则,支持自动管理容量,监控预警。存储扩展单独实例,不因中间件而产生瓶颈。
- 日志统计,等级分布,趋势报表等。
Log manager server
- 基于 vue-element-admin 修改,支持丰富的查询维度,比如 等级、关键字、TraceId 、ClientIP 、多级条件等。因成本和性能问题暂不支持全文索引
- 友好的操作交互,简易的配置,高效的内容展示,几乎可做到开箱注册即用。
- 集群容量统计查询,手动干预等功能。
性能测试工具
- /tools 包含 benchmark 与内存占用测试。
- 不同的运行环境和配置有不同的表现,可合理综合分析,初步检测此服务是否满足场景需求。
PS: 生产环境中,该项目经过几轮死循环“攻击”。。。
设计简图
使用建议
Client 端导入项目
go get -u github.com/bbdshow/qelog/qezap
服务快速部署
容器部署
git clone https://github.com/bbdshow/qelog.git
cd qelog
# custom you config
vim config.docker.toml
# build docker image
make image
# docker-compose start container
docker-compose up -d
主机部署
git clone https://github.com/bbdshow/qelog.git
cd qelog
go build, output ./bin
make
cd ./bin
vim configs/config.toml
cd ./admin
admin suggest single server, because have background task
nohup ./qelog_admin -f …/configs/config.toml >> nohup.out 2>&1 &
nohup ./qelog_receiver -f …/configs/config.toml >> nohup.out 2>&1 &
感谢支持,如果对您有用,希望Star以表支持,有问题请提 Issues ,持续更新并解决问题。
Golang Go语言 + Mongodb 小巧,高性能,低成本日志服务
更多关于Golang Go语言 + Mongodb 小巧,高性能,低成本日志服务的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
既然选择了 go 那应该会有 sqlite 版本的吧
更多关于Golang Go语言 + Mongodb 小巧,高性能,低成本日志服务的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
哈哈,想法不错,可以考虑考虑,不过连 docker 拉一个 mongo 就觉得麻烦了嘛 555
生产环境中,该项目经过几轮死循环“攻击”。。。
—
op 能细说下不? 有点感兴趣
哈哈,其实就是有两次团队小伙伴,在写定时任务的时候,有个异常逻辑 select 里面 break 了,并不是退出 for 循环,这个在 Go 语言的 Bug 里面也比较常见。 结果 for 循环了好几个小时,2c4g 的 mongo 写了 8 亿多条数据。最后 mongo 使用内存报警了接近打满了,然后通过后台直接删除异常的 mongo 集合,重启 mongodb 恢复。
简单的看了一下,日志是直接写到 mongodb 里的。 请教下实践中的性能瓶颈以及每日数据的增长量?
嗯,是直接入 DB 的。性能瓶颈,就是 Mongodb 的瓶颈。因为建立索引极其克制,所以批量写入性能很好,
项目 /tools 目录里面有 benchmark 工具,可以依据自己的环境来测试。2c4g 的 mongodb 空集合的情况下 7-8w/s 单条 /350bytes 还是可以的。
针对如果单进程有异常大的日志量,是建议 Bind 一个性能好点的 DB 实例上,进行纵向扩展性能,同时分片时间短一点,比如 7 天一个集合。这样能保证单集合不会过大,导致此进程写入日志性能下降。但是因为 Remote 写入实现是异步的,不会阻塞主进程。短时的峰值流量扛不住或者集群异常,会把日志写入备份本地文件,然后有异步逻辑补偿写入,直到备份文件内容追平。
不同的模块(理解成 APP 进程)可以绑定不同的 mongodb 实例里面,这样写入是分散的。但是做不到自动冷热分布,如果初期无法预估容量,可以通过统计趋势写入量的,然后通过后台手动绑定进程写入到哪个实例,来分布数据的冷热问题,达到均衡使用。
目前,我们部署方式很特殊,我们有很多独立的项目群。 目前网络不互通的 部署了 5 套, 目前最大的集群,日写入量在压缩后有 35G 左右。平均 4000W 条吧,2c4G 的 Mongodb 就可以满足。
谢谢,学习了!
请教下,如果只想保存 Info 以上的日志入库,需要自己写个过滤器不上报低等级的 log ,还是已经内置了这个功能?
qezap.New(qezap.WithLevel(YourLevel)) 默认 DEBUG 。 在初始化指定一下就行。 指定 info, 就是 info 及以上。其他日志级别同理
提个小建议,测试时发现交互流程有点奇怪,比如说表头上的有些筛选项没有填写,require,gte 验证是放在后端做的,而且用户填写错误时直接把后端代码中 exception 作为消息返回是不是不太妥当?
如:Param validator invalid Key: ‘FindLoggingByTraceIDReq.TraceID’ Error:Field validation for ‘TraceID’ failed on the ‘gte’ tag
这块字段验证逻辑放在前端来做是不是更好一些,提示语也可以更直观易懂。🫡
嗯,前端这块不是我的强项,是要优化一下,后面空了,我来弄 详细的 error code 来处理,这块的提醒。目前只有验证类型的错误会直接返回给前端,偷了个懒,哈哈。
写是写进去了,可是这个数量级靠 mongo 这种 db 查询真的没有问题吗?查询耗时大概需要多久?
嗯,你的问题很好!这里我们可以看到,当前系统,不支持 全文搜索,不支持跳条件查询,这都是考虑到 索引大小和查询速度, 而牺牲更大的灵活性。traceId 这种查询就不说了,他是走的单索引。
我们觉得 靠谱的日志打印,一定不是大海捞针 才找到。 一般来说通过 3 个 查询维度,就能缩小到很小的范围。所以我们只建立了一个联合索引,并且查询条件设置顺序 严格表现为 前缀形式, 比如:填了 等级筛选,才能填入短消息筛选,填入一级条件,才能使用二级条件…
我们举一个应用场景:一个进程每天的写入量在 5000W 日志,那么我们设置 此进程 3 天分一片, 那么此模块下,单集合容量差不多在 1.5 亿的情况。这个时候如果时间范围控制的比较好,查询返回是在 毫秒 级别的。因为缓存问题,相似查询条件,第二次查询会更快。
当然这里就会产生一个限制,就是单次最大查询时间范围只有 3 天,我们不支持自动跨集合查询。因为产生了跨集合查询,可能会导致资源占用不可控。
因为我们自定义了 collection 隔离,所以需要大量 IO 查询的情况下,对其他的进程写入和查询也是不受影响的。
我们知道 Count 是很耗时的,所以在查询的时候我们 优化了查询方式,异步最大 Count 5W 条 | MaxTimeout 3s 。 所这里存在的问题就是,日志条件筛选后还大于 5W 条 Count 就是不准的了。
如果写入量还很大,比如一天达到了 3-5 亿,因为我们的最小粒度是天分片。所以 2c4g 的 mongo 对单表 5 亿的筛选是很有压力的。不过还是特别恭喜你!你可以有更多的钱 去升级更好的系统了。 或者升级此系统的 Mongo 也可以!
支持!围观。
请问是否支持第三方导入?比如只用它的 server 端,client 不用 go ,使用其他语言写 log ,然后通过 logstash 或 filebeat 等工具录入
因为是自有协议,目前不支持 公共第三方导入。
/api 有协议编码文件,不过没有详细的文档
感谢,非常好的东西,希望以后能支持第三方收集工具导入,这样就不限制语言了,无痛切换
针对“Golang Go语言 + Mongodb 小巧,高性能,低成本日志服务”的帖子,以下是我的专业回复:
确实,使用Golang结合MongoDB可以构建一个小巧、高性能且低成本的日志服务。
Golang以其简洁的语法、高效的编译器和出色的并发性能,在处理大型数据和高并发场景时表现出色。MongoDB则是一个强大的NoSQL数据库,它提供了灵活的文档存储和高效的查询性能,非常适合存储和检索日志数据。
在构建日志服务时,可以利用Golang的并发特性来高效地处理日志数据的写入和查询。同时,MongoDB的灵活性和可扩展性也能够满足日志数据的不断增长和复杂查询需求。
为了降低成本,可以选择使用开源的Golang MongoDB驱动程序,并部署在云服务器或轻量级容器中。此外,通过合理的索引设计和查询优化,可以进一步提高日志服务的性能和响应速度。
综上所述,Golang结合MongoDB是一个构建小巧、高性能且低成本日志服务的优秀选择。它不仅能够满足基本的日志存储和查询需求,还能够在高并发场景下保持出色的性能和稳定性。