python定时任务执行shell脚本切割Nginx日志-慎用

Python定时任务执行shell脚本切割Nginx日志(慎用)

缘起

我们有一个Nginx服务用来接收埋点上报数据,输出的日志文件比较大,Nginx没有自带日志分割组件,这样输出的日志文件就比较大,抽取日志就比较麻烦。 网上切割日志的方式一般就两种:logratate和crontab+shell脚本 我这里探索的是第二种方式,中间踩了一些坑,记录一下。

环境

  • aliyunk8s
  • openresty 1.7.x
  • python2.7
  • 容器基础镜像为debian10

过程

1. crontab + shell

首先写分割日志的脚本如下(文件名为 cut_and_del_log_file.sh):

1#!/bin/bash 2# 初始化 3LOGS_PATH=/opt/app/logs 4CURRENT_TIME=$(date +%Y%m%d%H%M%S) 5logFileList=(access error) 6 7for fileIterm in ${logFileList[@]} 8 do 9 currentLogFileBaseName=${fileIterm} 10 currentPathFileName=${LOGS_PATH}/${currentLogFileBaseName}.log 11 echo "["${CURRENT_TIME}"]" "当前处理文件 "${currentPathFileName} 12 if [ -s $(echo $currentPathFileName) ]; then 13 afterReNameFileName=${LOGS_PATH}/${currentLogFileBaseName}_${CURRENT_TIME}.log 14 echo "["${CURRENT_TIME}"]" "移动后文件名 "${afterReNameFileName} 15 mv ${currentPathFileName} ${afterReNameFileName} 16 fi 17 done 18 19#向nginx主进程发送USR1信号,重新打开日志文件,否则会继续往mv后的文件写数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。如果不这样操作导致日志切割失败。 20kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'` 21 22#删除2天前的日志 23cd ${LOGS_PATH} 24find . -mtime +2 -name "*.log" | xargs rm -f 25 26exit 0

使用crontab 执行这段脚本就大功告成了,但是,遇到的第一个问题是我在容器里执行脚本的时候报错:

1Syntax error: "(" unexpected

查了下是因为debian系统默认使用dash替换bash,可以通过:

1dpkg -reconfigure

然后输入no就可以了,但无论是dockerfile还是启动脚本,都做不到,然后采用第二种方法,执行以下脚本:

1rm /bin/sh 2ln -s /bin/bash /bin/sh

直接进入docker容器内部执行没问题,但是发布的时候也不能进容器去做这个操作啊,于是决定放在dockerfile里面,但是执行完rm /bin/sh就会提示无法执行ln命令,原因是sh找不到了,妹的。于是我放在了容器启动脚本中,但是也没用,因为提示没有rm权限(我们k8s里面启动的默认账户不是root),于是想到了一个办法,既然先删除后链接不行,那就执行更新好了,dockerfile添加命令:

1RUN ln -snf /bin/bash /bin/sh

于是完美解决这个问题。 然后又遇到了crontab启动权限问题 我的dockerfile中crontab配置脚本是

1# op_user是我将来启动容器的用户 如果你使用root的话 op_user替换成root即可 2RUN echo "0 */4 * * * sh /opt/app/cut_and_del_log_file.sh > /opt/app/logs/cut.log 2>&1" > /var/spool/cron/crontabs/op_user

容器启动脚本是:

1ENTRYPOINT ["sh","/opt/app/start.sh"]

/opt/app/start.sh这个文件内容是:

1nohup service cron start & 2nginx -g "daemon off;"

然后提示我没权限启动cron,服了,这定时任务,crontab没机会了。

2. python + shell

于是使用了python,首先dockerfile安装python环境:

1# 安装python环境和pip 2RUN apt-get update -y && apt-get install python2.7 python-pip --no-install-recommends -y 3# 安装python组件schedule 4RUN pip install schedule -i http://mirrors.cloud.aliyuncs.com/pypi/simple --trusted-host mirrors.cloud.aliyuncs.com

