当前位置:Gxlcms > Python > 详解python日志打印和写入并发实现代码

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

时间:2021-07-01 10:21:17 帮助过:82人阅读

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

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

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

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

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

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

  1. # -*-coding:utf-8-*-
  2. """
  3. Author:yinshunyao
  4. Date:2017/3/5 0005下午 10:50
  5. """
  6. # import logging
  7. import os
  8. import time
  9. # 利用第三方系统锁实现文件锁定和解锁
  10. if os.name == 'nt':
  11. import win32con, win32file, pywintypes
  12. LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
  13. LOCK_SH = 0 # The default value
  14. LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
  15. __overlapped = pywintypes.OVERLAPPED()
  16. def lock(file, flags):
  17. hfile = win32file._get_osfhandle(file.fileno())
  18. win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)
  19. def unlock(file):
  20. hfile = win32file._get_osfhandle(file.fileno())
  21. win32file.UnlockFileEx(hfile, 0, 0xffff0000, __overlapped)
  22. elif os.name == 'posix':
  23. from fcntl import LOCK_EX
  24. def lock(file, flags):
  25. fcntl.flock(file.fileno(), flags)
  26. def unlock(file):
  27. fcntl.flock(file.fileno(), fcntl.LOCK_UN)
  28. else:
  29. raise RuntimeError("File Locker only support NT and Posix platforms!")
  30. class _Logger:
  31. file_path = '' #初始化日志路径
  32. @staticmethod
  33. def init():
  34. if not _Logger.file_path:
  35. _Logger.file_path = '%s/Log' % os.path.abspath(os.path.dirname(__file__))
  36. return True
  37. @staticmethod
  38. def _write(messge, file_name):
  39. if not messge:
  40. return True
  41. messge = messge.replace('\t', ',')
  42. file = '{}/{}'.format(_Logger.file_path, file_name)
  43. while True:
  44. try:
  45. f = open(file, 'a+')
  46. lock(f, LOCK_EX)
  47. break
  48. except:
  49. time.sleep(0.01)
  50. continue
  51. # 确保缓冲区内容写入到文件
  52. while True:
  53. try:
  54. f.write(messge + '\n')
  55. f.flush()
  56. break
  57. except:
  58. time.sleep(0.01)
  59. continue
  60. while True:
  61. try:
  62. unlock(f)
  63. f.close()
  64. return True
  65. except:
  66. time.sleep(0.01)
  67. continue
  68. @staticmethod
  69. def write(message, file_name, only_print=False):
  70. if not _Logger.init(): return
  71. print(message)
  72. if not only_print:
  73. _Logger._write(message, file_name)
  74. class Logger:
  75. def __init__(self, logger_name, file_name=''):
  76. self.logger_name = logger_name
  77. self.file_name = file_name # 根据消息级别,自定义格式,生成消息
  78. def _build_message(self, message, level):
  79. try:
  80. return '[%s]\t[%5s]\t[%8s]\t%s' \
  81. % (time.strftime('%Y-%m-%d %H:%M:%S'), level, self.logger_name, message)
  82. except Exception as e:
  83. print('解析日志消息异常:{}'.format(e))
  84. return ''
  85. def warning(self, message):
  86. _Logger.write(self._build_message(message, 'WARN'), self.file_name)
  87. def warn(self, message):
  88. _Logger.write(self._build_message(message, 'WARN'), self.file_name)
  89. def error(self, message):
  90. _Logger.write(self._build_message(message, 'ERROR'), self.file_name)
  91. def info(self, message):
  92. _Logger.write(self._build_message(message, 'INFO'), self.file_name, True)
  93. def debug(self, message):
  94. _Logger.write(self._build_message(message, 'DEBUG'), self.file_name)
  95. # 循环打印日志测试函数
  96. def _print_test(count):
  97. logger = Logger(logger_name='test{}'.format(count), file_name='test{}'.format(count % 3))
  98. key = 0
  99. while True:
  100. key += 1
  101. # print('{}-{}'.format(logger, key))
  102. logger.debug('%d' % key)
  103. logger.error('%d' % key)
  104. if __name__ == '__main__':
  105. from multiprocessing import Pool, freeze_support
  106. freeze_support() # 进程池进行测试
  107. pool = Pool(processes=20)
  108. count = 0
  109. while count < 20:
  110. count += 1
  111. pool.apply_async(func=_print_test, args=(count,))
  112. else:
  113. pool.close()
  114. pool.join()

以上就是详解python日志打印和写入并发实现代码的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行