文章目录

docker 日志持久化及应用日志报错巡检

docker & k8s 日志常用操作
docker logs 
    -f #跟踪日志输入
    -t #输出时间 如果日志默认没有时间 则会在日志输出时添加上时间
    --tail #和linux下的tail 命令类似
    --since #查找特定时间之后的日志 如  docker logs --since="2018-11-26" 查找26号之后的日志
    --until #查找特定时间之前的日志  

#/etc/docker/daemon.json 日志相关配置配置日志切割,level,大小,等 
#docker logs 能获取到切割后的日志 kubectl logs 则不能获取到所有日志
ELK or EFK 的弊端
1.占用服务器资源太高 
2.对于容器的日志处理并不友好 
3.能实现日志持久化 但是对于大日志查询过于繁琐(可能为个人习惯问题)
实现脚本
脚本思路
1.根据docker ps 匹配出业务应用的docker容器,过滤掉K8S的守护,用awk取出docker_id(K8S部署后pod的名字为pod_name+随机字符串)
2.使用docker logs 获取前一天的日志(docker 配有日志切割 当日志达到一定大小后自动切割,docker logs 能获取到切割后的日志,但是kubectl logs 只能获取到未切割的日志)
3.loop所有项目的日志并重定向到规划的日志目录
4.grep 取出异常的日志(本文是直接过滤掉正常的日志,所有项目logs均统一输出标准时间,如项目报错则不会输出时间,这里直接取无时间输出的日子,自己使用时根据自己的实际情况修改),并将异常日志输出到单独的文件
5.邮件发送错误日志
日志处理脚本
#!/bin/bash
LOGS_OUT_DIR=/data/logs
BACKNUM=30
YETDAY=`date -d last-day +%F`
SERVICES_LIST="talust-common talust-email talust-evi talust-file talust-im talust-notify talust-sms talust-pay talust-item talust-order talust-approval talust-clockin talust-contract talust-enterprise talust-notice talust-recruit talust-reports talust-training talust-storage talust-assessment talust-config talust-gateway talust-register talust-management talust-message talust-job talust-txmanager talust-rabbitmq talust-user"

SAVA_LOGS(){
    # 保存日志
    for app in $SERVICES_LIST; do
        /opt/kube/bin/docker logs --since="$YETDAY" `/opt/kube/bin/docker ps |grep $app|grep -v k8s_POD_|awk '{print $1}'` > $LOGS_OUT_DIR/$app-$YETDAY.log 2>&1
    done
}

SEND_ERR(){
    YET_LOG=`ls $LOGS_OUT_DIR/*$YETDAY.log`
    mv $LOGS_OUT_DIR/app_err.log $LOGS_OUT_DIR/app_err-`date +%F`.log
    for app_log in $YET_LOG; do
        echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx $app_log xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" >>$LOGS_OUT_DIR/app_err.log 
        grep -v -E "`date +%F`|$YETDAY" $app_log >>$LOGS_OUT_DIR/app_err.log 
    done
    # 发送报错日志
    python /data/bin/sendmail_file.py younglinuxer@gmail.com $YETDAY-err  $LOGS_OUT_DIR/app_err.log
}

DEL_EXPIRE(){
    # 删除指定过期时间的日志
    find $LOGS_OUT_DIR -mtime +$BACKNUM | xargs rm -rf {};
}

SAVA_LOGS
SEND_ERR
DEL_EXPIRE
邮件发送脚本
#!/usr/bin/python
#coding:utf-8
import smtplib
from email.mime.text import MIMEText
from  email.mime.multipart import  MIMEMultipart
from  email.mime.text import MIMEText
from  email.mime.application import MIMEApplication
from email.header import Header
import sys

#邮箱服务器地址
mail_host = 'smtp.mxhichina.com'
#邮箱用户名
mail_user = 'dev@talust.org'
#邮箱密码
mail_pass = 'xxxxxx'
to_list=["yuanby@talust.org","1352794122@qq.com"]

#传入content 为日志文件  读取后通过邮件发送
#邮件发送
def send_mail(to_list,sub,content):
    # me=mail_user+"<"+mail_user+"@"+mail_postfix+">"
    me=mail_user
    msg = MIMEMultipart()
    msg['Subject'] = sub
    msg['From'] = me
    # msg['To'] = ";".join(to_list)
    msg['To'] = to_list
    part = MIMEText(open(content,'r').read(),_charset='utf-8')
    msg.attach(part)
    part =MIMEApplication(open(content,'rb').read())
    msg.attach(part)
    # msg["Accept-Language"]="zh-CN"
    # msg["Accept-Charset"]="ISO-8859-1,utf-8"
    try:
        s = smtplib.SMTP_SSL(mail_host,465)
        s.connect(mail_host)
        s.login(mail_user,mail_pass)
        s.sendmail(me, to_list, msg.as_string())
        s.close()
        return True
    except Exception, e:
        print str(e)
        return False

if __name__ == "__main__":
    print sys.argv[1]
    print sys.argv[2]
    print sys.argv[3]
    send_mail(sys.argv[1], sys.argv[2], sys.argv[3])

部署方式(单台 多台)
#生产多台节点解决方案
1.日志保存到公用存储下(如nfs 上边脚本只运行第一个函数收集日志,不对日志进行处理)
2.所有节点部署定时任务定期刷新日志到存储 (如节点比较多可以写到 saltstack 或者ansible 里面)
3.选取其中一个节点 执行日志过滤并发送邮件