ELK太重?试试KFC日志采集
写在前面
ELK三剑客(ElasticSearch,Logstash,Kibana)基本上可以满足日志采集、信息处理、统计分析、可视化报表等一些日志分析的工作,但是对我们来说……太重了,并且技术栈不是一路的。我们的场景是需要采集各个业务部门服务器上面的各个业务系统,所以尽量不要影响到服务器的性能,以侵入性最低的方式进行采集,不做其他多余操作。因而,在前端日志采集这块,对比其他Logstash、Flume等采集工具之后,决定采用轻量的Filebeat作为日志采集工具,Filebeat采用go开发,运行不需要额外部署环境,相比Flume依赖jdk轻量了不少,且占用内存低。
采集链路如下所示:Filebeat日志采集、处理转换之后,推送到kafka,采用Clickhouse的kafka引擎进行消费存储。因而,我暂且称之为KFC组合。

Filebeat部署
采集目标环境:
系统:Window Server 2008 R2 Enterprise
日志类别:IIS日志、业务系统日志
日志路径:D:/IIS/www.A.com/logs/*.txt 、D:/IIS/www.B.com/logs/*.txt、D:/IIS/www.C.com/logs/*.txt
Filebeat:7.12.1(https://www.elastic.co/cn/downloads/beats/filebeat)

因为采集的是windows操作系统,建议下载Filebeat压缩包,并以windows服务的方式运行,使用安装包msi安装不方便调试,需要频繁的卸载、安装操作,下载之后解压出来进行对配置文件 filebeat.yml 进行配置。
业务系统日志格式示例:
2021-04-06 11:21:17,940 [39680] DEBUG Zc - time:0ms update XXX set ModifyTime=GETDATE(), [State] = 190, [FuZeRen] = '张三' where [ID] = '90aa9a69-7a33-420e-808c-624693c65aef' and [CompanyID] = '9e52867e-2035-4148-b09e-55a90b3020d5'
2021-04-06 11:21:21,612 [22128] DEBUG Service ModelBase - time:0ms (/api/XXX/XXX/XXX?InfoID=6d43b831-6169-46d2-9518-f7c9ed6fe39c&ValidateStatus=1)更新材料状态
2021-04-06 11:21:21,612 [22128] DEBUG Zc - time:0ms select ID from XXX where InfoRelationID='6d43b831-6169-46d2-9518-f7c9ed6fe39c'
2021-04-06 11:21:21,612 [22128] DEBUG Zc - time:0ms insert into XXXX(ValidateDate ,[ID],[ValidateState],[ValidateUser],[ValidateUserID],[ValidateUnit],[ValidateUnitID],[ValidateUnitType],[InfoRelationID]) values( GETDATE(),'c77cf4ab-71b5-46c7-b91b-2829d73aa700',1,'XXXX','0387f889-e1d4-48aa-b275-2241da1d2c9e','XXXXX有限公司','2f2a94c8-c23c-4e8a-98b3-c32a9b0487f7',0,'6d43b831-6119-46d2-9518-f7c9ed6fe39c')
2021-04-06 03:25:22,237 [46840] ERROR ASP.global_asax - time:0ms 客户端信息:Ip:116.238.55.21, 173.131.245.61 浏览器:Chrome 版本:68 操作系统:WinNT服务端错误信息:
页面:http://www.A.com:803/dbapp_53475dbapp_e524534.php
错误源:System.Web.Mvc
堆栈跟踪: at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
FileBeat配置:
max_procs: 2
queue:
mem:
events: 2048
flush.min_events: 2048
# ============================== Filebeat inputs =============================== filebeat.inputs: # 管理系统
- type: log
enabled: true
encoding: GB2312
paths:
- D:/IIS/www.A.com/logs/*.txt multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
multiline.negate: true
multiline.match: after
fields:
topic: 'dlbZcZGBSyslogs'
fields_under_root: true # 单位系统
- type: log
enabled: true
encoding: GB2312
paths:
- D:/IIS/www.B.com/logs/*.txt
### Multiline options
multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
multiline.negate: true
multiline.match: after
fields:
topic: 'dlbZcDWSyslogs'
fields_under_root: true # 个人系统
- type: log
enabled: true
encoding: GB2312
paths:
- D:/IIS/www.C.com/logs/*.txt
### Multiline options
multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
multiline.negate: true
multiline.match: after
fields:
topic: 'dlbZcMySyslogs'
fields_under_root: true # 调试输出
#output.console:
# pretty: true
#output.file:
# path: "D:/bigData"
# filename: filebeat.log # -------------------------------- Kafka Output --------------------------------
output.kafka:
# Boolean flag to enable or disable the output module.
enabled: true
hosts: ["192.168.1.10:9092"] # The Kafka topic used for produced events. The setting can be a format string
# using any event field. To set the topic from document type use `%{[type]}`.
topic: '%{[topic]}' # Authentication details. Password is required if username is set.
#username: ''
#password: '' # The number of concurrent load-balanced Kafka output workers.
worker: 2 max_message_bytes: 10000000 # ================================= Processors =================================
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
- script:
lang: javascript
id: my_filter
tag: enable
source: >
function process(event) {
var str = event.Get("message");
var sp = str.split(" ");
var log_datetime = sp.slice(0,2).join(" ");
var regEx = /^\d{4}-\d{2}-\d{2}$/;
var prefix_date = log_datetime.substring(0, 10);
if(prefix_date.match(regEx) != null)
{
event.Put("server","221");
log_datetime = log_datetime.replace(",",".");
log_datetime = log_datetime.replace("'","");
regEx = /^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3}$/;
if(log_datetime.match(regEx) != null)
{
event.Put("log_datetime",log_datetime);
event.Put("log_index",sp.slice(2,3).join(" ").replace("[","").replace("]",""));
event.Put("log_level",sp.slice(3,4).join(" "));
if(str.match(/(?<=time:)\S*(?=ms)/)!=null)
{
var spTime= str.split("time:");
var spPre = spTime[0].split(" ");
var spNext = spTime[1].split(" ");
event.Put("log_class",spPre.slice(4).join(" ")); var log_execTime= spNext.slice(0,1).join(" ").replace("ms","");
regEx = /^(\-|\+)?\d+(\.\d+)?$/;
if(regEx.test(log_execTime))
{
event.Put("log_execTime",log_execTime);
}
else
{
event.Put("log_execTime","-1");
}
event.Put("log_message",spNext.slice(1).join(" "));
}
else
{
event.Put("log_class",sp.slice(4,5).join(" "));
event.Put("log_execTime","-1");
event.Put("log_message",sp.slice(6).join(" "));
}
return;
}
}
event.Cancel();
}
- drop_fields:
fields: ["@timestamp", "message", "host", "ecs", "agent", "@metadata", "log", "input"]
以上的配置说明:
max_procs:设置可以同时执行的最大CPU数;
queue :内部队列信息;
Filebeat inputs:日志数据源采集的入口;
其他字段如下说明:
#日志类型
- type: log
#开启
enabled: true
#编码格式,有中文必须设置
encoding: GB2312
#路径
paths:
- D:/IIS/www.A.com/logs/*.txt
#多行匹配前缀
multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
#开启多行匹配
multiline.negate: true
#开启多行之后,匹配是合并到上一条信息
multiline.match: after
#增加一个字段,用于kafka的topic的识别
fields:
topic: 'dlbZcZGBSyslogs'
# 字段增加在输出json的根目录下
fields_under_root: true
//https://www.cnblogs.com/EminemJK/p/15165961.html
Kafka Output:kafka的配置信息,主要是 topic: '%{[topic]}' 的设置,因为这里采集多个数据源,对于不同的topic,在数据源输入的时候,已经设置好字段如 topic: 'dlbZcZGBSyslogs' ,所以此处使用占位符灵活设置;
Processors:配置处理器,即对采集的日志信息进行处理,处理是按行处理,当字符串处理即可,可以使用js语法进行对字符串进行处理;Filebeat的处理器可以多种多样,具体可以看文档。
另外,在调试的时候,可以采用文件输出或Console输出来观察处理后输出的数据格式,再进行微调:
output.file:
path: "D:/bigData"
filename: filebeat.log
IIS的日志也差不多,只是微调处理逻辑就可以了,一通百通。
其他配置可以参考官网文档:https://www.elastic.co/guide/en/beats/filebeat/current/index.html
Kafka配置
Kafka没有特别的处理,在这里只是进行消息的接收,新建好主题就可以。
//个人系统
bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcMySyslogs
//单位系统
bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcDWSyslogs
//管理系统
bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcZGBSyslogs
partitions 分区数的大小,取决设置了多少个消费者,这里我们有三台服务器做了Clickhouse的集群作为消费者,所以分区数设置为3,一般情况,消费者总数不应该大于分区数,每个分区只能分配一个消费者。
Clickhouse配置
Clickhouse三个分片的集群,如果你是单机的,只需要把语法相应的修改一下即可。
在每台服务器上创建kafka引擎表:
CREATE TABLE kafka_dlb_ZC_My_syslogs (
log_datetime DateTime64,
log_index String,
log_level String,
log_class String,
log_message String,
log_execTime Float32,
server String
) ENGINE = Kafka
SETTINGS kafka_broker_list = '192.168.1.10:9092',
kafka_topic_list = 'dlbZcMySyslogs',
kafka_group_name = 'dlbZcMySyslogs_sys',
kafka_format = 'JSONEachRow',
kafka_num_consumers = 1;
创建实体表:
CREATE TABLE dlb_ZC_My_syslogs on cluster cluster_3s_1r
(
log_datetime DateTime64,
log_index String,
log_level String,
log_class String,
log_message String,
log_execTime Float32,
server String
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/dlb_ZC_My_syslogs', '{replica}')
ORDER BY toDate(log_datetime)
PARTITION BY toYYYYMM(log_datetime);
//https://www.cnblogs.com/EminemJK/p/15165961.html
实体表是使用集群来创建的,如果是单机请删除 on cluster cluster_3s_1r ,修改表引擎即可。如果已经开启了zookeeper且开启复制表,在任一一台服务器运行运行一次即可。
在每台服务器上创建物化视图:
CREATE MATERIALIZED VIEW viem_dlb_ZC_My_syslogs_consumer TO dlb_ZC_My_syslogs
AS SELECT *
FROM kafka_dlb_ZC_My_syslogs;
创建分布式视图(可选,单机请忽略):
CREATE TABLE Dis_dlb_ZC_My_syslogs ON CLUSTER cluster_3s_1r
AS LogsDataBase.dlb_ZC_My_syslogs
ENGINE = Distributed(cluster_3s_1r, 'LogsDataBase', 'dlb_ZC_My_syslogs',rand());
分布式表将聚合集群中每个分片的表信息,进行执行一次。
运行
顺便提供一个快速运行Filebeat和卸载的bat脚本:
运行服务:
//windows server2008以上版本的服务器
cd %~dp0
.\install-service-filebeat.ps1
pause //windows server 2008 和以下的服务器
cd %~dp0
PowerShell.exe -ExecutionPolicy RemoteSigned -File .\install-service-filebeat.ps1
pause
卸载服务:
//windows server2008以上版本的服务器
cd %~dp0
.\uninstall-service-filebeat.ps1
pause //windows server2008和以下版本的服务器
cd %~dp0
PowerShell.exe -ExecutionPolicy RemoteSigned -File .\uninstall-service-filebeat.ps1
pause

运行之后,在任务管理器中,将服务设置为运行即可。
查看分布式数据:

数据采集完毕,完美。
既然数据已经有了,数据可视化方面可以采用多种方式了,以Grafana为例:

最后
下班,周末愉快。
ELK太重?试试KFC日志采集的更多相关文章
- SpringCloud微服务实战——搭建企业级开发框架(三十八):搭建ELK日志采集与分析系统
一套好的日志分析系统可以详细记录系统的运行情况,方便我们定位分析系统性能瓶颈.查找定位系统问题.上一篇说明了日志的多种业务场景以及日志记录的实现方式,那么日志记录下来,相关人员就需要对日志数据进行 ...
- 「视频小课堂」ELK和Kafka是怎么就玩在一起成了日志采集解决方案文字版
视频地址:ELK和Kafka是怎么就玩在一起成了日志采集解决方案 视频文字版 今天呢我就带来了一期视频,主要就是讲ELK和Kafka之间的通讯关系通过对一张通讯图,和一些操作命令,让我们能更深入的去理 ...
- 5-17 ELK 日志采集查询保存
ELK简介 什么是ELK ELK: E:Elasticsearch 全文搜索引擎 L:logstash 日志采集工具 K:Kibana ES的可视化工具 ELK是当今业界非常流行的日志采集保存和查询的 ...
- 大数据开发,Hadoop Spark太重?你试试esProc SPL
摘要:由于目标和现实的错位,对很多用户来讲,Hadoop成了一个在技术.应用和成本上都很沉重的产品. 本文分享自华为云社区<Hadoop Spark太重,esProc SPL很轻>,作者: ...
- Filebeat7 Kafka Gunicorn Flask Web应用程序日志采集
本文的内容 如何用filebeat kafka es做一个好用,好管理的日志收集工具 放弃logstash,使用elastic pipeline gunicron日志格式与filebeat/es配置 ...
- ELK:收集Docker容器日志
简介 之前写过一篇博客 ELK:日志收集分析平台,介绍了在Centos7系统上部署配置使用ELK的方法,随着容器化时代的到来,容器化部署成为一种很方便的部署方式,收集容器日志也成为刚需.本篇文档从 容 ...
- ELK:收集k8s容器日志最佳实践
简介 关于日志收集这个主题,这已经是第三篇了,为什么一再研究这个课题,因为这个课题实在太重要,而当今优秀的开源解决方案还不是很明朗: 就docker微服务化而言,研发有需求标准输出,也有需求文件输出, ...
- Docker笔记(十三):容器日志采集实践
日志是服务运行过程中的一个关键环节,借助日志,我们可以排查定位问题,也可以借助集中化的日志管理平台(如ELK)来做一些必要的数据统计分析.在Docker环境中,日志的采集比传统环境更为复杂,因此了解D ...
- 一篇文章教你搞懂日志采集利器 Filebeat
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 本文使用的Filebeat是7.7.0的版本,文章将从如下几个方面说明: Filebeat是什 ...
随机推荐
- Redisson 分布式锁源码 09:RedLock 红锁的故事
前言 RedLock 红锁,是分布式锁中必须要了解的一个概念. 所以本文会先介绍什么是 RedLock,当大家对 RedLock 有一个基本的了解.然后再看 Redisson 中是如何实现 RedLo ...
- Linux:Ubuntu配置jdk环境变量
1.下载jdk 推荐官网:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 下载tar.gz包即可. ...
- PHP中“简单工厂模式”实例讲解(转)
? 1 2 3 4 5 6 7 8 原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单 ...
- 使用 DataX 增量同步数据(转)
关于 DataX DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlServer.Postgre.HDFS.Hive.ADS.HBase.Tab ...
- QT. 学习之路 三
添加一个动作: Qt 使用QAction类作为动作.QAction包含了图标.菜单文字.快捷键.状态栏文字.浮动帮助等信息.当把一个QAction对象添加到程序中时,Qt 自己选择使用哪个属性来显示, ...
- python 16篇 多线程和多进程
1.概念 线程.进程 进程 一个程序,它是一组资源的集合 一个进程里面默认是有一个线程的,主线程 多进程是可以利用多核cpu的线程 最小的执行单位 线程和线程之间是互相独立的 主线程等待子线程执行结束 ...
- Redis 6.0 新特性:带你 100% 掌握多线程模型
Redis 官方在 2020 年 5 月正式推出 6.0 版本,提供很多振奋人心的新特性,所以备受关注. 码老湿,提供了啥特性呀?知道了我能加薪么? 主要特性如下: 多线程处理网络 IO: 客户端缓存 ...
- 简单梳理 ES6 函数
箭头函数 箭头函数提供了一种更加简洁的函数书写方式.基本语法是 参数 => 函数体 基本用法: var f = v => v; //等价于 var f = function(a){ ret ...
- 小猿圈-IT自学人的小圈子 【强力推荐学习】
笔记链接 https://book.apeland.cn/details/322/ 学习视频 https://www.apeland.cn/python
- PAT乙级:1070 结绳 (25分)
PAT乙级:1070 结绳 (25分) 题干 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟 ...