最简单的Spring Boot 整合ELK教程,实现日志收集

前言

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

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

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

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

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

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

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

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

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

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

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

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

毕竟——

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

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

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

秘籍展示

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

最简单的Spring Boot 整合ELK教程,实现日志收集

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

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

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

必备心法

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

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

准备粮草:准备一个Spring Boot项目

首先创建一个Spring Boot项目,项目结构如下:

最简单的Spring Boot 整合ELK教程,实现日志收集

引入项目必备依赖:

<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>

创建一些基础组件:

最简单的Spring Boot 整合ELK教程,实现日志收集

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

下面是核心代码:

// 使用环绕通知

@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 {

@GetMapping

public 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>

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

最简单的Spring Boot 整合ELK教程,实现日志收集

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

既然没有,那就建造吧!

搭建城池:搭建ELK环境

ELK这里我使用dokcer-compose搭建,一个字:快!

首先我们约定一个根目录:/user/aimashi/docker

按要求执行如下命令:

mkdir -p /Users/yangle/docker

cd /Users/yangle/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 => 4560

codec => 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.0

container_name: elasticsearch

environment:

  - "cluster.name=elasticsearch" #设置集群名称为Elasticsearch

  - "discovery.type=single-node" #以单一节点模式启动

  - "ES_JAVA_OPTS=-Xms512m -Xmx512m" #设置使用JVM内存大小

volumes:

  - /Users/yangle/docker/elk_stanrd/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件文件挂载

  - /Users/yangle/docker/elk_stanrd/elasticsearch/data:/usr/share/elasticsearch/data #数据文件挂载

ports:

  - 9200:9200

  - 9300:9300

kibana:

image: kibana:6.4.0

container_name: kibana

links:

  - elasticsearch:es #可以用es这个域名访问Elasticsearch服务

depends_on:

  - elasticsearch #Kibana在Elasticsearch启动之后再启动

environment:

  - "elasticsearch.hosts=http://es:9200" #设置访问Elasticsearch的地址

ports:

  - 5601:5601

logstash:

image: logstash:6.4.0

container_name: logstash

volumes:

  - ~/Users/yangle/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

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

最简单的Spring Boot 整合ELK教程,实现日志收集

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

最简单的Spring Boot 整合ELK教程,实现日志收集

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

访问地址: http://localhost:5601/

最简单的Spring Boot 整合ELK教程,实现日志收集

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

发起进攻:发送请求

ELK环境搭建完成之后,需要产生一点数据。该怎么做呢?

只要调用: http://localhost:8080/api?param1= 测试ELK接口,多调用几次,就会产生一些测试数据。

除此之外,还需要做一些配置才能让es去收集这些日志,用户才能看到:

最简单的Spring Boot 整合ELK教程,实现日志收集

最简单的Spring Boot 整合ELK教程,实现日志收集

选择字段,创建索引:

最简单的Spring Boot 整合ELK教程,实现日志收集

成功创建索引之后的界面:

最简单的Spring Boot 整合ELK教程,实现日志收集

最简单的Spring Boot 整合ELK教程,实现日志收集

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

最简单的Spring Boot 整合ELK教程,实现日志收集

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

最简单的Spring Boot 整合ELK教程,实现日志收集

所有包含“你好”的日志都被筛选出来,当然这里还可以有很多检索条件,例如右上角有一个时间过滤检索,我就不一一演示了,大家有兴趣的话可以自己研究下。

仓库:
https://gitee.com/yangleliu/learning.git

战后总结

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

就像ELK的出现,就是为了减少日渐脱发的代码攻城狮们从海量日志中找数据的时间,节省出更多的精力放在业务处理上面。

有了ELK,我们只需要在输入框中,轻松输入关键字,敲下回车,需要的数据就会呈现在我们面前。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值