配套视频教程已经上传
整合ELK-实现日志收集(知乎)
整合ELK-实现日志收集(CSDN)

项目源码已上传至 https://gitee.com/yangleliu/learning.git,免费索取
微信搜一搜【AI码师】关注帅气的我,回复【干货领取】,领取2021最新面试资料一份

为了方便不太熟悉linux系统和docker的同学,特地优化下docker-compose的路径设置

【前言】

开发任务后,提交代码的那一刻,心情是自由自在……速度是八十迈……

以为接下来是游戏、逛GAI或暖烘烘的被窝。

然而,梦想何其丰满,现实何其骨干。

总有测试小姐姐教你紧急刹车,回头做(改)人(bug):AI大师,你这不行啊!(吃瓜群众排排坐,笑歪了嘴)

我低头看了看自己的八块腹肌:行不行可不是你说了算!

小姐姐也不是吃素的,撸起袖子,打开她的联想十代:你行你连连报错,毒奶队友!

我:(⊙o⊙)…原来你说的是这个不行,我还以为……

小姐姐一脸疑惑:以为什么?真以为自己是大神了!

我清咳掉自己的尴尬,绝不认输:我认为是你传错了参数。毕竟本大师在本地调试时可没有任何问题。

小姐姐久经沙场,从无败绩:不!可!能!是你是你就是你!我从来不会错。

那一刻,我仿佛看到生理期的女朋友在面前闪现,内心是崩溃的。

我们俩就这样争执了很久,最后自然不出意料,缴械投降的还是我。

毕竟——

中华民族的传统美(糟)德(粕)是:好男不跟女斗!

于是我只能去服务器上看看日志,但是日志内容累累如高山,多多如牛毛,足足3.5个g,无奈的我只好使用一堆linux骚命令,将文件切割成一个个小文件,好在最后终于找到了那次请求,排查后找到了原因。

通过这件事,我痛定思痛:如果有一个平台能实时收集我们的日志,并能以可视化的界面呈现出来,那该多好啊!这样我们就再也不用在那堆厚重的日志文件里面找数据了。

【秘籍展示】

其实,这种神奇的平台早就有了,那就是ELK,它是三大神兽Elasticsearch(搜索引擎), Logstash(日志收集), Kibana(可视化的web界面)的组合:
我们来看下架构图:

对照架构图,我们来看下这三大神兽的工作过程

  1. 用户发送请求到我们的服务端
  2. 服务端将需要落日志的数据通过网络请求传送到logstash
  3. logstash对数据进行过滤清洗后,再传给Elasticsearch
  4. Elasticsearch 负责对数据创建索引,进行存储
  5. 用户通过访问kibana的web页面,能够实时查看日志

好吧,秘籍都告诉你了,现在需要带领你们去实战了

【必备心法】

在打仗之前,我们需要士兵们必须具备以下技能,不然上了战场后,只会被虐的体无完肤

  • 了解elk三大组件
  • 有实操过docker
  • 本地有docker环境
  • IDEA工具
  • 配置相对高一点的武器(电脑),不然会崩溃的

【准备粮草】 准备一个Springboot项目

首先创建一个springboot项目,项目结构如下

引入项目必备依赖

  <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.35</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.0</version></dependency>

创建一些基础组件

创建切面,实现低耦合记录日志

核心代码

    // 使用环绕通知@Around("controllerLog()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();// 获取当前请求对象ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 记录请求信息ReqRspLog webLog = new ReqRspLog();Object result = joinPoint.proceed();Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();// 通过反射,获取入参和出参,封装成json,落日志long endTime = System.currentTimeMillis();String urlStr = request.getRequestURL().toString();webLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));webLog.setIp(request.getRemoteUser());webLog.setMethod(request.getMethod());webLog.setParameter(getParameter(method, joinPoint.getArgs()));webLog.setResult(result);webLog.setSpendTime((int) (endTime - startTime));webLog.setStartTime(startTime);webLog.setUri(request.getRequestURI());webLog.setUrl(request.getRequestURL().toString());logger.info("{}", JSONUtil.parse(webLog));return result;}

创建测试接口

@RestController
@RequestMapping("/api")
public class ApiController {@GetMappingpublic R<String> addLog(@RequestParam(value = "param1",required = false) String param1){return R.success("你好,这段话将被日志记录");}
}

我们现在请求一下接口,会发现在控制台打印出 这样一段日志

{"method":"GET","uri":"/api","url":"http://localhost:8080/api","result":{"code":200,"data":"你好,这段话将被日志记录","message":"操作成功"},"basePath":"http://localhost:8080","parameter":{"param1":"测试ELK"},"startTime":1611529379353,"spendTime":9}

使用切面,实现日志记录并打印到控制台上已经完成了,现在我们按照架构图,需要通过logstash把日志发送到es里面,接下来整合logstash实现传送日志的功能

【招兵买马】 整合Logstash

