Spring Boot整合ELK 处理为服务日志,妙!(1)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Spring Boot整合ELK 处理为服务日志,妙!(1)

Spring Boot整合ELK 处理为服务日志,妙!

在排查线上异常的过程中,查询日志总是必不可缺的一部分。现今大多采用的微服务架构,日志被分散在不同的机器上,使得日志的查询变得异常困难。工欲善其事,必先利其器。如果此时有一个统一的实时日志分析平台,那可谓是雪中送碳,必定能够提高我们排查线上问题的效率。本文带您了解一下开源的实时日志分析平台 ELK 的搭建及使用。


ELK 简介


ELK 是一个开源的实时日志分析平台,它主要由 Elasticsearch、Logstash 和 Kiabana 三部分组成。


Logstash


Logstash 主要用于收集服务器日志,它是一个开源数据收集引擎,具有实时管道功能。Logstash 可以动态地将来自不同数据源的数据统一起来,并将数据标准化到您所选择的目的地。


Logstash 收集数据的过程主要分为以下三个部分:

  • 输入:数据(包含但不限于日志)往往都是以不同的形式、格式存储在不同的系统中,而 Logstash 支持从多种数据源中收集数据(File、Syslog、MySQL、消息中间件等等)。
  • 过滤器:实时解析和转换数据,识别已命名的字段以构建结构,并将它们转换成通用格式。
  • 输出:Elasticsearch 并非存储的唯一选择,Logstash 提供很多输出选择。


Elasticsearch


Elasticsearch (ES)是一个分布式的 Restful 风格的搜索和数据分析引擎,它具有以下特点:


  • 查询:允许执行和合并多种类型的搜索 — 结构化、非结构化、地理位置、度量指标 — 搜索方式随心而变。
  • 分析:Elasticsearch 聚合让您能够从大处着眼,探索数据的趋势和模式。
  • 速度:很快,可以做到亿万级的数据,毫秒级返回。
  • 可扩展性:可以在笔记本电脑上运行,也可以在承载了 PB 级数据的成百上千台服务器上运行。
  • 弹性:运行在一个分布式的环境中,从设计之初就考虑到了这一点。
  • 灵活性:具备多个案例场景。支持数字、文本、地理位置、结构化、非结构化,所有的数据类型都欢迎。


Kibana


Kibana 可以使海量数据通俗易懂。它很简单,基于浏览器的界面便于您快速创建和分享动态数据仪表板来追踪 Elasticsearch 的实时数据变化。其搭建过程也十分简单,您可以分分钟完成 Kibana 的安装并开始探索 Elasticsearch 的索引数据 — 没有代码、不需要额外的基础设施。


对于以上三个组件在 《ELK 协议栈介绍及体系结构》 一文中有具体介绍,这里不再赘述。


在 ELK 中,三大组件的大概工作流程如下图所示,由 Logstash 从各个服务中采集日志并存放至 Elasticsearch 中,然后再由 Kiabana 从 Elasticsearch 中查询日志并展示给终端用户。


图 1. ELK 的大致工作流程

01ebd755782e4c909dad0843d3544acf.jpeg

01ebd755782e4c909dad0843d3544acf.jpeg

ELK 的大致工作流程


ELK 实现方案


通常情况下我们的服务都部署在不同的服务器上,那么如何从多台服务器上收集日志信息就是一个关键点了。本篇文章中提供的解决方案如下图所示:


图 2. 本文提供的 ELK 实现方案

01ebd755782e4c909dad0843d3544acf.jpeg

本文提供的 ELK 实现方案


如上图所示,整个 ELK 的运行流程如下:


  1. 在微服务(产生日志的服务)上部署一个 Logstash,作为 Shipper 角色,主要负责对所在机器上的服务产生的日志文件进行数据采集,并将消息推送到 Redis 消息队列。
  2. 另用一台服务器部署一个 Indexer 角色的 Logstash,主要负责从 Redis 消息队列中读取数据,并在 Logstash 管道中经过 Filter 的解析和处理后输出到 Elasticsearch 集群中存储。
  3. Elasticsearch 主副节点之间数据同步。
  4. 单独一台服务器部署 Kibana 读取 Elasticsearch 中的日志数据并展示在 Web 页面。


通过这张图,相信您已经大致清楚了我们将要搭建的 ELK 平台的工作流程,以及所需组件。下面就让我们一起开始搭建起来吧。


