用Python来管理Nginx日志(按时截断、清空size为0的日志、每月一删)

日常前言

最开始建站的时候,网上搜集怎么对nginx产生的日志进行按小时切断的方法,搜出来的基本都是使用sh的脚本(Linux能直接解析的语言),无法完全看懂的我只好直接ctrlCV(T_T)。

后来想想,干嘛不用Python试试呢?说写就写!

开始

第一步,按时截断

按时
一般来说我们都是不会希望巨多的日志数据全部存储到一个文件里的,所以我们需要按自己的需要进行定时截断日志。

在实际生产过程中,在服务上while True跑一个py脚本是不现实的,这里通过一个名为crond的包来实现定时任务(内置的,没有就yum安一下)。我们通过crontab -e来编辑其内容,他的格式为分 时 日 月 星期 执行脚本的解释器 执行的文件。比如每小时运行一次的方法就是0 * * * * /usr/bin/python /opt/sbin/cut_nginx_logs.py

在多给几个实例方便使用

*/5 * * * * 每五分钟执行
0 * * * *   每小时
0 0 * * *   每天
0 0 * * 0   每周
0 0 1 * *   每月
0 0 1 1 *   每年

<font color='red'>注意:</font>每一次修改都需要重启crond服务!

截断:
这个接比较简单了,直接使用os.system配合linux的mv命令就可以实现效果

第二步:清空size为0的日志

肯定有人要问了,为什么需要size为0的文件呢?我可以保证我的网站每小时都能产生巨多的访问流量,每一个访问日志都不会空下来。

  • 第一:万一哪个产品经理就是要让你这么做呢?(手动滑稽)
  • 第二:就算访问量巨多,每个访问文件都爆满,有没有想过错误记录文件的数量呢?当网站的后端代码部署到服务器上之后,我们一般都会开启DEBUG = False这个选项,更多时间会选择在本地进行bug调试,而服务器上的错误日志记录只会在本地环境无法测试的时候才会去看,从产生大量size为0的环境,如下图:
    在这里插入图片描述

So,说通了理由,再来说说他的实现思路。通过os.listdir先获取到指定目录下所有的日志文件名(返回的是一个数组),然后使用os.path.getsize获取到文件的大小(单位:字节),最后使用if配置os.remove进行一套组合拳完成需求

在这里插入图片描述

def empty(self):
        '''清空size为0的日志'''
        self._sizeA = os.listdir(self.access_dir)
        self._sizeE = os.listdir(self.error_dir)
        for i in self.sizeA:
            if os.path.getsize(self.access_dir + i) == 0:
                os.remove(i)        
        for i in self.sizeE:
            if os.path.getsize(self.error_dir + i) == 0:
                os.remove(i)

最后:每月清空一次所有日志

这个比较简单了,也不需要去写什么contab -e(跟在按时截断文件里进行判断时间即可)

def rm(self):
    '''每个月的第一天删除所有的日志'''
    self._rm1 = 'rm -rf /opt/logs/access/*'
    self._rm2 = 'rm -rf /opt/logs/error/*'
    os.system(self._rm1)
    os.system(self._rm2) 

最后

在我看来,大多数能想得到的功能,一旦用Python来实现,那百分之九十都是既优雅又简洁。最后的最后附上源代码。

import os
import time

class Logs(object):
    """docstring for Logs"""
    def __init__(self):
        self.__now_time = time.strftime('%m%d%H-%Y', time.localtime(time.time()))
        self.__access_dir = '/opt/logs/access/'
        self.__error_dir = '/opt/logs/error/'

    def cut(self):
        '''剪切日志'''
        self._Acommod = 'mv %saccess.log %s%s.log' % (self.__access_dir,self.__access_dir,self.__now_time)
        self._Ecommod = 'mv %serror.log %s%s.log' % (self.__error_dir,self.__error_dir,self.__now_time)
        os.system(self._Acommod)
        os.system(self._Ecommod)
        os.system('systemctl reload nginx')

    def empty(self):
        '''清空size为0的日志'''
        self._sizeA = os.listdir(self.__access_dir)
        self._sizeE = os.listdir(self.__error_dir)
        for i in self._sizeA:
            if os.path.getsize(self.__access_dir + i) == 0:
                os.remove(self.__access_dir + i)        
        for i in self._sizeE:
            if os.path.getsize(self.__error_dir + i) == 0:
                os.remove(self.__error_dir + i)

    def rm(self):
        '''每个月的第一天删除所有的日志'''
        self._rm1 = 'rm -rf /opt/logs/access/*'
        self._rm2 = 'rm -rf /opt/logs/error/*'
        os.system(self._rm1)
        os.system(self._rm2) 

Logs().cut()

h = time.strftime('%H', time.localtime(time.time()))
d = time.strftime('%d', time.localtime(time.time()))
if int(h) == 0:
    Logs().empty()
if int(d) == 1:
    Logs().rm()

本文作者: Messy
原文链接:https://www.messys.top/detail/33
版权声明: 本博客所有文章除特别声明外, 均采用 CC BY-NC-SA 4.0 许可协议. 转载请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 11,119评论 0 10
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 10,786评论 0 9
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 6,070评论 0 6
  • Linux习惯问题: 在vim编辑时,按了ctrl + s后,再按ctrl + q就可以继续执行了。ctrl + ...
    光着脚的鞋阅读 9,961评论 0 16
  • 今天情绪又不好了,想到去练瑜伽,什么时候行动呢?亲爱的自己,先爱自己再爱别人。你已经很好了,要加油!
    不爱吃香菇阅读 819评论 0 0