【问题标题】:Display name of original module when calling another module调用另一个模块时显示原始模块的名称
【发布时间】:2020-05-21 14:33:48
【问题描述】:

我正在创建集中式日志记录。这基本上看起来像下面的脚本。

logit 模块将根据调用它的脚本名称创建一个文件。在这种情况下 apiCaller。

最初我在调用 logit 时手动定义了这个,但是我正在寻找 logit 以确定日志本身的来源。

这里有 3 个模块:

main.py:

def runAnalytic(script):
    importlib.import_module("monitoringScripts."+script["package"]+"."+script["module"], package=None)

packageModule = [{"package":"awesome","module":"apiCaller"}]

with concurrent.futures.ThreadPoolExecutor() as executor:
    results = executor.map(runAnalytic, packageModule)

apiCaller.py(上面的模块)

from adminTools.logger import logit
logit.create(results[i]["items"][r]["userId"],"apiCaller") #How i currently pass the script name, i want to get rid of this.

logit.py 处理我所有其他脚本的所有日志要求(集中式日志记录)

import sys, logging, logging.handlers, pathlib
#Path for all log files for scriptHub
logdir = str(pathlib.Path(__file__).parent.absolute())

#Creates the log file based on a given name from the script
def create(logMessage,scriptName, level="DEBUG"):
    #create filename
    log_filename = logdir+"/sysLogs/"+scriptName+".logs"
    #Creates the logging object
    my_logger = logging.getLogger(scriptName)
    my_logger.setLevel(logging.DEBUG)
    #Formats the log:
    formatter = logging.Formatter('%(asctime)s - %(message)s - %(name)s')
    #Gives the log file a limit for 100mb if it goes bigger than this, it will create another file, but keep the old one
    handler = logging.handlers.RotatingFileHandler(log_filename, maxBytes=100000000, backupCount=1)
    handler.setFormatter(formatter)
    #Handlers need to be cleared to stop duplicated logs.
    if (my_logger.hasHandlers()):
        my_logger.handlers.clear()
    my_logger.addHandler(handler)
    #creates the log message
    my_logger.debug(logMessage)

所以,我不确定这是否对你们所有人都有帮助或阻碍,哈哈

本质上,我希望 logit 从调用它的模块中获取它,而不是为 logit 提供脚本名称。例如,在这种情况下,“apiCaller”将是传递给 logit 的名称。

【问题讨论】:

  • 你可以使用%(module)s日志格式化器,见docs.python.org/2/library/logging.html的LogRecord属性部分
  • 当你做logging.getLogger时,你应该把__name__作为参数。 __name__ 是模块本身的名称(如果已导入)或 "__main__"(如果文件作为脚本运行)。然后日志格式化程序完成剩下的工作。
  • 如何从其他脚本调用您的脚本?什么是logit.py,为什么上面会打印test
  • @Dan 那个“模块”返回的是 logit 模块,而不是调用 logit 模块的那个。
  • @h4z3 name 只返回 logit 包结构(父母等)

标签: python python-3.x


【解决方案1】:

好的,改写问题:

我已经看到它以与您相反的方式完成 - 获取一个记录器,然后设置它(模块中有两行,而不是一行)。记录器是每个模块的东西,并且总是在那里。

在您的情况下,您每次都重新获取记录器并重新制作处理程序。

这样你就无法利用logging 模块提供的美好可能性!


所以基本上,另一种方法是:

在每个脚本中,您都执行logger = logging.getLogger(__name__),通常在靠近顶部的某个位置,在导入下方。

+您只需拨打logit.setupLogger(logger)即可。 (在你的情况下,在下一行。如果是脚本,我将它保存在 main 函数中 - 这样,如果我将脚本作为模块导入,我将在 imported_module.logger 上调用我需要的任何日志记录设置,所以它不会t 垃圾邮件错误的日志文件。:D)

重写logit.py

import sys, logging, logging.handlers, pathlib
#Path for all log files for scriptHub
logdir = str(pathlib.Path(__file__).parent.absolute())

#Creates the log file based on a given name from the script
def create(my_logger, level=logging.DEBUG):
    #create filename
    log_filename = logdir+"/sysLogs/"+logger.name+".logs"

    my_logger.setLevel(level)
    #Formats the log:
    formatter = logging.Formatter('%(asctime)s - %(message)s - %(name)s')
    #Gives the log file a limit for 100mb if it goes bigger than this, it will create another file, but keep the old one
    handler = logging.handlers.RotatingFileHandler(log_filename, maxBytes=100000000, backupCount=1)
    handler.setFormatter(formatter)
    #Handlers need to be cleared to stop duplicated logs.
    if (my_logger.hasHandlers()):
        my_logger.handlers.clear()
    my_logger.addHandler(handler)

这样,您只需在 logit 中设置记录器的内部 - 包括文件处理程序 - 即可使用标准的 logging 事物:

  • 您可以在模块中使用任何级别的日志记录:
logger.info("like")
logger.warning("this")
  • 您在上面的代码中编写每条日志消息 - 让代码充满日志消息! - 请记住调试消息应该包含调试所需的一切,这有时包括大量信息 + 请记住调试消息可能存在于信息消息旁边,只是具有不同的详细信息(例如,“从 X 获取信息”是信息,“已发送请求” some/address/here' 和收到的 '''chunk of data here'''" 正在调试)。
  • 当您需要降低关卡时 - 例如您调试了您的消息并且厌倦了看到 so.much.info(或只是从开发人员转到生产人员) - 您只需将 logit.setupLogger(logger) 更改为 logit.setupLogger(logger, logging.INFO) 或您需要的任何级别。

日志记录似乎是一个好主意,但当您学习如何使用它时,logging 模块非常强大。 :) Here's a How-To from Python's docs,但它有很多信息,所以simpler tutorials on python logging 是一个更好的开始。

Tbh 我也开始使用我自己的日志记录实践,即使在阅读了文档和教程之后,因为我根本没有得到它。当我看到它在我正在使用的库中使用时,我才切换到上面的方法。 :)

【讨论】:

    【解决方案2】:

    问题不是很清楚,但是可以使用inspect.stack()

    loggy.py

    import inspect
    
    def log(s):
        caller = inspect.stack()[1]
        print(f"{caller.filename} line {caller.lineno} says: {s}")
    

    thing.py

    import loggy
    
    loggy.log("Hey!")
    

    /v/f/n/8/T/tmp.ZiRzgsqi $ python3 thing.py
    thing.py line 3 says: Hey!
    /v/f/n/8/T/tmp.ZiRzgsqi $
    

    【讨论】:

    • 已经在其他地方找到了这个答案,但是由于您首先在这里写了它,所以您得到了信用:-) 谢谢。由于某种原因,我找不到其他帖子,但我确实投了赞成票。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多