Springboot整合ELFK(docker安装部署ELFK)
前言:日志对于一个程序的重要程度不用多说,正好之前部署了一套分布式日志解决方案(通过查阅大佬教程做此记录分享^ v ^)
- ELFK(Elasticsearch+Logstash+FileBeat+Kibana)
简单流程:Filebeat 会定时监听事先指定的日志文件,如果日志文件有变化,会将数据推送至 Logstash,Logstash通过配置进行过滤筛选存入es,最终通过 Kibana 将数据呈现出来。
一. 环境准备
准备服务器:目前使用linux centos搭建docker(docker环境搭建可查阅相关教程)
二.自定义网络:保证同一网络下的容器 (ElasticSearch、Logstash、Kibana)相互访问
- 创建自定义网络elk
docker network create elk
- 查看已有网络(Docker自带3种网络模式 bridge、host、none)
docker network ls
三. ELFK部署
- ElasticSerach+ik分词器 部署
- 创建目录并设置目录777权限
mkdir -p /opt/elasticsearch/{config,data}
chmod 777 /opt/elasticsearch/{config,data}
- 拉取镜像
ElasticSearch7以上版本需要JDK11支持,但是我们系统安装的是JDK8(请自行匹配es版本)
docker pull elasticsearch:7.14.1
- 配置文件
vi /opt/elasticsearch/config/elasticsearch.yml
- 配置信息
# 允许通过本机所有IP访问
http.host: 0.0.0.0
# 是否支持跨域,默认为false
http.cors.enabled: true
http.cors.allow-origin: "*"
# elasticsearch 7版本以上的默认只允许1000个分片,可能会报分片不足的问题
cluster.max_shards_per_node: 10000
- 创建和启动容器
docker run -d --name elasticsearch --net elk --restart always \
-p 9200:9200 -p 9300:9300 \
-e "ES_JAVA_OPTS=-Xms3g -Xmx3g" \
-e "discovery.type=single-node" \
-v /opt/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /opt/elasticsearch/data:/usr/share/elasticsearch/data \
elasticsearch:7.14.1
JVM堆内存大小建议设置大一点,不然可能会报错,建议堆内存设置至少 256M以上。
- 安装IK分词器
复制对应es版本的ik分词器完整下载地址—下载链接
- 容器下载安装
docker exec -it elasticsearch /bin/sh
cd bin/
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.1/elasticsearch-analysis-ik-7.14.1.zip
- 查看已安装的IK分词器
elasticsearch-plugin list
- 重启es生效
docker restart elasticsearch
- Kibana部署
- 拉取对应es版本的kibana镜像
docker pull kibana:7.14.1
- 创建和启动容器
docker run -d --name kibana --net elk --restart always \
-p 5601:5601 \
-e "I18N_LOCALE=zh-CN" \
kibana:7.14.1
-e 汉化启动
-p 指定端口号
- 访问 http://ip:5601,显示kibana界面
- Logstash 部署
- 拉取对应es版本的Logstash镜像
docker pull logstash:7.14.1
- 创建目录并设置目录777权限
mkdir -p /opt/logstash/{config,data,pipeline}
chmod 777 /opt/logstash/{config,data,pipeline}
- 配置文件(设置JVM堆内存大小)
vi /opt/logstash/config/jvm.options
-Xmx128m
-Xms128m
- Logstash配置
vi /opt/logstash/config/logstash.yml
# 允许通过本机所有IP访问
http.host: "0.0.0.0"
# 指定使用管道ID
xpack.management.pipeline.id: ["main"]
- 管道ID和配置文件路径映射
vi /opt/logstash/config/pipelines.yml
添加管道ID和管道配置文件目录映射,注意符号 - 前后都要有空格(巨坑)
- pipeline.id: main
path.config: "/usr/share/logstash/pipeline"
- 管道配置
vi /opt/logstash/pipeline/logstash-log.conf
input {
beats {
port => 5044
client_inactivity_timeout => 36000
}
}
filter {
grok {
match =>{
"message"=>"(?<data>({.*}))"
}
}
grok {
match =>{
"message"=>"%{TIMESTAMP_ISO8601:logTime}"
}
}
grok {
match =>{
"message"=>"%{LOGLEVEL:logLevel}"
}
}
grok {
match => {
"message"=>"(?<userId>(?<=\"userId\":)(\d+))"
}
}
# 设置东八区时间
ruby {
code => "event.set('logstashTime', event.get('@timestamp').time.localtime + 8*60*60);
event.set('@timestamp', event.get('logstashTime'))"
}
mutate {
remove_field => ["@version"]
remove_field => ["tags"]
}
}
output {
if [appname] == "admin-server" {
elasticsearch {
hosts => ["http://es-ip:9200"]
index => "saas-admin-log"
}
}else if [appname] == "auth-server" {
elasticsearch {
hosts => ["http://es-ip:9200"]
index => "saas-auth-log"
}
}else if [appname] == "biz-server" {
elasticsearch {
hosts => ["http://es-ip:9200"]
index => "saas-biz-log"
}
}
stdout { codec => rubydebug }
}
可以看到在 output 里根据 appname 生成的不同索引库,其中 appname 是 filebeat 自定义字段,目的区分多应用日志,自定义字段在 Filebeat部署的时候定义(es-ip:es部署服务的ip地址或域名)。
- 创建和启动容器
docker run -d --name logstash --net elk --restart always \
-p 5044:5044 -p 9600:9600 \
-v /opt/logstash/config:/usr/share/logstash/config \
-v /opt/logstash/data:/usr/share/logstash/data \
-v /opt/logstash/pipeline:/usr/share/logstash/pipeline \
logstash:7.14.1
- Filebeat 部署
- 拉取对应es版本的Filebeat镜像
docker pull elastic/filebeat:7.14.1
- 创建目录并设置目录777权限
mkdir -p /opt/filebeat/config
chmod 777 /opt/filebeat/config
- 配置文件
vi /opt/filebeat/config/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /logs/admin-server/log.log
fields:
appname: admin-server # 自定义字段,提供给 Logstash 用于区分日志来源
fields_under_root: true # 开启自定义字段
- type: log
enabled: true
paths:
- /logs/auth-server/log.log
fields:
appname: auth-server
fields_under_root: true
- type: log
enabled: true
paths:
- /logs/biz-server/log.log
fields:
appname: biz-server
fields_under_root: true
processors:
- drop_fields:
fields: ["log","input","host","agent","ecs"] # 过滤不需要的字段
output.logstash:
hosts: ['ipxxxx:5044']
/logs/admin-server/log.log 是应用 admin服务 输出的日志文件路径
ipxxxx 是部署 Logstash 服务器的IP地址
- 容器创建和启动
docker run -d --name filebeat --restart=always \
--log-driver json-file \
--log-opt max-size=100m \
--log-opt max-file=2 \
-v /logs:/logs \
-v /opt/filebeat/config/filebeat.yml:/usr/share/filebeat/filebeat.yml \
elastic/filebeat:7.14.1
四. SpringBoot部署日志
- 配置日志模块
在SpringBoot项目日志公共模块中加入如下日志配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<property name="LOG_HOME" value="/logs/${APP_NAME}" />
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 2. 输出到文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当前记录的日志文档完整路径 -->
<file>${LOG_HOME}/log.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的 addtivity 属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
-->
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
-->
<!-- 开发环境输出至控制台 -->
<springProfile name="dev">
<logger name="com.alibaba.nacos" level="OFF" addtivity="false"> </logger>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<!-- 生产环境输出至文件 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>
项目本地启动,接口添加log打印(log.info(xxxx);)项目日志,会在本地根目录生成日志文件夹
然后将项目发布到线上,因为项目使用idea集成docker远程部署(可以查询相关资料进行部署),所以先添加Docker容器日志目录挂载宿主机
然后启动发布到服务器上
五. 查询日志
查看 Logstash 处理日志
docker logs logstash
然后再Kibana中查找索引进行日志管理
ok!