Spring Boot/Spring Cloud 整合 ELK(Elasticsearch、Logstash、Kibana)详细避坑指南

发布于:2025-03-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

我们在开发中经常会写日志,所以需要有个日志可视化界面管理,使用ELK可以实现高效集中化的日志管理与分析,提升性能稳定性,满足安全合规要求,支持开发运维工作。

下述是我在搭建ELK时遇到的许许多多的坑,希望能替大家避开.

1. 环境准备

  • Elasticsearch: 用于存储和检索日志数据。

  • Logstash: 用于收集、处理和转发日志数据。

  • Kibana: 用于可视化和分析日志数据。

2. 安装 ELK 组件

你可以通过 Docker 快速安装 ELK 组件:

# 拉取 ELK 镜像
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.0
docker pull docker.elastic.co/logstash/logstash:7.10.0
docker pull docker.elastic.co/kibana/kibana:7.10.0

# 启动 Elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.10.0

# 启动 Logstash
docker run -d --name logstash -p 5044:5044 docker.elastic.co/logstash/logstash:7.10.0

# 启动 Kibana
docker run -d --name kibana -p 5601:5601 --link elasticsearch:elasticsearch docker.elastic.co/kibana/kibana:7.10.0

若不通过Docker,可直接官网下载,如下:

2.1 下载Elasticsearch

       - 访问 Elasticsearch 下载页面,选择适合的版本(如 8.17.3)。

        - 解压下载的文件

        - 启动 Elasticsearch:

                默认情况下,Elasticsearch 会监听 9200 端口。

                访问 http://localhost:9200,确认 Elasticsearch 是否正常运行。

       

        避坑点1:

       在启动时,发现老是报错,查了很久都没有结果,最终终于排查出来是环境变量配置的问题.

        我们可以看下述它自带的配置文件,文件中说明了若配置了ES_JAVA_HOME,则会使用此配置指向的JDK,但是此处JAVA_HOME和CLASS_PATH的环境变量会影响启动,所以如果想要直接使用它自带的JDK,需要将JAVA_HOME和CLASS_PATH的环境变量暂时注释掉.

set SCRIPT=%0

rem determine Elasticsearch home; to do this, we strip from the path until we
rem find bin, and then strip bin (there is an assumption here that there is no
rem nested directory under bin also named bin)
for %%I in (%SCRIPT%) do set ES_HOME=%%~dpI

:es_home_loop
for %%I in ("%ES_HOME:~1,-1%") do set DIRNAME=%%~nxI
if not "%DIRNAME%" == "bin" (
  for %%I in ("%ES_HOME%..") do set ES_HOME=%%~dpfI
  goto es_home_loop
)
for %%I in ("%ES_HOME%..") do set ES_HOME=%%~dpfI

rem now set the classpath
set ES_CLASSPATH=!ES_HOME!\lib\*
set ES_MODULEPATH=!ES_HOME!\lib
set LAUNCHERS_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\launchers\*;!ES_HOME!\lib\java-version-checker\*
set SERVER_CLI_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\tools\server-cli\*

set HOSTNAME=%COMPUTERNAME%

if not defined ES_PATH_CONF (
  set ES_PATH_CONF=!ES_HOME!\config
)

rem now make ES_PATH_CONF absolute
for %%I in ("%ES_PATH_CONF%..") do set ES_PATH_CONF=%%~dpfI

set ES_DISTRIBUTION_TYPE=zip

cd /d "%ES_HOME%"

rem now set the path to java, pass "nojava" arg to skip setting ES_JAVA_HOME and JAVA
if "%1" == "nojava" (
   exit /b
)

rem comparing to empty string makes this equivalent to bash -v check on env var
rem and allows to effectively force use of the bundled jdk when launching ES
rem by setting ES_JAVA_HOME=
if defined ES_JAVA_HOME (
  set JAVA="%ES_JAVA_HOME%\bin\java.exe"
  set JAVA_TYPE=ES_JAVA_HOME
  if not exist !JAVA! (
    echo "could not find java in !JAVA_TYPE! at !JAVA!" >&2
    exit /b 1
  )

  rem check the user supplied jdk version
  !JAVA! -cp "%ES_HOME%\lib\java-version-checker\*" "org.elasticsearch.tools.java_version_checker.JavaVersionChecker" || exit /b 1
) else (
  rem use the bundled JDK (default)
  set JAVA="%ES_HOME%\jdk\bin\java.exe"
  set "ES_JAVA_HOME=%ES_HOME%\jdk"
  set JAVA_TYPE=bundled JDK
)

