Spring Boot整合ELK实现日志采集与监控

前言

在分布式项目中,可以采用ELK来作为日志的收集与分析系统,提供一个统一的入口来对日志进行收集,访问和管理。本文主要演示Spring Boot项目与ELK整合来实现日志的采集与监控。

架构图示

本次测试工程中,采用的架构如下图所示,微服务通过TCP协议将日志提供给Logstach,Logstach对日志数据进行采集和转换之后,将日志数据发送到Elasticsearch存储库,然后再通过Kibana对日志数据进行可视化的呈现。

当然还有很多种不同的实现方案,比如可以通过Beats替代Logstash,或者可以与消息队列集成,通过生产消费的模式来提升日志数据的可靠性等等,大家有兴趣可以自行了解一下,官方也有一些图示与讲解,具体可以参考:https://www.elastic.co/guide/en/logstash/current/deploying-and-scaling.html

ELK搭建

本次搭建使用的是docker的方式,具体使用的软件版本如下(本次用于测试,数据目录未挂载出来):

elasticsearch 7.14.2
logstash 7.14.2
kibana 7.14.2
docker 20.10.10
docker-compose 1.29.2

在docker中创建一个自定义网络elk,elasticsearch、logstash、kibana服务都基于该网络:

docker network create elk # 创建自定义网络

启动elasticsearch:

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --name elasticsearch --network elk -d elasticsearch:7.14.2

通过http://localhost:9200访问,可以看到如下信息,说明elasticsearch启动成功:

启动kibana,这边指定了elasticsearch的地址,不指定的话默认是http://elasticsearch:9200:

docker run -p 5601:5601 -e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" --name kibana --network elk -d kibana:7.14.2

启动完成之后,通过http://localhost:5601可以访问kibana:

启动logstash:

docker run -it -p 4560:4560 -p 4570:4570 -p 4580:4580 -v /Users/yuanzhihao/elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf --name logstash --network elk -d logstash:7.14.2

logstash对外开放了三个端口,这样可以将不同类型的日志投送到不同的端口,对日志进行分类管理,比如运行日志,安全日志,操作日志等等。同时还需要挂载一个logstash.conf配置文件,具体配置如下:

input {
  tcp {
    mode => "server" # 模式指定为server模式
    host => "0.0.0.0" # server模式时 ip地址是本机
    port => 4560 # 指定监听端口
    codec => json_lines # 指定输入数据的解码器 使用json格式
    type => info # 日志的类型
	}
  tcp {
    mode => "server"
    host => "0.0.0.0"
    port => 4570
    codec => json_lines
    type => operation
  }
  tcp {
    mode => "server"
    host => "0.0.0.0"
    port => 4580
    codec => json_lines
    type => security
  }
}

output {
  stdout {
    codec => rubydebug # 可以在logstash控制台输出日志 默认就是rubydebug
  }
  
  if [type] == "info" {
    elasticsearch {
      hosts => "elasticsearch:9200"
      index => "info-log-%{ YYYY.MM.dd}"
    }
  }

  if [type] == "operation" {
    elasticsearch {
      hosts => "elasticsearch:9200"
      index => "operation-log-%{ YYYY.MM.dd}"
    }
  }

  if [type] == "security" {
    elasticsearch {
      hosts => "elasticsearch:9200"
      index => "security-log-%{ YYYY.MM.dd}"
    }
  }
} 

这边的input输入用到的是Logstash提供的一个TCP的一个插件,我新增了一个type表示日志的类型,有关于TCP插件的具体参数说明可以参考:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-tcp.html

同时,Logstash配置文件中也是支持条件表达式的,参考:https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html#conditionals,这边是对日志做了一个分类的处理,不同类型的日志对应不同的端口,然后在elasticsearch上面创建不同的索引。

也可以通过docker-compose的方式,启动elk,docker-compose.yml配置文件如下:

version: '2.2'
services:
  elasticsearch:
    image: elasticsearch:7.14.2
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - elk
  kibana:
    image: kibana:7.14.2
    container_name: kibana
    depends_on:
      - elasticsearch
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - 5601:5601
    networks:
      - elk
  logstash:
    image: logstash:7.14.2
    container_name: logstash
    environment:
      - node.name=es01
    volumes:
      - /Users/yuanzhihao/elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - 4560:4560
      - 4570:4570
      - 4580:4580
    networks:
      - elk
