1.1创建ELK安装目录
mkdir -p /opt/elk/{elasticsearch/{data,plugins},logstash/config}
1.2:对/opt/elk/elasticsearch
目录提前授权:
chmod -R 777 /opt/elk/elasticsearch/
2.1创建logstash配置文件
Tips:index => "applog-%{+YYYY-MM-dd}" 这个索引会显示在kibana中创建索引模式
tee /opt/elk/logstash/config/logstash.conf << \EOF
input {
tcp {
mode => "server"
host => "0.0.0.0"
port => 5041
type => "amaxlog"
codec => json_lines
}
}
filter {
date {
match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSS" ]
target => "@timestamp"
}
}
output {
elasticsearch {
hosts => ["自己的es的ip地址:9200"]
index => "applog-%{+YYYY-MM-dd}"
codec => json
action => "index"
}
}
EOF
上面hosts是配置的es节点地址,index是指定ES索引名称,索引名称这里按天创建,是为了将日志按天切割及清理
2.2编写ELK部署文件
创建docker-compose编排文件:
tee /opt/elk/elk-docker-compose.yml << \EOF
version: '3'
services:
elasticsearch:
image: elasticsearch:7.17.7 # 镜像
container_name: elk_elasticsearch # 定义容器名称
restart: always # 开机启动,失败也会一直重启
environment:
- "cluster.name=elasticsearch" # 设置集群名称为elasticsearch
- "discovery.type=single-node" # 以单一节点模式启动
- "ES_JAVA_OPTS=-Xms512m -Xmx1024m" # 设置使用jvm内存大小
volumes:
- /opt/elk/elasticsearch/plugins:/usr/share/elasticsearch/plugins # 插件文件挂载
- /opt/elk/elasticsearch/data:/usr/share/elasticsearch/data # 数据文件挂载
ports:
- 9200:9200
kibana:
image: kibana:7.17.7
container_name: elk_kibana
restart: always
depends_on:
- elasticsearch # kibana在elasticsearch启动之后再启动
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200 # 设置访问elasticsearch的地址
- I18N_LOCALE=zh-CN # kibana中文界面显示
ports:
- 5601:5601
logstash:
image: logstash:7.17.7
container_name: elk_logstash
restart: always
volumes:
# 挂载logstash的配置文件
- /opt/elk/logstash/config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch # kibana在elasticsearch启动之后再启动
links:
- elasticsearch:es # 可以用es这个域名访问elasticsearch服务
ports:
- 5041:5041
EOF
注意,这里logstash暴露的端口要与logstash配置文件中监听的端口一致,否则后续收集不到日志。
2.4部署ELK
启动部署:
docker-compose -f /opt/elk/elk-docker-compose.yml up -d
验证ES服务:
查看目前存在的索引:http://esip:9200/_cat/indices?v
验证kibana:
http://ip:5601/
如无意外,es与Kibana都能正常打开。
但是我出现了意外:logstash.conf 配置的es的地址配置错误了,然后启动成功后,Kibana上创建不了索引模式,找不到索引。通过 docker logs elk_logstash 查看日志,发现报错了:Unreachable: [http://esip:9200/][Manticore::ConnectTimeout] Connect to esip:9200 [/esip] failed: connect timed out。于是更改了logstash.conf 重新启动,还是报错。
删除logstash镜像,重启启动,Kibana上成功出现了索引
3.项目代码集成logstash
这里以logback为示例,集成logstash。
添加jar引用:
<!--(ELK)logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
</dependency>
logback.xml完整示例:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="./logs"/>
<property name="appName" value="elk-demo"/>
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${appName} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- File Appender -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${appName} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Logstash Appender -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstaship地址:5044</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"appname":"${appName}"}</customFields>
</encoder>
</appender>
<!-- Spring Boot Logger -->
<logger name="com.sam" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</logger>
<!-- Root Logger -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>
4.定时清理日志数据
注意:日志索引一定要以日期后缀方式才能按时间去清理,示例格式:applog-2023.07.07
编写清理日志索引shell脚本:
tee /opt/elk/clean_elk.sh << \EOF
#!/bin/bash
# @Author: 胡桃夹子
# @Date: 2023-07-10
# ELK日志数据保留近 N 天
KEEP_DAYS=30
# ES地址
ES_SERVER=esip地址:9200
# 日志索引名称前缀,示例:applog-2023.07.07
LOG_INDEX_PREFIX=applog
# 删除前 N的所有天到 前N+10天==>每天执行
function get_to_days()
{
# declare -A DAY_ARR
# DAY_ARR=""
for i in $(seq 1 10);
do
THIS_DAY=$(date -d "$(($KEEP_DAYS+$i)) day ago" +%Y-%m-%d)
DAY_ARR=( "${DAY_ARR[@]}" $THIS_DAY)
done
echo ${DAY_ARR[*]}
}
# 返回数组的写法
TO_DELETE_DAYS=(`get_to_days`)
for DAY in "${TO_DELETE_DAYS[@]}"
do
echo "${LOG_INDEX_PREFIX}-${DAY} index will be delete"
URL=http://${ES_SERVER}/${LOG_INDEX_PREFIX}-${DAY}
# echo ${URL}
curl -XDELETE ${URL}
done
EOF
上面shell中变量解释:
KEEP_DAYS代表日志保留天数;
ES_SERVER代表ES的服务地址;
LOG_INDEX_PREFIX日志索引名称前缀,示例:applog-2023.07.07;
for i in $(seq 1 10) 数字10 代表 删除7天以前的10天,如果你之前还有1年的数据 可以改成365;
授权shell脚本可执行权限:
chmod +x /opt/elk/clean_elk.sh
配置定时任务:
编辑任务列表
crontab -e
添加定时任务,每天凌晨1点钟执行
0 1 * * * /opt/elk/clean_elk.sh >/dev/null 2>&1
至此,ELK已经完成安装、应用集成、定时清理。
5.日志显示
运行测试代码
package org.example.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/web")
@Slf4j
public class TestController {
@GetMapping("/v1/test")
public String saveBlock() {
log.info("测试哈哈哈哈");
log.error("4343434344");
return "已打印";
}
}
执行完测试代码后,在成功创建了索引模式后,就直接可以进行搜索了
通过es索引查询也能看到自己的日志数据
esIp:9200/applog-2024-05-09/_search
esIp:9200/applog-2024-05-09/_doc/sSViXI8B2YRpJOxQvFdk 可以获得具体的值:
如下es查询操作,写的真的是完美了,可以直接拿来主义