问题描述:

多个项目,有些项目分库分表分布在多个节点,因此,对慢日志的切割并且收集对于慢日志分析来说是极其必要的。

实现方案:

①环境准备

Host1 :ftp服务器(192.168.xx.xxx),用于集中存储各项目每天(可脚本自定义)的日志
Host2 :mysql服务器(192.168.xx.xxx),用于存储配置相关的参数(如需要收集的日志host,user,pwd,日志位置等信息),之后用于脚本的查询调用。
Host3 : 执行操作的机器(192.168.xx.xxx) ,即执行脚本设置定时任务的机器

②脚本准备

涉及到两个脚本,logrotate.sh 以及 job.sh
其中job.sh用于批量执行的mysql中存储的相关host的操作,job.sh调用logrotate.sh
logrotate.sh用于在各台需要收集日志的机器上实际的执行操作

mysql配置表结构及数据如下(注意添加一个所有机器都能查询该表的一个账号):






job.sh脚本如下:

点击(此处)折叠或打开

#!/bin/bash


mysql_host=192.168.xx.xxx
mysql_port=3456
mysql_user=xxx
mysql_pwd=xxxxxx


function get_info {
cmd=`which mysql`
$cmd -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_pwd -BNe "select * from DB_SPLIT_LOG.t_log_info;" | while read line
do
host_ip=`echo $line | awk '{print $3}'`
ssh_user=`echo $line | awk '{print $9}'`
ssh_pwd=`echo $line | awk '{print $10}'`
/usr/bin/sshpass -p $ssh_pwd ssh -o StrictHostKeyChecking=no $ssh_user@$host_ip "bash " < logrotate.sh
done
}

get_info
logrotate.sh脚本内容如下:

点击(此处)折叠或打开

#!/bin/bash


declare game
declare slow_log
declare ftp_host
declare ftp_user
declare ftp_pwd
declare ssh_pwd
declare local_ip
declare log_name
declare old_dir
declare tmp_conf
declare tran_log_dir
declare tran_log

dev=eth2
mysql_host=192.168.xx.xxx
mysql_port=3456
mysql_user=xxx
mysql_pwd=xxxxx
mysql_db=DB_SPLIT_LOG

date=`date +%Y%m%d`


function get_ip {
local_ip=`/sbin/ifconfig| grep -A 1 "$dev" | grep -i 'inet addr' | head -1 | awk -F[:] '{print $2}' | cut -d' ' -f1`
}

function get_info {
cmd=`which mysql`
argvs=`$cmd -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_pwd -BNe "select * from DB_SPLIT_LOG.t_log_info where host_ip='${local_ip}' limit 1;"`
game=`echo $argvs | awk '{print $2}'`
local_ip=`echo $argvs | awk '{print $3}'`
old_dir=`echo $argvs | awk '{print $4}'`
slow_log=`echo $argvs | awk '{print $5}'`
ftp_host=`echo $argvs | awk '{print $6}'`
ftp_user=`echo $argvs | awk '{print $7}'`
ftp_pwd=`echo $argvs | awk '{print $8}'`


log_name=${game}_`date +%Y%m%d`_$local_ip.slow
tmp_conf=$old_dir/logrotate_${date}.conf
mkdir -p /tmp/slow_tran_log
tran_log_dir=/tmp/slow_tran_log
tran_log=$tran_log_dir/${date}.log
}


function operation_log {
exec 1>$tran_log
exec 2>$tran_log
}

function create_rotate_conf {
echo """
$slow_log {
daily
copytruncate
dateext
create 0660 mysql mysql
olddir $old_dir
rotate 1
}
""" > $tmp_conf
}


function start_logrotate {
echo ""
/usr/sbin/logrotate -vf $tmp_conf
}


function change_logname {
echo ""

for file in `find $old_dir -maxdepth 1 -type f -name "*slow*${date}*"`
do
echo $file
done
echo "change log name $file to ${old_dir}/${log_name}"
mv $file ${old_dir}/${log_name}
}

function ftp_put {
echo ""
echo "start ftp put $log_name"
ftp -in <<EOF
open $ftp_host
user $ftp_user $ftp_pwd
mkdir $game
cd $game
lcd $old_dir
mput $log_name
quit
EOF
echo "ftp put $log_name over!"
}

function clear_tmp_file {
echo ""
echo "clear tmp file"
cd $old_dir
echo "cd $old_dir "
echo "rm -f $tmp_conf "
echo "rm -f $log_name "
rm -f $tmp_conf
rm -f $log_name
}

get_ip
get_info
operation_log
create_rotate_conf
start_logrotate
change_logname
ftp_put
clear_tmp_file 在Host3上将两个脚本置于一个目录之下,然后添加一个定时任务




在Host2(ftp)上查看操作结果




③过程描述
1 . job.sh 查询DB_SPLIT_LOG.t_log_info表中的所有host_ip ssh_user ssh_pwd ,然后循环远程执行脚本logrotate.sh
2 . logrotate.sh 首先查询本机ip ,然后根据本机ip获取DB_SPLIT_LOG.t_log_info表中对应的log_dir lot_file game ftp相关信息
3 . 生成logrotate的配置文件
4 . 进行切割
5 . 更改切割出来的日志名称
6 . 上传到ftp
7 . 清空临时文件

注意点:logrotate所切割的文件产生的结果必须和源文件在一个分区上(即你切割的结果文件slow.log-2016-10-25和原来的slow.log文件),不然切割会不成功。

另 : 该脚本适用于任何日志文件的切割与收集。只需要在DB_SPLIT_LOG.t_log_info表中添加相应的记录即可。