networks:
  elk:
    driver: bridge

通过命令启动,效果和上面docker启动一样

docker-compose -f docker-compose.yml up -d

Spring Boot工程配置

Spring Boot项目的maven的pom文件配置如下,需要添加logstash-logback-encoder依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.6</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

在代码中添加日志打印:

/**
 * @author yuanzhihao
 * @since 2022/6/19
 */
@SpringBootApplication
@RestController
@Slf4j
public class Application {
    private static final Logger operationLog = LoggerFactory.getLogger("operation");
    private static final Logger securityLog = LoggerFactory.getLogger("security");

    @GetMapping("/hello")
    public String hello() {
        log.info("hello info log");
        operationLog.info("hello operation log");
        securityLog.info("hello security log");
        return "Hello elk demo";
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

在resources目录下添加logback-spring.xml配置文件,根据日志类型输出到logstash开放出来的对应的端口:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <springProperty scope="context" name="applicationName" source="spring.application.name"/>

    <appender name="infoLogstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:4560</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <!--添加applicationName字段 -->
            <customFields>{"applicationName":"${applicationName}"}</customFields>
        </encoder>
    </appender>

    <appender name="operationLogstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:4570</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"applicationName":"${applicationName}"}</customFields>
        </encoder>
    </appender>

    <appender name="securityLogstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:4580</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"applicationName":"${applicationName}"}</customFields>
        </encoder>
    </appender>

    <logger name="operation" level="info">
        <appender-ref ref="operationLogstash"/>
    </logger>

    <logger name="security" level="info">
        <appender-ref ref="securityLogstash"/>
    </logger>

    <root level="INFO">
        <appender-ref ref="infoLogstash"/>
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

验证

查看logstash是否接收到日志

启动Spring Boot项目。可以看到logstash控制台会打印对应的日志,说明logstash已经接收到工程传过来的日志,logstash验证ok。

查看索引是否已经生效

访问http://localhost:9200/_cat/indices,这个可以查出来所有在elasticsearch上面创建的索引,可以看到我们的索引都已经生效了。

日志分析

创建索引模式

访问http://localhost:5601/app/management/kibana/indexPatterns地址,选择右上角Create index pattern创建索引模式


输入索引名称,这边输入operation-log-*

之后在配置中选择@timestamp,并创建索引

查看日志

转到http://localhost:5601/app/discover看板页面,可以看见我们创建的所有的索引,添加Filter可以对字段进行过滤,筛选出我们需要的日志信息。

结语

本次elk的整合的demo就到这边,这个也差不多是我们项目目前使用的场景了,比较简单。如果有问题可以留言。

参考地址:https://auth0.com/blog/spring-boot-logs-aggregation-and-monitoring-using-elk-stack

代码链接:https://github.com/yzh19961031/blogDemo/tree/master/elkDemo

Spring Boot整合ELK实现日志采集与监控的更多相关文章

  1. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

  2. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  3. Spring JdbcTemplate执行数据库操作详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下

  4. Spring Batch批处理框架操作指南

    Spring Batch 是 Spring 提供的一个数据处理框架。企业域中的许多应用程序需要批量处理才能在关键任务环境中执行业务操作,这篇文章主要介绍了Spring Batch批处理框架操作指南,需要的朋友可以参考下

  5. Spring详细讲解@Autowired注解

    @Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入

  6. Python利用watchdog模块监控文件变化

    这篇文章主要为大家介绍一个Python中的模块:watchdog模块,它可以实现监控文件的变化。文中通过示例详细介绍了watchdog模块的使用,需要的可以参考一下

  7. 使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. Node.js+ELK日志规范的实现

    这篇文章主要介绍了Node.js+ELK日志规范的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. Spring Security认证器实现过程详解

    一些权限框架一般都包含认证器和决策器,前者处理登陆验证,后者处理访问资源的控制,这篇文章主要介绍了Spring Security认证器实现过程,需要的朋友可以参考下

  10. spring学习JdbcTemplate数据库事务管理

    这篇文章主要为大家介绍了spring学习JdbcTemplate数据库事务管理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部