搭建Spring Boot + ELK日志平台,实现可视化日志监控

1.原因:

每次用tail -f 在服务器上翻日志太麻烦,线上问题排查时有时找不到日志。本文将带你从零开始,搭建一套企业级的ELK日志平台,让你的日志管理变得简单、高效、可视化。

传统日志管理的痛点

登录服务器

ssh user@prod-server

查看日志

tail -f /var/log/app/app.log

搜索错误

grep "ERROR" /var/log/app/app.log

跨服务器查日志?噩梦开始...

痛点总结

日志分散在多台服务器,排查问题需要来回切换, 搜索能力有限,复杂的查询难以实现,无法可视化分析,只能看原始文本日志,文件轮转后,历史日志难以追溯

2.分析:

功能介绍:

|-------------------|----|--------------------------|
| Elasticsearch | ES | 分布式搜索和分析引擎,负责日志的存储和索引 |
| Logstash | - | 日志采集管道,支持从多种来源采集、过滤、转换数据 |
| Kibana | - | 可视化平台,提供图表、仪表盘、日志浏览界面 |

3.解决:

3.1 版本选择

本文使用 ELK 7.17.15,这是7.x系列的最后一个稳定版本,兼容性好,社区文档丰富。

组件 版本 说明
Elasticsearch 7.17.15 长期支持版本
Kibana 7.17.15 与ES版本保持一致
Logstash 7.17.15 与ES版本保持一致
Spring Boot 3.x 使用logback-logstash-encoder

3.2 macOS 安装(使用二进制包)

安装一般不管win10\mac\linux,都是官网、华为云、阿里云、清华云等镜像搜索下载。

备注:我的是mac安装包,如果不能下载留言,我上传或者发送。

创建安装目录

mkdir -p ~/elk && cd ~/elk

下载 Elasticsearch (Apple Silicon 版本)

curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.15-darwin-aarch64.tar.gz

下载 Kibana

curl -L -O https://artifacts.elastic.co/downloads/kibana/kibana-7.17.15-darwin-x86_64.tar.gz

下载 Logstash

curl -L -O https://artifacts.elastic.co/downloads/logstash/logstash-7.17.15-darwin-x86_64.tar.gz

解压

for file in *.tar.gz; do tar -xzf "$file"; done

重命名

mv elasticsearch-7.17.15 elasticsearch

mv kibana-7.17.15-darwin-x86_64 kibana

mv logstash-7.17.15-darwin-x86_64 logstash

3.3 启动

3.3.1 启动ES:

复制代码
# 进入 ES 目录并后台启动
cd ~/elk/elasticsearch
./bin/elasticsearch -d

localhost:9002

3.3.2 启动kibana

cd ~/elk/kibana

nohup ./bin/kibana > ~/elk/logs/kibana.log 2>&1 &

localhost:5601

3.3.3 启动logstash

先建测试包

复制代码
config目录下新建 springboot-logstash.conf
java 复制代码
input {
  file {
    path => "/tmp/spring-logs/*.log"
    codec => json
    start_position => "beginning"
    sincedb_path => "/dev/null"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "springboot-logs-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}
复制代码
启动命令:
logstash -f /path/to/config.conf

4. springboot 项目关联

4.1 新建项目 elk_dm

pom.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dp.ccrr</groupId>
    <artifactId>elk_dm</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>elk_dm</name>
    <description>elk_dm</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <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>7.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

resource :

logback-spring.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="app"/>

    <!-- JSON 格式输出到文件 -->
    <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/tmp/spring-logs/${appName}.log</file>
        <!-- 添加滚动策略(同时解决 TriggeringPolicy 警告) -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/tmp/spring-logs/${appName}.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"service":"${appName}","environment":"dev"}</customFields>
        </encoder>
    </appender>

    <!-- 控制台输出(开发环境) -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 开发环境:输出到控制台 -->
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <!-- 生产/测试环境:输出 JSON 到文件 -->
    <springProfile name="prod,test,default">
        <root level="INFO">
            <appender-ref ref="JSON_FILE"/>
        </root>
    </springProfile>
</configuration>
复制代码
ELKController.java
java 复制代码
package com.dp.ccrr.elk_dm.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/elk")
public class ELKController {
    @RequestMapping("/")
    public String index() {
        log.info("------------ELKController.index");
        return "Hello World!";
    }
}
复制代码
TraceIdFilter.java
java 复制代码
package com.dp.ccrr.elk_dm.filter;

import jakarta.servlet.*;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.UUID;

@Component
public class TraceIdFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
        chain.doFilter(request, response);
        MDC.clear();
    }
}

启动项目:

http://localhost:8081/elk/

  1. 测试:

http://localhost:9200/test-index/_search?pretty

http://localhost:5601/

新建信息仓库,

输入springboot-logs*

然后在discover查看

搜索条件:

service elk_dm

today

然后就能看到测试数据了。

Done.

相关推荐
jameslogo9 小时前
如何用RocketMQTemplate发送事务消息
java·spring boot·rocketmq
无关868810 小时前
Spring Boot 项目标准化部署打包实战
java·spring boot·后端
jay神10 小时前
基于微信小程序课外创新实践学分认定系统
java·spring boot·小程序·vue·毕业设计
阿丰资源11 小时前
基于Spring Boot的酒店客房管理系统
java·spring boot·后端
zzqssliu11 小时前
SpringBoot框架搭建跨境独立站|Taocarts代购系统订单模块深度开发
java·spring boot·后端
武子康12 小时前
Java-219 RocketMQ Spring Boot 集成指南:生产者与消费者实战
java·spring boot·分布式·kafka·消息队列·rocketmq·java-rocketmq
想学习java初学者12 小时前
SpringBoot整合GS1编码解码
java·spring boot·后端
00后程序员张13 小时前
Windows 下怎么生成 AppStoreInfo.plist?不依赖 Xcode 的方法
ide·macos·ios·小程序·uni-app·iphone·xcode
i220818 Faiz Ul13 小时前
智慧养老平台|基于SprinBoot+vue的智慧养老平台系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·智慧养老平台