rem do not let JAVA_TOOL_OPTIONS slip in (as the JVM does by default)
if defined JAVA_TOOL_OPTIONS (
  echo warning: ignoring JAVA_TOOL_OPTIONS=%JAVA_TOOL_OPTIONS%
  set JAVA_TOOL_OPTIONS=
)

rem warn that we are not observing the value of $JAVA_HOME
if defined JAVA_HOME (
  echo warning: ignoring JAVA_HOME=%JAVA_HOME%; using %JAVA_TYPE% >&2
)

rem JAVA_OPTS is not a built-in JVM mechanism but some people think it is so we
rem warn them that we are not observing the value of %JAVA_OPTS%
if defined JAVA_OPTS (
  (echo|set /p=warning: ignoring JAVA_OPTS=%JAVA_OPTS%; )
  echo pass JVM parameters via ES_JAVA_OPTS
)

cd %ES_HOME%

成功启动后,访问地址效果:

2.2 安装 Logstash

  1. 下载 Logstash:

  使用 -e 参数进行简单测试

bin/logstash -e 'input { stdin {} } output { stdout { codec => rubydebug } }'

若启动成功,可访问http://localhost:9600/看是否有json数据返回即可.

到此处,说明下载的Logstash没问题.

        

        2. 配置文件编写

        Logstash 的配置文件分为两类:主配置文件(logstash.conf)和管道配置文件(pipelines.yml)。

        

        1)logstash.conf 配置文件

logstash.conf 是 Logstash 的核心配置文件,定义了数据的输入、过滤和输出。它通常位于 Logstash 安装目录的 config 文件夹中。

  • 输入(Input):定义数据源,例如日志文件、网络端口等。
    示例:

    input {
        file {
            path => "/var/log/*.log"
            start_position => "beginning"
        }
    }
  • 过滤(Filter):对数据进行解析和处理,例如使用 Grok 插件解析日志。
    示例:

    filter {
        grok {
            match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request}" }
        }
    }
  • 输出(Output):定义数据的输出目标,例如 Elasticsearch、文件或控制台。
    示例:

  • output {
        elasticsearch {
            hosts => ["http://localhost:9200"]
            index => "logstash-%{+YYYY.MM.dd}"
        }
        stdout {
            codec => rubydebug
        }
    }

        (2)pipelines.yml 配置文件

pipelines.yml 文件用于定义管道的配置,包括管道的名称和配置文件路径。它通常位于 Logstash 安装目录的 config 文件夹中。

- pipeline.id: main
  path.config: "config/logstash-sample.conf"

避坑点2:

此处不知道怎么配置都会显示 No configuration found in the configured sources. 一直没找出原因

重新从配置的信息中找原因,最终发现是conf配置文件的问题.

logstash-sample.conf  示例如下:

input {
  # 示例3:HTTP 接收数据
  http {
    port => 8080
    codec => "json"
  }
}

output {
  # 示例1:输出到 Elasticsearch(带安全认证)
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "logs-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "password"
    ssl => false
  }
}

 logstash.yml  此文件需要配置上去,否则会一直报错,很多教程中没有指这一点!!!


# 节点名称(用于集群标识)
node.name: "my-logstash-node"

# 管道配置路径(可指定多个管道)
path.config: "config/pipelines/*.conf"

# 数据存储路径(队列和持久化数据)
path.data: "data/"

# 日志路径
path.logs: "logs/"

# HTTP API 配置(用于监控和管理)
api.http.host: "0.0.0.0"
api.http.port: 9600

# 性能调优(根据硬件调整线程和批处理大小)
pipeline.workers: 2          # 工作线程数(建议等于CPU核心数)
pipeline.batch.size: 125     # 每批处理事件数

