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

那年烟雨落申城
• 阅读 158

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):
    #!/bin/bash
    # 初始化
    LOGS_PATH=/opt/app/logs
    CURRENT_TIME=$(date +%Y%m%d%H%M%S)
    logFileList=(access error)
    

for fileIterm in ${logFileList[@]} do currentLogFileBaseName=${fileIterm} currentPathFileName=${LOGS_PATH}/${currentLogFileBaseName}.log echo "["${CURRENT_TIME}"]" "当前处理文件 "${currentPathFileName} if [ -s $(echo $currentPathFileName) ]; then afterReNameFileName=${LOGS_PATH}/${currentLogFileBaseName}_${CURRENT_TIME}.log echo "["${CURRENT_TIME}"]" "移动后文件名 "${afterReNameFileName} mv ${currentPathFileName} ${afterReNameFileName} fi done

#向nginx主进程发送USR1信号,重新打开日志文件,否则会继续往mv后的文件写数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。如果不这样操作导致日志切割失败。 kill -USR1 ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'

#删除2天前的日志 cd ${LOGS_PATH} find . -mtime +2 -name "*.log" | xargs rm -f

exit 0

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

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

dpkg -reconfigure

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

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

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

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

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

# op_user是我将来启动容器的用户 如果你使用root的话 op_user替换成root即可
RUN 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

容器启动脚本是:

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

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

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

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

2. python + shell

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

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

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

# -*- coding: UTF-8 -*-
import schedule
from datetime import datetime
import os

def job():
    now = datetime.now()
    dateTimeStr = now.strftime("%Y-%m-%d %H:%M:%S")
    print("start cut log shell ",dateTimeStr)
    os.system("sh /opt/app/cut_and_del_log_file.sh >> /opt/app/logs/cut.log")
    print("end cut log shell")

def func():
    schedule.clear()
    schedule.every(4).hours.do(job)
    while True:
        schedule.run_pending()

func()

容器中启动脚本为:

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

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

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

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

然后dockerfile加上:

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

容器启动脚本如下:

service cron start && nginx -g "daemon off;"
点赞
收藏
评论区
推荐文章
DevOpSec DevOpSec
3年前
nginx配置系列-日志切割
nginx配置系列日志切割背景nginx日志中我们希望日志能够每天或者每小时自动切割,nginx本身没有提供自动切割的机制,但是我们可以通过脚本或者稍加改造让其具备这种能力。下面让我们看看怎么操作吧。日志切割常见做法有四种,在我们做之前我们来学习一下nginx日志中常用的内置变量字段都是什么意思nginx内置变量
DevOpSec DevOpSec
1年前
nginx内置日志切割实战
在日常运维过程中我们希望日志自动的按天切割,而不是通过脚本加定时任务或三方工具实现,增加了运维维护的复杂度,下面让我们看看怎么操作吧。
Stella981 Stella981
2年前
Linux——定时清空日志内容和删除日志文件
前言最近在做性能压测试,会生成大量的日志,导致后续越压越慢,最终磁盘空间占满之类的问题。老是要手动删除日志文件,为避免此类问题发生,编写一个Linux日志定时清理的脚本,一劳永逸。1、shell脚本创建脚本并赋权touch/home/mppay/autotruncatelog.shchmod u
Wesley13 Wesley13
2年前
LNMP架构之访问日志、日志切割、静态文件不记录及过期时间设置
本文索引:Nginx访问日志Nginx日志切割静态文件不记录日志和过期时间Nginx访问日志修改nginx配置文件root@localhostvhostvim/usr/local/nginx/conf/nginx.conf搜索:/log_format
Stella981 Stella981
2年前
Logstash收集nginx访问日志和错误日志
1、收集访问日志1)、首先是要在nginx里面配置日志格式化输出log_formatmain"$http_x_forwarded_for|$time_local|$request|$status|$body_bytes_sent|$request_body|$content_length|$http_ref
Stella981 Stella981
2年前
Nginx日志切割之Logrotate篇
  不管是什么日志文件,都是会越来越大的,大到一定程度就是个可怕的事情了,所以要及早的做处理,方法之一就是按时间段来存储,不过linux系统提供了Logrotate的日志管理工具,很好用,不用写计划任务脚本了,不过弊端是转储后的日志文件放入指定的目录,必须和当前日志文件再同一个系统,下面是摘录别人的。记录下以备不时之需。      Logrotate是L
Stella981 Stella981
2年前
Python日志库logging总结
在部署项目时,不可能直接将所有的信息都输出到控制台中,我们可以将这些信息记录到日志文件中,这样不仅方便我们查看程序运行时的情况,也可以在项目出现故障时根据运行时产生的日志快速定位问题出现的位置。1、日志级别Python标准库logging用作记录日志,默认分为六种日志级别(括号为级别对应的数值),NOTSET(0)、DEBUG(10)
Wesley13 Wesley13
2年前
LAMP架构之访问日志的设置及切割、静态文件失效设置
本文索引访问日志不记录静态文件访问日志切割静态文件过期时间访问日志不记录静态文件为什么要这样设置网站大多为静态网页,网页内部的图片、css文件等同样有其网址链接,如果不设置,这些无效的信息也将被存入访问日志中,会导致访问日志文件大小快速增加,占用大量存储空间。我们可以通过设置不记录某
Lua将Nginx请求数据写入Kafka——埋点日志解决方案
缘起有一个埋点收集系统,架构是NginxFlume。web,小程序,App等客户端将数据报送至Nginx,Nginx将请求写入本地文件,然后Flume读取日志文件的数据,将日志写入Kafka。这个架构本来没什么问题,但是部署在K8s容器就有问题了,当前一
那年烟雨落申城
那年烟雨落申城
Lv1
男 · 众安科技 · 高级Java开发工程师
是你吧,我能从很远很远的地方一眼认出你来
文章
25
粉丝
0
获赞
1