日常前言
最开始建站的时候,网上搜集怎么对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 * 每年
注意:每一次修改都需要重启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 许可协议. 转载请注明出处!