添加logstash依赖

 <!--集成logstash--><dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>5.3</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>

编辑配置文件logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration><include resource="org/springframework/boot/logging/logback/defaults.xml"/><include resource="org/springframework/boot/logging/logback/console-appender.xml"/><!--应用名称--><property name="APP_NAME" value="mall-admin"/><!--日志文件保存路径--><property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/><contextName>${APP_NAME}</contextName><!--每天记录日志到文件appender--><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern><maxHistory>30</maxHistory></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder></appender><!--输出到logstash的appender--><appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"><!--可以访问的logstash日志收集端口--><destination>127.0.0.1:4560</destination><encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/></appender><root level="info"><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/><appender-ref ref="LOGSTASH"/></root>
</configuration>

编辑完之后,项目结构是这样的:

虽然在项目中已经集成了logstash功能,但是logstash还不知道把日志往哪里发,因为我们还没有城池。

既然没有,那就建造吧!

【搭建城池】 搭建ELK环境

ELK这里我使用dokcer-compose搭建,一个字:快!
首先我们约定一个根目录:/user/aimashi/docker
按要求执行如下命令

mkdir -p /root/docker
cd /root/docker
mkdir elk_stanrd
cd elk_stanrd
mkdir logstash
cd logstash
vim logstash.conf

将以下文件内容复制到logstash.conf

input {tcp {mode => "server"host => "0.0.0.0"port => 4560codec => json_lines}
}output {elasticsearch {hosts => "es:9200"index => "logstash-service-%{+YYYY.MM.dd}"}
}

继续执行如下命令

cd ../
vim docker-compose.yml

同样将以下内容复制到配置文件中

version: '3'
services:elasticsearch:image: elasticsearch:6.4.0container_name: elasticsearchenvironment:- "cluster.name=elasticsearch" #设置集群名称为elasticsearch- "discovery.type=single-node" #以单一节点模式启动- "ES_JAVA_OPTS=-Xms512m -Xmx512m" #设置使用jvm内存大小volumes:- /root/docker/elk_stanrd/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件文件挂载- /root/docker/elk_stanrd/elasticsearch/data:/usr/share/elasticsearch/data #数据文件挂载ports:- 9200:9200- 9300:9300kibana:image: kibana:6.4.0container_name: kibanalinks:- elasticsearch:es #可以用es这个域名访问elasticsearch服务depends_on:- elasticsearch #kibana在elasticsearch启动之后再启动environment:- "elasticsearch.hosts=http://es:9200" #设置访问elasticsearch的地址ports:- 5601:5601logstash:image: logstash:6.4.0container_name: logstashvolumes:- /root/docker/elk_stanrd/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf #挂载logstash的配置文件depends_on:- elasticsearch #kibana在elasticsearch启动之后再启动links:- elasticsearch:es #可以用es这个域名访问elasticsearch服务ports:- 4560:4560

到目前为止,搭建elk环境的准备工作已经完成。
现在需要启动elk,在/Users/yangle/docker/elk_stanrd目录下执行如下命令

docker-compose up -d

执行之后出现如下提示,则代表初创建成功

接下来,我们执行docker ps 来查看容器是否启动

如果和图中一样,代表容器正常启动,但是还需等待一分钟左右,才能访问可视化平台
访问地址 http://localhost:5601/

如果出现这个页面,则代表elk已经搭建完成,现在,我们需要往里面塞点数据

【发起进攻】 发送请求

elk环境搭建完成之后,需要产生一点数据。该怎么做呢?
只要调用 http://localhost:8080/api?param1=测试ELK 接口,多调用几次,就会产生一些测试数据。
除此之外,还需要做一些配置才能让es去收集这些日志,用户才能看到:

选择字段,创建索引

成功创建索引之后的界面

选择logstash-servicez之后,界面是这样的:

可以看到系统中的日志已经被收集上来了,试下搜索“你好”

所有包含“你好”的日志都被筛选出来,当然这里还可以有很多检索条件,例如右上角有一个时间过滤检索,我就不一一演示了,大家有兴趣的话可以自己研究下。
仓库:https://gitee.com/yangleliu/learning.git
乐于助人、大公无私的五好青年——我已将以上所有代码全部上传到git仓库中,大家自行获取,记得start啊

【战后总结】

每个新技术的出现,都是为了解决某一类问题。

就像elk的出现,就是为了减少日渐脱发的代码攻城狮们从海量日志中找数据的时间,节省出更多的精力放在业务处理上面。
有了elk,我们只需要在输入框中,轻松输入关键字,敲下回车,需要的数据就会呈现在我们面前。

测试小姐姐等待的时间短了,心情好了,矛盾自然也就少了。

如此想来,如果能有一个平台,将女友的十万个情绪爆发的原因实时展现出来,那世界将是多么美好的明天!

嘘~

如果大家感兴趣的话,可以给我点个赞哦,我将会更有动力为大家带来更好的实战文章,后面将会对这个日志系统进行优化,引入更加成熟的架构filebeat+kafka+logstash+Elasticsearch+kibana,敬请期待!

项目实战|史上最简单的springboot 整合elk教程,实现日志收集(带视频哦)相关推荐

  1. 史上最简单的wordpress迁移搬家教程

    当我们的wordpress网站需要换服务器或者域名时,又或者我们在本地使用做好了wordpress网站需要上线时,都需要用到wordpress迁移搬家技术.我网上也搜了很多,什么又要改数据什么的比较麻 ...

  2. SpringBoot+Kafka+ELK 完成海量日志收集(超详细)

    点击关注公众号,实用技术文章及时了解 来源:jiandansuifeng.blog.csdn.net/ article/details/107361190 整体流程大概如下: 服务器准备 在这先列出各 ...

  3. 秒懂系列 | 史上最简单的Python Django入门教程

    http://www.cnblogs.com/baiboy/p/django1.html 摘要:Django的学习教程也是分门别类,形式不一.或是较为体系的官方文档,或者风格自由的博客文档,或者偏向实 ...

  4. python入门教程慕课网_秒懂系列 | 史上最简单的Python Django入门教程

    摘要:Django的学习教程也是分门别类,形式不一.或是较为体系的官方文档,或者风格自由的博客文档,或者偏向实例的解析文档.即使官方文档,章节较多,文字阐述累赘,有时候我们只是关注某个功能用法而已,而 ...

  5. 史上最简单的微博AccessToken申请教程 ; - )

    打开链接:http://open.weibo.com/ 点击"网站接入", 点击"立即接入", 填写微博账号密码进行登录, 填写开发者信息,个人或公司任选其一, ...

  6. 做玫瑰花的方法 用纸_史上最简单的纸玫瑰花的折法教程教你用纸编法做玫瑰花...

    史上最简单的纸玫瑰花的折法教程教你用纸编法做玫瑰花 玫瑰花的折法制作教程一直以来都是不少同学比较喜欢的手工制作教程类型,无论是折纸玫瑰花的制作还是其他手工类型纸玫瑰花的制作,总是能够满足大家响应的制作 ...

  7. 史上最简单的 SpringCloud 教程

    关注公众号"风色年代"订阅更多精彩文章,本博大部分文章为转载并已标明原文出处,如有再转敬请保留,请自觉尊重原创作者的劳动成果! https://blog.csdn.net/fore ...

  8. 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)

    转:https://blog.csdn.net/forezp/article/details/70037291 最新版本: 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spr ...

  9. 史上最简单的spark教程第十三章-SparkSQL编程Java案例实践(终章)

    Spark-SQL的Java实践案例(五) 本章核心:JDBC 连接外部数据库,sparkSQL优化,故障监测 史上最简单的spark教程 所有代码示例地址:https://github.com/My ...

最新文章

  1. MUV LUV EXTRA 2019CCPC秦皇岛站J题 KMP
  2. 【web】从数据库读取多条数据到前台
  3. 在大厂干了 5 年产品后,如今她裸辞回家开店去了
  4. linux zsh命令行vim命令补齐,Linux使用zsh提高效率的5条建议
  5. android 自定义view实现拖动放大缩小_自定义itemClickView
  6. h5列表 php,H5的标签使用详解
  7. 解决FastCGI 进程超过了配置的活动超时时限的问题
  8. idea中springBoot项目修改html之类的文件后服务不自动更新
  9. [POJ1035]Spell checker
  10. 【译】你不知道的Chrome调试工具技巧 第六天:command 菜单
  11. cad批量打印快捷键_CAD高效批量打印成PDF
  12. jquery表单的提交
  13. Vue+FusionCharts 动态获取数据生成甘特图
  14. 一起写RPC框架(七)RPC网络模块的搭建五 Netty模块
  15. 跟我一起学Linux系统编程006C-进程内存分配,堆分配brk、malloc、free
  16. CoffeeScript
  17. Feature Enhancement Network: A Refined Scene Text Detector
  18. 游戏模拟器成了外挂帮凶,灰产对抗再升级
  19. vue和layui哪个更好用_指纹锁哪个牌子更好用?
  20. fiilt1左耳无法同步_【FIIL T1 蓝牙耳机使用总结】功能|操作|闪连|防水|音质_摘要频道_什么值得买...

热门文章

  1. 【Soul源码阅读】3.HTTP 用户接入 Soul 流程解析
  2. MySQL中如何设置外键
  3. 时间合并、周一至周五
  4. 图片验证码显示不出来的问题
  5. 文件转base64输出
  6. 初次使用github
  7. Android开发越来越式微了吗?,爆火的Android面试题
  8. shell脚本传递参数的方法
  9. mtk6595资料帖和问题帖集合
  10. MCMC实现——Python安装+Anaconda+PYMC3