python按大小,按时间分割日志,多进程安全配置。

1. 按大小分割日志 

import logging
import os
import time
from concurrent_log_handler import ConcurrentRotatingFileHandler

app = Flask(__name__)

# 按大小分割日志
def init_logger(app):
    file_dir = os.path.join(Config.basedir, 'logs')
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    logname = 'logger-' + time.strftime('%Y-%m-%d', time.localtime(time.time())) + '.log'
    if len(logname) > 0:
        logbytes = app.config.get('LOGBYTES', 10240)
        logback = app.config.get('LOGBACK', 1)
        loglevel = app.config.get('LOGLEVEL', 0)
        handler =  ConcurrentRotatingFileHandler(os.path.join(file_dir, logname),
                maxBytes=logbytes, backupCount=logback)
        formatter = logging.Formatter('%(levelname)s %(pathname)s->func:%(funcName)s '
                                        'line:%(lineno)d %(message)s %(asctime)s')
        handler.setFormatter(formatter)
        handler.setLevel(loglevel)
        app.logger.addHandler(handler)

init_logger(app)

2. 按时间分割日志

首先需要重写handler

import os
import re
import datetime
import logging

try:
    import codecs
except ImportError:
    codecs = None

# 支持多进程
class TimedRotatingFileHandler(logging.FileHandler):

    def __init__(self,filename,when='D',backupCount=0,encoding=None,delay=False):
        """filename 日志文件名,when 时间间隔的单位,backupCount 保留文件个数
        delay 是否开启 OutSteam缓存
            True 表示开启缓存,OutStream输出到缓存,待缓存区满后,刷新缓存区,并输出缓存数据到文件。
            False表示不缓存,OutStrea直接输出到文件"""
        self.prefix = filename
        self.backupCount = backupCount
        self.when = when.upper()
        # 正则匹配 年-月-日
        self.extMath = r"^\d{4}-\d{2}-\d{2}"

        # S 每秒建立一个新文件
        # M 每分钟建立一个新文件
        # H 每天建立一个新文件
        # D 每天建立一个新文件
        # 当然如果你还需要其他的方式可以加上去比如按月
        self.when_dict = {
            'S':"%Y-%m-%d-%H-%M-%S.log",
            'M':"%Y-%m-%d-%H-%M.log",
            'H':"%Y-%m-%d-%H.log",
            'D':"%Y-%m-%d.log"
        }
        #日志文件日期后缀
        self.suffix = self.when_dict.get(when)
        if not self.suffix:
            raise ValueError(u"指定的日期间隔单位无效: %s" % self.when)
        #拼接文件路径 格式化字符串
        self.filefmt = os.path.join("logs","%s-%s" % (self.prefix,self.suffix))
        #使用当前时间,格式化文件格式化字符串
        self.filePath = datetime.datetime.now().strftime(self.filefmt)
        #获得文件夹路径
        _dir = os.path.dirname(self.filefmt)
        try:
            #如果日志文件夹不存在,则创建文件夹
            if not os.path.exists(_dir):
                os.makedirs(_dir)
        except Exception:
            print(u"创建文件夹失败")
            print(u"文件夹路径:" + self.filePath)
            pass

        if codecs is None:
            encoding = None

        logging.FileHandler.__init__(self,self.filePath,'a+',encoding,delay)

    def shouldChangeFileToWrite(self):
        """更改日志写入目的写入文件
        :return True 表示已更改,False 表示未更改"""
        #以当前时间获得新日志文件路径
        _filePath = datetime.datetime.now().strftime(self.filefmt)
        #新日志文件日期 不等于 旧日志文件日期,则表示 已经到了日志切分的时候
        #   更换日志写入目的为新日志文件。
        #例如 按 天 (D)来切分日志
        #   当前新日志日期等于旧日志日期,则表示在同一天内,还不到日志切分的时候
        #   当前新日志日期不等于旧日志日期,则表示不在
        #同一天内,进行日志切分,将日志内容写入新日志内。
        if _filePath != self.filePath:
            self.filePath = _filePath
            return True
        return False

    def doChangeFile(self):
        """输出信息到日志文件,并删除多于保留个数的所有日志文件"""
        #日志文件的绝对路径
        self.baseFilename = os.path.abspath(self.filePath)
        #stream == OutStream
        #stream is not None 表示 OutStream中还有未输出完的缓存数据
        if self.stream:
            #flush close 都会刷新缓冲区,flush不会关闭stream,close则关闭stream
            #self.stream.flush()
            self.stream.close()
            #关闭stream后必须重新设置stream为None,否则会造成对已关闭文件进行IO操作。
            self.stream = None
        #delay 为False 表示 不OutStream不缓存数据 直接输出
        #   所有,只需要关闭OutStream即可
        if not self.delay:
            #这个地方如果关闭colse那么就会造成进程往已关闭的文件中写数据,从而造成IO错误
            #delay == False 表示的就是 不缓存直接写入磁盘
            #我们需要重新在打开一次stream
            #self.stream.close()
            self.stream = self._open()
        #删除多于保留个数的所有日志文件
        if self.backupCount > 0:
            print('删除日志')
            for s in self.getFilesToDelete():
                print(s)
                os.remove(s)

    def getFilesToDelete(self):
        """获得过期需要删除的日志文件"""
        #分离出日志文件夹绝对路径
        #split返回一个元组(absFilePath,fileName)
        #例如:split('I:\ScripPython\char4\mybook\util\logs\mylog.2017-03-19)
        #返回(I:\ScripPython\char4\mybook\util\logs, mylog.2017-03-19)
        # _ 表示占位符,没什么实际意义,
        dirName,_ = os.path.split(self.baseFilename)
        fileNames = os.listdir(dirName)
        result = []
        #self.prefix 为日志文件名 列如:mylog.2017-03-19 中的 mylog
        #加上 点号 . 方便获取点号后面的日期
        prefix = self.prefix + '.'
        plen = len(prefix)
        for fileName in fileNames:
            if fileName[:plen] == prefix:
                #日期后缀 mylog.2017-03-19 中的 2017-03-19
                suffix = fileName[plen:]
                #匹配符合规则的日志文件,添加到result列表中
                if re.compile(self.extMath).match(suffix):
                    result.append(os.path.join(dirName,fileName))
        result.sort()

        #返回  待删除的日志文件
        #   多于 保留文件个数 backupCount的所有前面的日志文件。
        if len(result) < self.backupCount:
            result = []
        else:
            result = result[:len(result) - self.backupCount]
        return result

    def emit(self, record):
        """发送一个日志记录
        覆盖FileHandler中的emit方法,logging会自动调用此方法"""
        try:
            if self.shouldChangeFileToWrite():
                self.doChangeFile()
            logging.FileHandler.emit(self,record)
        except (KeyboardInterrupt,SystemExit):
            raise
        except:
            self.handleError(record)