ELK 平台搭建


**本节主要介绍搭建 ELK 日志平台,包括安装 Indexer 角色的 Logstash,Elasticsearc****h 以及 Kibana 三个组件。**完成本小节,您需要做如下准备:

  1. 一台 Ubuntu 机器或虚拟机,作为入门教程,此处省略了 Elasticsearch 集群的搭建,且将 Logstash(Indexer)、Elasticsearch 以及 Kibana 安装在同一机器上。
  2. 在 Ubuntu 上安装 JDK,注意 Logstash 要求 JDK 在 1.7 版本以上。
  3. Logstash、Elasticsearch、Kibana 安装包,您可以在 此页面 下载。


安装 Logstash


解压压缩包:

tar -xzvf logstash-7.3.0.tar.gz

显示更多简单用例测试,进入到解压目录,并启动一个将控制台输入输出到控制台的管道。

cd logstash-7.3.0
elk@elk:~/elk/logstash-7.3.0$ bin/logstash -e 'input { stdin {} } output { { stdout {} } }'

显示更多看到如下日志就意味着 Logstash 启动成功。

图 3. Logstash 启动成功日志

01ebd755782e4c909dad0843d3544acf.jpeg

Logstash 启动成功日志

在控制台输入 Hello Logstash ,看到如下效果代表 Logstash 安装成功。

清单 1. 验证 Logstash 是否启动成功Hello Logstash

{
    "@timestamp" => 2019-08-10T16:11:10.040Z,
          "host" => "elk",
      "@version" => "1",
       "message" => "Hello Logstash"
}

安装 Elasticsearch


解压安装包:

tar -xzvf elasticsearch-7.3.0-linux-x86_64.tar.gz

启动 Elasticsearch:

cd elasticsearch-7.3.0/
bin/elasticsearch

在启动 Elasticsearch 的过程中我遇到了两个问题在这里列举一下,方便大家排查。


问题一 :内存过小,如果您的机器内存小于 Elasticsearch 设置的值,就会报下图所示的错误。解决方案是,修改 elasticsearch-7.3.0/config/jvm.options 文件中的如下配置为适合自己机器的内存大小,若修改后还是报这个错误,可重新连接服务器再试一次。


图 4. 内存过小导致 Elasticsearch 启动报错

01ebd755782e4c909dad0843d3544acf.jpeg

内存过小导致 Elasticsearch 启动报错

问题二 ,如果您是以 root 用户启动的话,就会报下图所示的错误。解决方案自然就是添加一个新用户启动 Elasticsearch,至于添加新用户的方法网上有很多,这里就不再赘述。

图 5. Root 用户启动 Elasticsearch 报错

01ebd755782e4c909dad0843d3544acf.jpeg

Root 用户启动 Elasticsearch 报错

启动成功后,另起一个会话窗口执行 curl http://localhost:9200 命令,如果出现如下结果,则代表 Elasticsearch 安装成功。

清单 2. 检查 Elasticsearch 是否启动成功

elk@elk:~$ curl http://localhost:9200
{
  "name" : "elk",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "hqp4Aad0T2Gcd4QyiHASmA",
  "version" : {
    "number" : "7.3.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "de777fa",
    "build_date" : "2019-07-24T18:30:11.767338Z",
    "build_snapshot" : false,
    "lucene_version" : "8.1.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

安装 Kibana

解压安装包:

tar -xzvf kibana-7.3.0-linux-x86_64.tar.gz

修改配置文件 config/kibana.yml ,主要指定 Elasticsearch 的信息。

清单 3. Kibana 配置信息#Elasticsearch主机地址

elasticsearch.hosts: "http://ip:9200"
# 允许远程访问
server.host: "0.0.0.0"
# Elasticsearch用户名 这里其实就是我在服务器启动Elasticsearch的用户名
elasticsearch.username: "es"
# Elasticsearch鉴权密码 这里其实就是我在服务器启动Elasticsearch的密码
elasticsearch.password: "es"

启动 Kibana:

cd kibana-7.3.0-linux-x86_64/bin
./kibana

在浏览器中访问 http://ip:5601 ,若出现以下界面,则表示 Kibana 安装成功。

图 6. Kibana 启动成功界面

01ebd755782e4c909dad0843d3544acf.jpeg

Kibana 启动成功界面

ELK 日志平台安装完成后,下面我们就将通过具体的例子来看下如何使用 ELK,下文将分别介绍如何将 Spring Boot 日志和 Nginx 日志交由 ELK 分析。


在 Spring Boot 中使用 ELK


首先我们需要创建一个 Spring Boot 的项目,之前我写过一篇文章介绍 如何使用 AOP 来统一处理 Spring Boot 的 Web 日志 ,本文的 Spring Boot 项目就建立在这篇文章的基础之上。


修改并部署 Spring Boot 项目


在项目 resources 目录下创建 spring-logback.xml 配置文件。

清单 4. Spring Boot 项目 Logback 的配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <contextName>Logback For demo Mobile</contextName>
    <property name="LOG_HOME" value="/log" />
    <springProperty scope="context" name="appName" source="spring.application.name"
                    defaultValue="localhost" />
    ...
    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        ...
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{25} ${appName} -%msg%n</pattern>
        </encoder>
        ...
    </appender>
    ...
</configuration>

以上内容省略了很多内容,您可以在源码中获取。在上面的配置中我们定义了一个名为 ROLLING_FILE 的 Appender 往日志文件中输出指定格式的日志。而上面的 pattern 标签正是具体日志格式的配置,通过上面的配置,我们指定输出了时间、线程、日志级别、logger(通常为日志打印所在类的全路径)以及服务名称等信息。


将项目打包,并部署到一台 Ubuntu 服务器上。


清单 5. 打包并部署 Spring Boot 项目

# 打包命令
mvn package -Dmaven.test.skip=true
# 部署命令
java -jar sb-elk-start-0.0.1-SNAPSHOT.jar

查看日志文件, logback 配置文件中我将日志存放在 /log/sb-log.log 文件中,执行 more /log/sb-log.log 命令,出现以下结果表示部署成功。


图 7. Spring Boot 日志文件

01ebd755782e4c909dad0843d3544acf.jpeg

Spring Boot 日志文件


配置 Shipper 角色 Logstash


Spring Boot 项目部署成功之后,我们还需要在当前部署的机器上安装并配置 Shipper 角色的 Logstash。Logstash 的安装过程在 ELK 平台搭建小节中已有提到,这里不再赘述。安装完成后,我们需要编写 Logstash 的配置文件,以支持从日志文件中收集日志并输出到 Redis 消息管道中,Shipper 的配置如下所示。

清单 6. Shipper 角色的 Logstash 的配置

input {
    file {
        path => [
            # 这里填写需要监控的文件
            "/log/sb-log.log"
        ]
    }
}
output {
    # 输出到redis
    redis {
        host => "10.140.45.190"   # redis主机地址
        port => 6379              # redis端口号
        db => 8                   # redis数据库编号
        data_type => "channel"    # 使用发布/订阅模式
        key => "logstash_list_0"  # 发布通道名称
    }
}

其实 Logstash 的配置是与前面提到的 Logstash 管道中的三个部分(输入、过滤器、输出)一一对应的,只不过这里我们不需要过滤器所以就没有写出来。上面配置中 Input 使用的数据源是文件类型的,只需要配置上需要收集的本机日志文件路径即可。Output 描述数据如何输出,这里配置的是输出到 Redis。


Redis 的配置 data_type 可选值有 channel 和 list 两个。channel 是 Redis 的发布/订阅通信模式,而 list 是 Redis 的队列数据结构,两者都可以用来实现系统间有序的消息异步通信。channel 相比 list 的好处是,解除了发布者和订阅者之间的耦合。举个例子,一个 Indexer 在持续读取 Redis 中的记录,现在想加入第二个 Indexer,如果使用 list ,就会出现上一条记录被第一个 Indexer 取走,而下一条记录被第二个 Indexer 取走的情况,两个 Indexer 之间产生了竞争,导致任何一方都没有读到完整的日志。channel 就可以避免这种情况。这里 Shipper 角色的配置文件和下面将要提到的 Indexer 角色的配置文件中都使用了 channel 。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
3天前
|
存储 消息中间件 网络协议
日志平台-ELK实操系列(一)
日志平台-ELK实操系列(一)
|
7天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
1天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
4天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
5天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
6天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
8天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
9天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
2天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"
|
3天前
日志管理服务
日志管理服务 1.保证rsyslogd服务运行 查询是否启动 ps aux | grep "rsyslog" | grep -v"grep" 查询rsyslogd 自启动状态 systemctl list-unit-files | grep "rsyslog"