上述坑点避开后,基本上都能启动了。效果如下:

2.3 安装 Kibana

  1. 下载 Kibana:

  2. 配置 Kibana:
    编辑 config/kibana.yml 文件,设置 Elasticsearch 的地址:

    elasticsearch.hosts: ["http://localhost:9200"]
    server.host: "0.0.0.0"
  3. 启动 Kibana:

    ./bin/kibana
    • Kibana 会监听 5601 端口。

    • 访问 http://localhost:5601,确认 Kibana 是否正常运行。

首次启动时,报了下述错误:

 从日志上看起来应该是配置问题,依旧先检查配置文件 config/kibana.yml

原来是按上述的配置文件内容是不足够的,所以我又添加了一些配置信息(Elastic连接信息、Kibana安全参数等)

# 配置Kibana服务运行的主机地址,允许远程访问时可设置为"0.0.0.0"
server.host: "localhost"

# 配置Kibana服务运行的端口
server.port: 5601

# 配置Elasticsearch的地址,如果有多个节点,可以像下面这样列出
elasticsearch.hosts:
  - "http://localhost:9200"

# 启用Kibana的安全功能
xpack.security.enabled: true

# 配置Elasticsearch的用户名和密码
elasticsearch.username: "elastic"
elasticsearch.password: "your_password"

按上述配置文件重启后,依旧报错:

原因:kibana连接Elasticsearch不允许直接使用超级账号elastics,需要按照下述方式创建专用账号

使用elasticsearch-service-tokens CLI工具
  1. 打开终端或命令提示符。

  2. 运行以下命令来创建服务账号令牌:

    bash复制

    elasticsearch-service-tokens create elastic/kibana <token_name>

    其中elastic/kibana是Kibana的服务账号,<token_name>是你为这个令牌指定的名称,例如kibana-token

  3. 该命令会在$ES_HOME/config/service_tokens文件中保存新的服务令牌,并在终端输出Bearer令牌。

# 配置Kibana服务运行的主机地址,允许远程访问时可设置为"0.0.0.0"
server.host: "localhost"

# 配置Kibana服务运行的端口
server.port: 5601

# 配置Elasticsearch的地址,如果有多个节点,可以像下面这样列出
elasticsearch.hosts:
  - "http://localhost:9200"

elasticsearch.serviceAccountToken: "AAEAAWVsYXN0aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1NldHZlZjdm9B"

根据生成的TOKEN,按上述最终的配置信息,重启服务即可,访问localhost:5601,出现下述界面说明成功了!

3. 集成项目

上述三个服务全部安装完成之后,我们就可以开始对接项目了.

Spring Boot 项目配置

3.1 添加依赖

在 pom.xml 中添加依赖:

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.6</version>
</dependency>
3.2 添加配置

在 src/main/resources 目录下创建 logback-spring.xml 文件(此处需注意,若已存在logback相关xml文件,则不需要重新创建):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:5044</destination>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
    </appender>

    <root level="INFO">
        <appender-ref ref="LOGSTASH"/>
        <appender-ref ref="console"/>
    </root>
</configuration>

添加上述配置,注意root节点不能重复,重复的话会以最后一个root节点为主.

3.3 测试:

在你的项目中将日志打印出来

logger.info("用户列表日志记录!!!");

若上述有问题,则需要检查是否已经创建了索引,先检查logstash的配置文件:

input {
  tcp {
    port => 5044
    codec => json_lines
  }
}

output {
  # 示例1:输出到 Elasticsearch(带安全认证)
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "springboot-logs-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "XXX"
    ssl => false
  }
}

此处的tcp监听是监听springboot配置文件中对应的端口.

3.4 查看索引

output中的index则是elastic的索引名称,访问此路径确认索引是否创建成功:http://localhost:9200/_cat/indices?v

若创建成功,在下图中就能看到了

3.5 查看日志

有了索引,我们就可以在kibana中查看了,如下图:

Stack Management  -> Data views -> Create data view

Discover 中搜索并查看,如下图:

这样我们整个过程就结束了,也成功使用ELK查看到日志了!