python脚本如下(文件名为 loopCut.py):

1# -*- coding: UTF-8 -*- 2import schedule 3from datetime import datetime 4import os 5 6def job(): 7 now = datetime.now() 8 dateTimeStr = now.strftime("%Y-%m-%d %H:%M:%S") 9 print("start cut log shell ",dateTimeStr) 10 os.system("sh /opt/app/cut_and_del_log_file.sh >> /opt/app/logs/cut.log") 11 print("end cut log shell") 12 13def func(): 14 schedule.clear() 15 schedule.every(4).hours.do(job) 16 while True: 17 schedule.run_pending() 18 19func()

容器中启动脚本为:

1nohup python loopCut.py 2>&1 & 2nginx -g "daemon off;"

dockerfile中的ENTRYPOINT命令不变,发布后可以正确切割日志了 至此搞定此项任务。

------------------------------------------------20230216分界线------------------------------------------------ python这个schedule框架似乎有点问题,发布后会吃满一个CPU核心资源,慎用 ------------------------------------------------20230313分界线------------------------------------------------ 最后还是说服了security团队和运维团队的人,给加了crontab的支持 将以下内容保存为文件schedulefile

10 */4 * * * sh /opt/app/cut_and_del_log_file.sh > /opt/app/logs/cut.log 2>&1

然后dockerfile加上:

1# 安装cron 2RUN apt-get update -y && apt-get install --fix-missing cron -y 3# 拷贝上面的文件到 /opt/app/下 4COPY schedulefile /opt/app/ 5# 将上面的文件内容应用到crontab 6RUN crontab -u root /opt/app/schedulefile

容器启动脚本如下:

1service cron start && nginx -g "daemon off;"
点赞
收藏

评论区

加载中...

相关推荐

nginx内置日志切割实战

在日常运维过程中我们希望日志自动的按天切割,而不是通过脚本加定时任务或三方工具实现,增加了运维维护的复杂度,下面让我们看看怎么操作吧。

nginx配置系列-日志切割

nginx配置系列日志切割背景nginx日志中我们希望日志能够每天或者每小时自动切割,nginx本身没有提供自动切割的机制,但是我们可以通过脚本或者稍加改造让其具备这种能力。下面让我们看看怎么操作吧。日志切割常见做法有四种,在我们做之前我们来学习一下nginx日志中常用的内置变量字段都是什么意思nginx内置变量

Linux——定时清空日志内容和删除日志文件

前言最近在做性能压测试,会生成大量的日志,导致后续越压越慢,最终磁盘空间占满之类的问题。老是要手动删除日志文件,为避免此类问题发生,编写一个Linux日志定时清理的脚本,一劳永逸。1、shell脚本创建脚本并赋权touch/home/mppay/autotruncatelog.shchmod u

LNMP架构之访问日志、日志切割、静态文件不记录及过期时间设置

本文索引:Nginx访问日志Nginx日志切割静态文件不记录日志和过期时间Nginx访问日志修改nginx配置文件root@localhostvhostvim/usr/local/nginx/conf/nginx.conf搜索:/log_format

Logstash收集nginx访问日志和错误日志

1、收集访问日志1)、首先是要在nginx里面配置日志格式化输出log_formatmain"$http_x_forwarded_for|$time_local|$request|$status|$body_bytes_sent|$request_body|$content_length|$http_ref

Nginx日志切割之Logrotate篇

  不管是什么日志文件,都是会越来越大的,大到一定程度就是个可怕的事情了,所以要及早的做处理,方法之一就是按时间段来存储,不过linux系统提供了Logrotate的日志管理工具,很好用,不用写计划任务脚本了,不过弊端是转储后的日志文件放入指定的目录,必须和当前日志文件再同一个系统,下面是摘录别人的。记录下以备不时之需。      Logrotate是L