简介
- 使用ELK做系统服务日志的收集,随着使用的时间和用户量的增长,ES的存储压力会越来越大,而一些过期日志又没什么参考价值,如果你们系统的服务日志索引名也是按日期去切割的,你就可以参考一下本文的清理ES索引脚本
本文将介绍如何规划ES索引名以及怎样清理过期索引信息,内容有
- ELK日志系统的介绍
- 服务索引名命名规则
- 日志收集方式说明与示例
- 自动清理索引脚本
- 定时自动清理任务
1、ELK日志系统的介绍
- ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ/网络)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
- 本文将使用ELK进行日志收集与日志检索以及运营数据分析等等,但它还可以支持其它任何数据分析和收集的场景,日志分析和收集只是更具有代表性。并非唯一性。
- ELK在面对性能、高并发、实时性、大数据等场景时,我们可以在对数据收集、传输、存储、展示等阶段加入一些中间件服务或替换其他组件来提升其服务能力。拿收集应用日志举例。
- 在数据量少的时候,可以直接使用logstash的TCP服务插件用来接收数据,应用程序可以直接将数据传入到TCP服务;
- 当服务并发量大了,将日志发送到logstashTCP服务将占有很高的系统资源,严重影响服务性能,这时候我们就可以先把日志写到磁盘上,通过logstash去监听日志文件变化,来搜集日志;
- 但刚开始还是能顶住压力,但是后面日志并发量太大、ES的都扛不住了,这时候我们就需要在传入到ES前做个缓冲机制了,日志可以通过logstash收集后先传递给MQ或者Redis中间件,然后再使用一个logstash从这些中间件中读取日志,再写入到ES中,这样问题就不大了。
2、 服务索引名命名规则
我们在使用ES做日志存储的时候,一般可以通过按索引名切分后做存储,切分方式有:
- 按业务范围来做切分,比如是用户服务就叫:user-log ,商品服务就叫 product-log;
- 按日期来做切分,日志量小就可以按月、年来做切分,量大就需要按日期做切分;
一般我们都会结合上面两种方式对索引名做切割,eg:
user-log-2020.01.22 #用户服务2020年1月22日的日志都存储在这个索引中
3、 日志收集方式说明与示例
- Logstash TCP服务收集日志配置:
input { #启动TCP服务进行日志收集 tcp { port => 9022 mode => "server" codec => "json" } } output { stdout { codec => rubydebug } # 输出到 elasticsearch elasticsearch { hosts => ["localhost:9200"] index => "%{[type]}-%{[module]}-%{+YYYY.MM.DD}" #索引名称,按年月日切分 } }
- Logstash 监听文件方式收集日志配置:
input { file { path => "/data/workspace/logs/*.log" #收集这个目录下的所有日志,这里也可以明确指定哪些文件名,支持数组方式["xxx","yyy"] codec => "json" mode => "tail" } } output { stdout { codec => rubydebug } # 输出到 elasticsearch elasticsearch { hosts => ["localhost:9200"] index => "%{[type]}-%{[module]}-%{+YYYY.MM}" #索引名称 } }
4、 自动清理索引脚本
由于系统日志量太大,我这里提供了一个清理指定日期前多少天ES中日志索引信息的脚本startDeleteOldLog.sh
#!/bin/bash
###################################
###################################
#清除最近多少天的日志,默认30天
past_day_count=$1
if [ ! $past_day_count ]; then
past_day_count=30;
fi
#待清除的索引匹配规则
index_prefix=$2
if [ ! $index_prefix ]; then
index_prefix="user\-log\-*";
fi
#ES地址
es_host=$3
if [ ! $es_host ]; then
es_host=localhost:9200;
fi
echo "准备清理掉ES[$es_host]内索引前缀为[$index_prefix]的超过当前时间前$past_day_count天的信息......"
function delete_indices() {
index_name=$1
index_date=$2
comp_date=`date -d "$past_day_count day ago" +"%Y-%m-%d"`
date1="$index_date 00:00:00"
date2="$comp_date 00:00:00"
t1=`date -d "$date1" +%s`
t2=`date -d "$date2" +%s`
if [ $t1 -le $t2 ]; then
curl -XDELETE http://$es_host/$index_name
fi
}
curl -XGET http://$es_host/_cat/indices | awk -F" " '{print $3}' | egrep "$index_prefix" | sort | while read LINE
do
index_name=$LINE;
index_date=`echo $LINE | awk -F"-" '{print $NF}' | egrep "[0-9]*\.[0-9]*\.[0-9]*" | uniq | sed 's/\./-/g'`
if [ $index_date ]; then
delete_indices $index_name $index_date
fi
done
echo "清理完成!"
5、定时自动清理任务
- 将我们的定时脚本加入到linux定时任务中,自动清理ES中的过期日志信息
# crontab -e 0 2 */10 * * sh /data/bash/task/es/startDeleteOldLog.sh
每隔10天自动清理一次,在凌晨2点整自动进行
- 简单介绍一下crontab的用法
- 使用场景:
1、系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
2、个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置
- 命令用法:
crontab [ -u user ] file
或crontab [ -u user ] { -l | -r | -e }
说明:
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。
-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。
参数说明:
- -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
- -r : 删除目前的时程表
- -l : 列出目前的时程表
- 定时任务配置格式说明:
时间格式:
f1 f2 f3 f4 f5 program
- 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。
- 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
- 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推
- 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
- 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,其馀类推
* * * * * - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 7) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59)
使用者也可以将所有的设定先存放在文件中,用 crontab file 的方式来设定执行时间。
- 使用示例
0 */2 * * * /sbin/service httpd restart #意思是每两个小时重启一次apache
50 7 * * * /sbin/service sshd start #意思是每天7:50开启ssh服务
50 22 * * * /sbin/service sshd stop #意思是每天22:50关闭ssh服务
0 0 1,15 * * fsck /home #每月1号和15号检查/home 磁盘
1 * * * * /home/bruce/backup #每小时的第一分执行 /home/bruce/backup这个文件
00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} \; #每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。
30 6 */10 * * ls #意思是每月的1、11、21、31日是的6:30执行一次ls命令
**注意:**当程序在你所指定的时间执行后,系统会寄一封信给你,显示该程序执行的内容,若是你不希望收到这样的信,请在每一行空一格之后加上 > /dev/null 2>&1 即可