我有一个名为data.py的主脚本,它将调用logger.py(用于日志(log)配置)和login.py(用于登录)

# data.py

from logger import configure_logger
from login import *
if __name__ == "__main__":
    script_name = (f"C:\\datalog") #save logfile in a different directory than script location
    logger = configure_logger(script_name)
    logger.info(f"This log is from data.py")
# logger.py

import logging
from datetime import datetime as dt
def configure_logger(script_name):
    py_name = ((__file__.split('\\')[-1]).split('.')[0]).upper()
    log_format = f'%(asctime)s - %(levelname)s - {py_name} - %(message)s'
    logging.basicConfig(filename=f"{script_name}_{dt.now().strftime('%Y%m%d-%H_%M_%S')}.log", level=logging.INFO, format=log_format)
    logger = logging.getLogger()
    return logger
# login.py

from logger import configure_logger
import os
import sys
script_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
logger = configure_logger(script_name)
logger.info(f"This log is from login.py")

我在datalog_<date_timestamp>.log年的预期yields :

2023-09-28 14:20:27,767 - INFO - LOGIN - This log is from login.py
2023-09-28 14:20:27,768 - INFO - DATA - This log is from data.py

BU以上脚本生成如下所示的输出到data_<date_timestamp>.log:(日志(log)文件中不需要文件名和名称)

2023-09-28 14:20:27,767 - INFO - LOGGER - This log is from login.py
2023-09-28 14:20:27,768 - INFO - LOGGER - This log is from data.py

我的登录和记录器模块是常见的,它将从多个主脚本调用,如data.py. 我需要根据我的主脚本中提到的名称(在本例中是-data.py)创建日志(log)文件,并且对于每个日志(log)条目,我希望包括执行它的原始脚本的名称.例如,如果运行的是login.py,我需要包括LOGIN作为名称,如果运行的是data.py,则必须是DATA

我怎样才能做到这一点呢?

推荐答案

因此,这里有几个问题.首先,__file__在logger.py中的确切位置进行求值.第二个logging.basicConfig被呼叫了两次.第二个呼吁被简单地忽略了.您可以通过从time导入sleep并在调用之前将sleep(3)添加到data.py中的configure_logger来测试这一点.秒数将滚动,从而产生不同的文件名,但只创建第一个文件.最后,您传递的是script_name的完全不同的值,但是,如上所述,第二个调用被忽略了.

未修改的文件名

如果您可以容忍它是小写的,并且扩展名为.py,那么您可以使用可用于日志(log)格式的内置文件名参数.这允许您完全删除logger.py文件以及对getLogger()的调用

# data.py

import logging
from datetime import datetime as dt

# Only put this here if logging needs to happen in imported modules OUTSIDE of functions
log_basename = "./datalog"
log_format = f'%(asctime)s - %(levelname)s - %(filename)s - %(message)s'
logging.basicConfig(filename=f"{log_basename}_{dt.now().strftime('%Y%m%d-%H_%M_%S')}.log", level=logging.INFO, format=log_format)

from login import *
if __name__ == "__main__":
    logging.info(f"This log is from data.py")
# login.py

import logging
logging.info(f"This log is from login.py")

这将提供以下输出:

2023-09-28 04:33:46,382 - INFO - login.py - This log is from login.py
2023-09-28 04:33:46,382 - INFO - data.py - This log is from data.py

正如 comments 所暗示的那样,将日志(log)配置放在导入之前是违反惯例的.如果所有日志(log)记录都发生在函数或主块中,则应该在导入之后设置日志(log)记录.或者,也可以将其移回其自己的文件中,然后再次导入.

import logging

from datetime import datetime as dt
from login import *

def setup_logging():
    log_basename = "./datalog"
    log_format = f'%(asctime)s - %(levelname)s - %(filename)s - %(message)s'
    logging.basicConfig(filename=f"{log_basename}_{dt.now().strftime('%Y%m%d-%H_%M_%S')}.log", level=logging.INFO, format=log_format)

if __name__ == "__main__":
    setup_logging()
    login_foo()
    logging.info(f"This log is from data.py")
# login.py

import logging

def login_foo():
    logging.info(f"This log is from login.py")

带有大小写更改的文件名

如果更改大小写并删除.py扩展名很重要,您可以使用context filter将修改后的文件名变量添加到记录器的字典中.

# data.py

import logging
from datetime import datetime as dt
from login import *

class ContextFilter(logging.Filter):
    def filter(self, record):
        record.FILENAME = record.filename[:-3].upper()
        return True


def setup_logging():
    log_basename = "./datalog"
    log_format = f'%(asctime)s - %(levelname)s - %(FILENAME)s - %(message)s'
    logging.basicConfig(filename=f"{log_basename}_{dt.now().strftime('%Y%m%d-%H_%M_%S')}.log", level=logging.INFO, format=log_format)
    f = ContextFilter()
    logging.getLogger().addFilter(f)


if __name__ == "__main__":
    setup_logging()
    login_foo()
    logging.info(f"This log is from data.py")

这提供了准确的所需输出.

2023-09-28 05:24:56,256 - INFO - LOGIN - This log is from login.py
2023-09-28 05:24:56,256 - INFO - DATA - This log is from data.py

Python相关问答推荐

单击cookie按钮,但结果不一致

在Python中添加期货之间的延迟

定义同侪组并计算同侪组分析

给定数据点,制定它们的关系

如何使用Python中的clinicalTrials.gov API获取完整结果?

在Python中为变量的缺失值创建虚拟值

try 与gemini-pro进行多轮聊天时出错

由于NEP 50,向uint 8添加-256的代码是否会在numpy 2中失败?

Python json.转储包含一些UTF-8字符的二元组,要么失败,要么转换它们.我希望编码字符按原样保留

如何在Python中并行化以下搜索?

数据抓取失败:寻求帮助

对所有子图应用相同的轴格式

try 将一行连接到Tensorflow中的矩阵

运输问题分支定界法&

如何调整QscrollArea以正确显示内部正在变化的Qgridlayout?

Python Pandas获取层次路径直到顶层管理

Pandas:计算中间时间条目的总时间增量

如何将数据帧中的timedelta转换为datetime

如何在Great Table中处理inf和nans

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion