写在前面

  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 进行配置。

  业务系统日志格式示例:

  1. 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'
  2. 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)更新材料状态
  3. 2021-04-06 11:21:21,612 [22128] DEBUG Zc - time:0ms select ID from XXX where InfoRelationID='6d43b831-6169-46d2-9518-f7c9ed6fe39c'
  4. 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')
  5. 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服务端错误信息:
  6. 页面:http://www.A.com:803/dbapp_53475dbapp_e524534.php
  7. 错误源:System.Web.Mvc
  8. 堆栈跟踪: at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
  9. at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
  10. at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
  11. at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
  12. at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
  13. at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

  FileBeat配置:

  1. max_procs: 2
  2. queue:
  3. mem:
  4. events: 2048
  5. flush.min_events: 2048
  6. # ============================== Filebeat inputs ===============================
  7.  
  8. filebeat.inputs:
  9.  
  10. # 管理系统
  11. - type: log
  12. enabled: true
  13. encoding: GB2312
  14. paths:
  15. - D:/IIS/www.A.com/logs/*.txt
  16.  
  17. multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
  18. multiline.negate: true
  19. multiline.match: after
  20. fields:
  21. topic: 'dlbZcZGBSyslogs'
  22. fields_under_root: true
  23.  
  24. # 单位系统
  25. - type: log
  26. enabled: true
  27. encoding: GB2312
  28. paths:
  29. - D:/IIS/www.B.com/logs/*.txt
  30. ### Multiline options
  31. multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
  32. multiline.negate: true
  33. multiline.match: after
  34. fields:
  35. topic: 'dlbZcDWSyslogs'
  36. fields_under_root: true
  37.  
  38. # 个人系统
  39. - type: log
  40. enabled: true
  41. encoding: GB2312
  42. paths:
  43. - D:/IIS/www.C.com/logs/*.txt
  44. ### Multiline options
  45. multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
  46. multiline.negate: true
  47. multiline.match: after
  48. fields:
  49. topic: 'dlbZcMySyslogs'
  50. fields_under_root: true
  51.  
  52. # 调试输出
  53. #output.console:
  54. # pretty: true
  55. #output.file:
  56. # path: "D:/bigData"
  57. # filename: filebeat.log
  58.  
  59. # -------------------------------- Kafka Output --------------------------------
  60. output.kafka:
  61. # Boolean flag to enable or disable the output module.
  62. enabled: true
  63. hosts: ["192.168.1.10:9092"]
  64.  
  65. # The Kafka topic used for produced events. The setting can be a format string
  66. # using any event field. To set the topic from document type use `%{[type]}`.
  67. topic: '%{[topic]}'
  68.  
  69. # Authentication details. Password is required if username is set.
  70. #username: ''
  71. #password: ''
  72.  
  73. # The number of concurrent load-balanced Kafka output workers.
  74. worker: 2
  75.  
  76. max_message_bytes: 10000000
  77.  
  78. # ================================= Processors =================================
  79. processors:
  80. - add_host_metadata:
  81. when.not.contains.tags: forwarded
  82. - add_cloud_metadata: ~
  83. - add_docker_metadata: ~
  84. - add_kubernetes_metadata: ~
  85. - script:
  86. lang: javascript
  87. id: my_filter
  88. tag: enable
  89. source: >
  90. function process(event) {
  91. var str = event.Get("message");
  92. var sp = str.split(" ");
  93. var log_datetime = sp.slice(0,2).join(" ");
  94. var regEx = /^\d{4}-\d{2}-\d{2}$/;
  95. var prefix_date = log_datetime.substring(0, 10);
  96. if(prefix_date.match(regEx) != null)
  97. {
  98. event.Put("server","221");
  99. log_datetime = log_datetime.replace(",",".");
  100. log_datetime = log_datetime.replace("'","");
  101. regEx = /^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3}$/;
  102. if(log_datetime.match(regEx) != null)
  103. {
  104. event.Put("log_datetime",log_datetime);
  105. event.Put("log_index",sp.slice(2,3).join(" ").replace("[","").replace("]",""));
  106. event.Put("log_level",sp.slice(3,4).join(" "));
  107. if(str.match(/(?<=time:)\S*(?=ms)/)!=null)
  108. {
  109. var spTime= str.split("time:");
  110. var spPre = spTime[0].split(" ");
  111. var spNext = spTime[1].split(" ");
  112. event.Put("log_class",spPre.slice(4).join(" "));
  113.  
  114. var log_execTime= spNext.slice(0,1).join(" ").replace("ms","");
  115. regEx = /^(\-|\+)?\d+(\.\d+)?$/;
  116. if(regEx.test(log_execTime))
  117. {
  118. event.Put("log_execTime",log_execTime);
  119. }
  120. else
  121. {
  122. event.Put("log_execTime","-1");
  123. }
  124. event.Put("log_message",spNext.slice(1).join(" "));
  125. }
  126. else
  127. {
  128. event.Put("log_class",sp.slice(4,5).join(" "));
  129. event.Put("log_execTime","-1");
  130. event.Put("log_message",sp.slice(6).join(" "));
  131. }
  132. return;
  133. }
  134. }
  135. event.Cancel();
  136. }
  137. - drop_fields:
  138. fields: ["@timestamp", "message", "host", "ecs", "agent", "@metadata", "log", "input"]

以上的配置说明:

  max_procs:设置可以同时执行的最大CPU数;

  queue :内部队列信息;

  Filebeat inputs:日志数据源采集的入口;

  其他字段如下说明:

  1. #日志类型
  2. - type: log
  3. #开启
  4. enabled: true
  5. #编码格式,有中文必须设置
  6. encoding: GB2312
  7. #路径
  8. paths:
  9. - D:/IIS/www.A.com/logs/*.txt
  10. #多行匹配前缀
  11. multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}'
  12. #开启多行匹配
  13. multiline.negate: true
  14. #开启多行之后,匹配是合并到上一条信息
  15. multiline.match: after
  16. #增加一个字段,用于kafka的topic的识别
  17. fields:
  18. topic: 'dlbZcZGBSyslogs'
  19. # 字段增加在输出json的根目录下
  20. fields_under_root: true

    //https://www.cnblogs.com/EminemJK/p/15165961.html

  Kafka Output:kafka的配置信息,主要是  topic: '%{[topic]}' 的设置,因为这里采集多个数据源,对于不同的topic,在数据源输入的时候,已经设置好字段如 topic: 'dlbZcZGBSyslogs' ,所以此处使用占位符灵活设置;

  Processors:配置处理器,即对采集的日志信息进行处理,处理是按行处理,当字符串处理即可,可以使用js语法进行对字符串进行处理;Filebeat的处理器可以多种多样,具体可以看文档。

另外,在调试的时候,可以采用文件输出或Console输出来观察处理后输出的数据格式,再进行微调:

  1. output.file:
  2. path: "D:/bigData"
  3. filename: filebeat.log

  IIS的日志也差不多,只是微调处理逻辑就可以了,一通百通。

  其他配置可以参考官网文档:https://www.elastic.co/guide/en/beats/filebeat/current/index.html

Kafka配置

  Kafka没有特别的处理,在这里只是进行消息的接收,新建好主题就可以。

  1. //个人系统
  2. bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcMySyslogs
  3. //单位系统
  4. bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcDWSyslogs
  5. //管理系统
  6. bin/kafka-topics.sh --create --zookeeper 192.168.1.10:2181 --replication-factor 1 --partitions 3 --topic dlbZcZGBSyslogs

   partitions 分区数的大小,取决设置了多少个消费者,这里我们有三台服务器做了Clickhouse的集群作为消费者,所以分区数设置为3,一般情况,消费者总数不应该大于分区数,每个分区只能分配一个消费者。

Clickhouse配置

  Clickhouse三个分片的集群,如果你是单机的,只需要把语法相应的修改一下即可。

  在每台服务器上创建kafka引擎表:

  1. CREATE TABLE kafka_dlb_ZC_My_syslogs (
  2. log_datetime DateTime64,
  3. log_index String,
  4. log_level String,
  5. log_class String,
  6. log_message String,
  7. log_execTime Float32,
  8. server String
  9. ) ENGINE = Kafka
  10. SETTINGS kafka_broker_list = '192.168.1.10:9092',
  11. kafka_topic_list = 'dlbZcMySyslogs',
  12. kafka_group_name = 'dlbZcMySyslogs_sys',
  13. kafka_format = 'JSONEachRow',
  14. kafka_num_consumers = 1;

  创建实体表:

  1. CREATE TABLE dlb_ZC_My_syslogs on cluster cluster_3s_1r
  2. (
  3. log_datetime DateTime64,
  4. log_index String,
  5. log_level String,
  6. log_class String,
  7. log_message String,
  8. log_execTime Float32,
  9. server String
  10. ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/dlb_ZC_My_syslogs', '{replica}')
  11. ORDER BY toDate(log_datetime)
  12. PARTITION BY toYYYYMM(log_datetime);

    //https://www.cnblogs.com/EminemJK/p/15165961.html

  实体表是使用集群来创建的,如果是单机请删除 on cluster cluster_3s_1r ,修改表引擎即可。如果已经开启了zookeeper且开启复制表,在任一一台服务器运行运行一次即可。

  在每台服务器上创建物化视图:

  1. CREATE MATERIALIZED VIEW viem_dlb_ZC_My_syslogs_consumer TO dlb_ZC_My_syslogs
  2. AS SELECT *
  3. FROM kafka_dlb_ZC_My_syslogs;

  创建分布式视图(可选,单机请忽略):

  1. CREATE TABLE Dis_dlb_ZC_My_syslogs ON CLUSTER cluster_3s_1r
  2. AS LogsDataBase.dlb_ZC_My_syslogs
  3. ENGINE = Distributed(cluster_3s_1r, 'LogsDataBase', 'dlb_ZC_My_syslogs',rand());

  分布式表将聚合集群中每个分片的表信息,进行执行一次。

运行

  顺便提供一个快速运行Filebeat和卸载的bat脚本:

  运行服务:

  1. //windows server2008以上版本的服务器
  2. cd %~dp0
  3. .\install-service-filebeat.ps1
  4. pause
  5.  
  6. //windows server 2008 和以下的服务器
  7. cd %~dp0
  8. PowerShell.exe -ExecutionPolicy RemoteSigned -File .\install-service-filebeat.ps1
  9. pause

  卸载服务:

  1. //windows server2008以上版本的服务器
  2. cd %~dp0
  3. .\uninstall-service-filebeat.ps1
  4. pause
  5.  
  6. //windows server2008和以下版本的服务器
  7. cd %~dp0
  8. PowerShell.exe -ExecutionPolicy RemoteSigned -File .\uninstall-service-filebeat.ps1
  9. pause

  运行之后,在任务管理器中,将服务设置为运行即可。

  查看分布式数据:

  数据采集完毕,完美。

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

最后

  下班,周末愉快。

ELK太重?试试KFC日志采集的更多相关文章

  1. SpringCloud微服务实战——搭建企业级开发框架(三十八):搭建ELK日志采集与分析系统

      一套好的日志分析系统可以详细记录系统的运行情况,方便我们定位分析系统性能瓶颈.查找定位系统问题.上一篇说明了日志的多种业务场景以及日志记录的实现方式,那么日志记录下来,相关人员就需要对日志数据进行 ...

  2. 「视频小课堂」ELK和Kafka是怎么就玩在一起成了日志采集解决方案文字版

    视频地址:ELK和Kafka是怎么就玩在一起成了日志采集解决方案 视频文字版 今天呢我就带来了一期视频,主要就是讲ELK和Kafka之间的通讯关系通过对一张通讯图,和一些操作命令,让我们能更深入的去理 ...

  3. 5-17 ELK 日志采集查询保存

    ELK简介 什么是ELK ELK: E:Elasticsearch 全文搜索引擎 L:logstash 日志采集工具 K:Kibana ES的可视化工具 ELK是当今业界非常流行的日志采集保存和查询的 ...

  4. 大数据开发,Hadoop Spark太重?你试试esProc SPL

    摘要:由于目标和现实的错位,对很多用户来讲,Hadoop成了一个在技术.应用和成本上都很沉重的产品. 本文分享自华为云社区<Hadoop Spark太重,esProc SPL很轻>,作者: ...

  5. Filebeat7 Kafka Gunicorn Flask Web应用程序日志采集

    本文的内容 如何用filebeat kafka es做一个好用,好管理的日志收集工具 放弃logstash,使用elastic pipeline gunicron日志格式与filebeat/es配置 ...

  6. ELK:收集Docker容器日志

    简介 之前写过一篇博客 ELK:日志收集分析平台,介绍了在Centos7系统上部署配置使用ELK的方法,随着容器化时代的到来,容器化部署成为一种很方便的部署方式,收集容器日志也成为刚需.本篇文档从 容 ...

  7. ELK:收集k8s容器日志最佳实践

    简介 关于日志收集这个主题,这已经是第三篇了,为什么一再研究这个课题,因为这个课题实在太重要,而当今优秀的开源解决方案还不是很明朗: 就docker微服务化而言,研发有需求标准输出,也有需求文件输出, ...

  8. Docker笔记(十三):容器日志采集实践

    日志是服务运行过程中的一个关键环节,借助日志,我们可以排查定位问题,也可以借助集中化的日志管理平台(如ELK)来做一些必要的数据统计分析.在Docker环境中,日志的采集比传统环境更为复杂,因此了解D ...

  9. 一篇文章教你搞懂日志采集利器 Filebeat

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 本文使用的Filebeat是7.7.0的版本,文章将从如下几个方面说明: Filebeat是什 ...

随机推荐

  1. Nginx:Nginx的安装

    Nginx安装 首先安装依赖 #安装Nginx需要gcc openssl-devel pcre-devel zlib-devel依赖 yum -y install gcc openssl-devel ...

  2. Netty实现对Websocket的支持

    一.WebSocket的简介及优势 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准.WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的 ...

  3. Linux中grep和egrep命令详解

    rep / egrep 语法: grep  [-cinvABC]  'word'  filename -c :打印符合要求的行数-i :忽略大小写-n :在输出符合要求的行的同时连同行号一起输出-v ...

  4. Vue3 + Cesium + Typescript 集成搭建的快速启动模板(包含示例数据)

    开门见山 项目地址:https://github.com/tanghaojie/vue3-cesium-typescript-start-up-template 好用的话给个star呗,有更新可以第一 ...

  5. SLAM十四讲第二版项目代码总结

    github地址:https://github.com/gaoxiang12/slambook2/tree/master/ch13 双目视觉里程计 头文件 所有的类都在myslam命名空间中 1.co ...

  6. ClickHouse学习系列之八【数据导入迁移&同步】

    背景 在介绍了一些ClickHouse相关的系列文章之后,大致对ClickHouse有了比较多的了解.它是一款非常优秀的OLAP数据库,为了更好的来展示其强大的OLAP能力,本文将介绍一些快速导入大量 ...

  7. 【LeetCode】217.存在重复元素

    217. 存在重复元素 知识点:数组:Set: 题目描述 给定一个整数数组,判断是否存在重复元素. 如果存在一值在数组中出现至少两次,函数返回 true .如果数组中每个元素都不相同,则返回 fals ...

  8. Gradle入门第一集【下载,安装和测试】

    参考:https://www.cnblogs.com/panchanggui/p/9394760.html 1,http://services.gradle.org/distributions/链接下 ...

  9. pip install 默认安装路径修改

    一.使用命令查看pip默认安装目录 python -m site 这里的USER_BASE和USER_SITE其实就是默认的启用Python通过pip自动下载的脚本和依赖安装包的基础路径. 接着使用命 ...

  10. C++:第一个c++程序

    // C++ 环境搭建: https://www.bilibili.com/video/BV1nt4y1r7Ez?t=535 // 学习资料:https://www.runoob.com/cplusp ...