|
| 1 | +#!/bin/env python3 |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +# @author DDDivano |
| 4 | +# encoding=utf-8 vi:ts=4:sw=4:expandtab:ft=python |
| 5 | +""" |
| 6 | +ServeTest |
| 7 | +""" |
| 8 | +import logging |
| 9 | +import os |
| 10 | +from datetime import datetime |
| 11 | + |
| 12 | +import pytz |
| 13 | + |
| 14 | + |
| 15 | +class Logger(object): |
| 16 | + """ |
| 17 | + 日志记录配置的基础类。 |
| 18 | + """ |
| 19 | + |
| 20 | + SAVE_LEVELS = ["both", "file", "channel"] |
| 21 | + LOG_FORMAT = "%(asctime)s - %(name)s - [%(levelname)s] - %(message)s" |
| 22 | + |
| 23 | + def __init__(self, loggername, save_level="both", log_path=None): |
| 24 | + """ |
| 25 | + 使用指定名称和保存级别初始化日志记录器。 |
| 26 | +
|
| 27 | + Args: |
| 28 | + loggername (str): 日志记录器的名称。 |
| 29 | + save_level (str): 日志保存的级别。默认为"both"。file: 仅保存到文件,channel: 仅保存到控制台。 |
| 30 | + log_path (str, optional): 日志文件保存路径。默认为None。 |
| 31 | + """ |
| 32 | + |
| 33 | + if save_level not in self.SAVE_LEVELS: |
| 34 | + raise ValueError(f"Invalid save level: {save_level}. Allowed values: {self.SAVE_LEVELS}") |
| 35 | + |
| 36 | + self.logger = logging.getLogger(loggername) |
| 37 | + self.logger.setLevel(logging.DEBUG) |
| 38 | + |
| 39 | + # 设置时区为东八区 |
| 40 | + tz = pytz.timezone("Asia/Shanghai") |
| 41 | + |
| 42 | + # 自定义时间格式化器,指定时区为东八区 |
| 43 | + class CSTFormatter(logging.Formatter): |
| 44 | + """ |
| 45 | + 自定义时间格式化器,指定时区为东八区 |
| 46 | + """ |
| 47 | + |
| 48 | + def converter(self, timestamp): |
| 49 | + """ |
| 50 | + 自定义时间转换函数,加上时区信息 |
| 51 | + Args: |
| 52 | + timestamp (int): 时间戳。 |
| 53 | + Returns: |
| 54 | + tuple: 格式化后的时间元组。 |
| 55 | + """ |
| 56 | + dt = datetime.utcfromtimestamp(timestamp) |
| 57 | + dt = pytz.utc.localize(dt).astimezone(tz) |
| 58 | + return dt.timetuple() |
| 59 | + |
| 60 | + formatter = CSTFormatter(self.LOG_FORMAT) |
| 61 | + log_name = None |
| 62 | + if save_level == "both" or save_level == "file": |
| 63 | + os.makedirs(log_path, exist_ok=True) |
| 64 | + log_filename = f"out_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log" |
| 65 | + log_name = os.path.join(log_path, log_filename) |
| 66 | + file_handler = logging.FileHandler(log_name, encoding="utf-8") |
| 67 | + file_handler.setLevel(logging.DEBUG) |
| 68 | + file_handler.setFormatter(formatter) |
| 69 | + self.logger.addHandler(file_handler) |
| 70 | + |
| 71 | + if save_level == "both" or save_level == "channel": |
| 72 | + console_handler = logging.StreamHandler() |
| 73 | + console_handler.setLevel(logging.DEBUG) |
| 74 | + console_handler.setFormatter(formatter) |
| 75 | + self.logger.addHandler(console_handler) |
| 76 | + |
| 77 | + if log_name is None: |
| 78 | + self.logger.info( |
| 79 | + f"Logger initialized. Log level: {save_level}. " |
| 80 | + f"Log path ({log_path}) is unused according to the level." |
| 81 | + ) |
| 82 | + else: |
| 83 | + self.logger.info(f"Logger initialized. Log level: {save_level}. Log path: {log_name}") |
| 84 | + # Adjusting the timezone offset |
| 85 | + |
| 86 | + def get_logger(self): |
| 87 | + """ |
| 88 | + Get the logger object |
| 89 | + """ |
| 90 | + return self.logger |
| 91 | + |
| 92 | + |
| 93 | +if __name__ == "__main__": |
| 94 | + # Test the logger |
| 95 | + logger = Logger("test_logger", save_level="channel").get_logger() |
| 96 | + logger.info("the is the beginning") |
| 97 | + logger.debug("the is the beginning") |
| 98 | + logger.warning("the is the beginning") |
| 99 | + logger.error("the is the beginning") |
0 commit comments