0

0

详解python日志打印和写入并发实现代码

高洛峰

高洛峰

发布时间:2017-03-21 09:04:37

|

2697人浏览过

|

来源于php中文网

原创

大家一般都用logging日志打印,但logging是线程安全的,多进程也有很多介绍,引入一些文件锁,对logging做好配置,能过支持。

但通过测试,发现多进程时还是容易出现重复写入文件或者打印正常漏写入文件的问题。

我的日志需求比较简单,能够区分文件,正确的写入日志文件。

引入文件锁;日志写入函数封装到一个操作_Logger类中; 日志名称和写入级别封装到一个业务类Logger中。

本范例基于python3实现。本范例20个进程并发,分别写入3个文件,每s每个文件写入超过100行数据,日志文件中没有数据冗余,也没有数据遗漏。

ima.copilot
ima.copilot

腾讯大混元模型推出的智能工作台产品,提供知识库管理、AI问答、智能写作等功能

下载

立即学习Python免费学习笔记(深入)”;

详解python日志打印和写入并发实现代码

# -*-coding:utf-8-*- 
"""
Author:yinshunyao
Date:2017/3/5 0005下午 10:50
"""
# import logging
import os
import time
# 利用第三方系统锁实现文件锁定和解锁
if os.name == 'nt':
    import win32con, win32file, pywintypes
    LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
    LOCK_SH = 0  # The default value
    LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
    __overlapped = pywintypes.OVERLAPPED()


    def lock(file, flags):
        hfile = win32file._get_osfhandle(file.fileno())
        win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)

    def unlock(file):
        hfile = win32file._get_osfhandle(file.fileno())
        win32file.UnlockFileEx(hfile, 0, 0xffff0000, __overlapped)

elif os.name == 'posix':
    from fcntl import LOCK_EX


    def lock(file, flags):
        fcntl.flock(file.fileno(), flags)

    def unlock(file):
        fcntl.flock(file.fileno(), fcntl.LOCK_UN)
else:
    raise RuntimeError("File Locker only support NT and Posix platforms!") 



class _Logger:
    file_path = ''    #初始化日志路径

    @staticmethod
    def init():

        if not _Logger.file_path:
            _Logger.file_path = '%s/Log' % os.path.abspath(os.path.dirname(__file__))
        return True

    @staticmethod
    def _write(messge, file_name):
        if not messge:
            return True
        messge = messge.replace('\t', ',')
        file = '{}/{}'.format(_Logger.file_path, file_name)
        while True:
            try:
                f = open(file, 'a+')
                lock(f, LOCK_EX)
                break
            except:
                time.sleep(0.01)
                continue

        # 确保缓冲区内容写入到文件
        while True:
            try:
                f.write(messge + '\n')
                f.flush()
                break
            except:
                time.sleep(0.01)
                continue

        while True:
            try:
                unlock(f)
                f.close()
                return True
            except:
                time.sleep(0.01)
                continue
        @staticmethod
    def write(message, file_name, only_print=False):
        if not _Logger.init(): return
        print(message)
        if not only_print:
            _Logger._write(message, file_name)


class Logger:
    def __init__(self, logger_name, file_name=''):
        self.logger_name = logger_name
        self.file_name = file_name    # 根据消息级别,自定义格式,生成消息

    def _build_message(self, message, level):
        try:
            return '[%s]\t[%5s]\t[%8s]\t%s' \
                   % (time.strftime('%Y-%m-%d %H:%M:%S'), level, self.logger_name, message)
        except Exception as e:
            print('解析日志消息异常:{}'.format(e))
            return ''

    def warning(self, message):
        _Logger.write(self._build_message(message, 'WARN'), self.file_name)

    def warn(self, message):
        _Logger.write(self._build_message(message, 'WARN'), self.file_name)

    def error(self, message):
        _Logger.write(self._build_message(message, 'ERROR'), self.file_name)

    def info(self, message):
        _Logger.write(self._build_message(message, 'INFO'), self.file_name, True)

    def debug(self, message):
        _Logger.write(self._build_message(message, 'DEBUG'), self.file_name) 
# 循环打印日志测试函数


def _print_test(count):
    logger = Logger(logger_name='test{}'.format(count), file_name='test{}'.format(count % 3))
    key = 0
    while True:
        key += 1
        # print('{}-{}'.format(logger, key))
        logger.debug('%d' % key)
        logger.error('%d' % key)

if __name__ == '__main__':
    from multiprocessing import Pool, freeze_support
    freeze_support()    # 进程池进行测试
    pool = Pool(processes=20)
    count = 0
    while count < 20:
        count += 1
        pool.apply_async(func=_print_test, args=(count,))
    else:
        pool.close()
        pool.join()

相关文章

全能打印神器
全能打印神器

全能打印神器是一款非常好用的打印软件,可以在电脑、手机、平板电脑等设备上使用。支持无线打印和云打印,操作非常简单,使用起来也非常方便,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

17

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

6

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

1

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

2

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

1

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

53

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

26

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号