然后再配置中修改一下

import logging
import os
import time

app = Flask(__name__)

# 按时间切割日志文件
def time_logging(app):
    file_dir = os.path.join(Config.basedir, 'logs')
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    loglevel = app.config.get('LOGLEVEL', 0)
    # 导入自定义的handler
    from app.loghandler import MultiprocessHandler

    handler = MultiprocessHandler('logger', when='D')
    formatter = logging.Formatter('%(levelname)s %(pathname)s->func:%(funcName)s '
                                    'line:%(lineno)d %(message)s %(asctime)s')
    handler.setFormatter(formatter)
    handler.setLevel(loglevel)
    app.logger.addHandler(handler)

time_logging(app)

使用方式:

from app import app
from gevent.pywsgi import WSGIServer
from config import Config

# 多进程启动app
def serve_forever(is_ssl,debug=False):
    threads = []
    app.debug = debug
    def http_task(listener, concurrency):
        server = WSGIServer(listener, app, \
                            spawn=concurrency)
        if Config.THREAD_NUM > 1:
            server.set_environ({'wsgi.multithread': True})
        server.serve_forever()

    listener = _tcp_listener(('0.0.0.0', 6677))
    for i in range(0, Config.THREAD_NUM - 1):
        t = threading.Thread(target=http_task, args=(listener, 'default'))
        t.start()
        threads.append(t)

    http_task(listener, 'default')

if __name__ == '__main__':
    debug = True
    # 测试log
    app.logger.info(f'........................log start.........................')
    serve_forever(True,debug)

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中使用FFmpeg进行多进程分割视频文件可以通过以下步骤实现: 1. 首先,你需要安装FFmpeg并确保它已经添加到系统的环境变量中。你可以从FFmpeg的官方网站(https://ffmpeg.org/)下载并安装它。 2. 在Python中,你可以使用`subprocess`模块来执行FFmpeg命令。首先,导入`subprocess`模块: ```python import subprocess ``` 3. 接下来,你可以使用`subprocess.Popen`函数来启动一个新的进程并执行FFmpeg命令。例如,你可以使用以下代码来分割视频文件: ```python def split_video(input_file, output_file, start_time, duration): command = ['ffmpeg', '-i', input_file, '-ss', start_time, '-t', duration, '-c', 'copy', output_file] process = subprocess.Popen(command) process.wait() ``` 在上面的代码中,`input_file`是输入视频文件的路径,`output_file`是输出视频文件的路径,`start_time`是分割开始的时间(以秒为单位),`duration`是分割的持续时间(以秒为单位)。 4. 如果你想要同时分割多个视频文件,你可以使用Python的多进程库(如`multiprocessing`)来实现并行处理。以下是一个示例代码: ```python import multiprocessing def split_video(input_file, output_file, start_time, duration): # 分割视频的代码 if __name__ == '__main__': input_files = ['video1.mp4', 'video2.mp4', 'video3.mp4'] output_files = ['output1.mp4', 'output2.mp4', 'output3.mp4'] start_times = [10, 20, 30] durations = [5, 10, 15] processes = [] for i in range(len(input_files)): process = multiprocessing.Process(target=split_video, args=(input_files[i], output_files[i], start_times[i], durations[i])) processes.append(process) process.start() for process in processes: process.join() ``` 在上面的代码中,`input_files`是输入视频文件的路径列表,`output_files`是输出视频文件的路径列表,`start_times`是分割开始的时间列表,`durations`是分割的持续时间列表。通过循环创建多个进程来同时处理多个视频文件的分割操作。 这样,你就可以使用FFmpeg和Python的多进程库来实现多进程分割视频文件了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值