Source code for pyloggers

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# date:        2019/5/26
# author:      he.zhiming
#

from __future__ import (absolute_import, unicode_literals)

import functools
import inspect
import logging
import sys
import threading
from logging import handlers

_THREADLOCAL = threading.local()
_THREADLOCAL.loggername_logger = {}


class _Logger(object):
    _DEFAULT_FORMAT = ('[%(levelname)s] '
                       '[%(asctime)s %(created)f] '
                       '[%(name)s %(module)s] '
                       '[%(process)d %(processName)s %(thread)d %(threadName)s] '
                       '[%(filename)s %(lineno)s %(funcName)s] '
                       '%(message)s')
    _DEFAULT_FORMATTER = logging.Formatter(fmt=_DEFAULT_FORMAT)
    _DEFAULT_LOG_FILENAME = './PYTHON_LOG.log'
    _DEFAULT_SINGLE_FILE_MAX_BYTES = (1 * 1024 * 1024 * 1024)  # 1G
    _DEFAULT_BACKUP_COUNT = 10
    _DEFAULT_FILE_ENCODING = 'UTF-8'

    def __init__(self, logger_name, logger_level=logging.INFO, logger_filename=None, max_bytes=None, backup_count=None):
        self._logger_name = logger_name
        self._logger_filename = logger_filename or self._DEFAULT_LOG_FILENAME
        self._max_bytes = max_bytes or self._DEFAULT_SINGLE_FILE_MAX_BYTES
        self._backup_count = (backup_count or self._DEFAULT_BACKUP_COUNT)

        self._logger = logging.Logger(logger_name, level=logger_level)

        self._init()

    def get_real_logger(self):
        """

        :rtype: logging.Logger
        :return:
        """
        return self._logger

    def _init(self):
        if self._logger_filename is None:
            self._logger.addHandler(self._get_console_stream_handler())
            return
        else:
            self._logger.addHandler(self._get_rotating_file_handler())

    def _get_console_stream_handler(self):
        h = logging.StreamHandler()
        formatter = logging.Formatter(fmt=self._DEFAULT_FORMAT)
        h.setFormatter(formatter)

        return h

    def _get_rotating_file_handler(self):
        h = handlers.RotatingFileHandler(self._logger_filename,
                                         maxBytes=self._max_bytes,
                                         backupCount=self._backup_count,
                                         encoding=self._DEFAULT_FILE_ENCODING)

        h.setFormatter(self._DEFAULT_FORMATTER)

        return h

    @classmethod
    def get_console_logger(cls, logger_name, level=logging.DEBUG):
        logger = logging.Logger(logger_name)
        h = logging.StreamHandler(stream=sys.stdout)
        h.setFormatter(cls._DEFAULT_FORMATTER)
        h.setLevel(level)

        logger.addHandler(h)
        logger.setLevel(level)

        return logger


[docs]def make_file_logger(logger_name, level=logging.INFO, filename=None, max_bytes=None, backup_count=None): """获取一个logger,记录内容到文件里面 :param logger_name: :param level: :param filename: :param max_bytes: :param backup_count: :return: """ if logger_name in _THREADLOCAL.loggername_logger: return _THREADLOCAL.loggername_logger[logger_name] logger = _Logger( logger_name, logger_level=level, logger_filename=filename, max_bytes=max_bytes, backup_count=backup_count).get_real_logger() _THREADLOCAL.loggername_logger[logger_name] = logger return logger
# 记录控制台输入的日志器 CONSOLE = _Logger.get_console_logger('CONSOLE_LOGGER')
[docs]def log(func): """记录函数的输入-输出值 Usage: @log def add(a, b): :param func: :return: """ @functools.wraps(func) def _wrapper(*args, **kwargs): ismethod = inspect.ismethod(func) CONSOLE.info(f"====function start.==== {args} {kwargs}") func_result = func(*args, **kwargs) CONSOLE.info(f"==== function end. ==== {func_result}") return func_result return _wrapper