我正在尝试为python日志库创建一个包装器类。其思想是,用户可以向构造函数提供记录器的名称,并根据json文件的内容配置实例,其中提供的名称是配置文件相应部分的键
这是我的密码
class LogLib:
def __init__(self, logger_name=""):
conf_dict = Config.get("LogLib")
logging_config.dictConfig(conf_dict)
if not logger_name:
self.logger = logging.getLogger()
else:
self.logger = logging.getLogger(logger_name)
def debug(self, message, db=False):
caller_info = self.get_callerInfo()
msg = message + caller_info
self.logger.debug(msg)
if db:
self.log_db(message, "DEBUG")
def info(self, message, db=False):
caller_info = self.get_callerInfo()
msg = message + caller_info
self.logger.info(msg)
if db:
self.log_db(message, "INFO")
def warning(self, message, db=False):
caller_info = self.get_callerInfo()
msg = message + caller_info
self.logger.warning(msg)
if db:
self.log_db(message, "WARNING")
def error(self, message, db=False, stacktrace=False):
caller_info = self.get_callerInfo()
msg = message + caller_info
self.logger.error(msg, exc_info=stacktrace)
if db:
self.log_db(message, "ERROR")
def critical(self, message, db=False, stacktrace=False):
caller_info = self.get_callerInfo()
msg = message + caller_info
self.logger.critical(msg, exc_info=stacktrace)
if db:
self.log_db(message, "CRITICAL")
def log_db(self, message, level):
raise NotImplemented()
# psql = PostgresqlConnector()
# with psql.create_session() as session:
# psql.insert(session, Log(message=message, level=level))
def get_callerInfo(self):
raw = self.logger.findCaller(stack_info=False)
caller_fileName = raw[0].rsplit("/", 1)[1].split(".")[0]
return f"\nSOURCE > {caller_fileName}.{raw[2]}, Line: {raw[1]}\n"
为了进行一些测试,我在LogLib文件的底部添加了一个小main(),位于类之外。看起来是这样的:
def main():
logger = LogLib(logger_name="db_logger")
logger.debug("Debug test - This should not show up in the file.")
logger.info("Info test")
logger.warning("Warning test")
logger.error("Error test")
if __name__ == "__main__":
main()
为了配置这个包装器,我创建了一个JSON格式的配置部分,然后将其提取并在中使用。配置如下所示:
"LogLib": {
"version": 1,
"root": {
"handlers": ["console", "file"],
"level": "DEBUG"
},
"db_logger": {
"handlers": ["db_file"],
"level": "INFO"
},
"handlers": {
"console": {
"formatter": "console_formatter",
"class": "logging.StreamHandler",
"level": "WARNING"
},
"file": {
"formatter": "file_formatter",
"class": "logging.FileHandler",
"level": "DEBUG",
"filename": "C:\\Users\\name\\Documents\\GitHub\\proj\\logs\\app_err.log"
},
"db_file": {
"formatter": "file_formatter",
"class": "logging.FileHandler",
"level": "INFO",
"filename": "C:\\Users\\name\\Documents\\GitHub\\proj\\logs\\db.log"
}
},
"formatters": {
"console_formatter": {
"format": "%(asctime)s [%(levelname)s] > %(message)s",
"datefmt": "%d/%m/%Y-%I:%M:%S"
},
"file_formatter": {
"format": "%(asctime)s [%(levelname)s] > %(message)s",
"datefmt": "%d/%m/%Y-%I:%M:%S"
}
}
}
根记录器在其配置方式上工作良好(写入app_err.log并打印到控制台以获得给定级别),但当我尝试为其提供名称“db_logger”时,它不工作,默认为root
我想要的是,当用户通过参数“logger_name”向构造函数提供名称时,它应该检查具有该名称的记录器的配置,并将为该名称指定的配置应用于LogLib实例。在本例中,我希望所有级别为INFO或更高的日志消息都发送到名为db.log的文件中,而不需要任何控制台输出
我已经检查了文档并搜索了堆栈溢出,但到目前为止我还无法理解我做错了什么。在此问题上的任何协助都将不胜感激。 多谢各位
我认为
logging
包装器总体上是一种糟糕的设计,我在商业和OSS代码库中都看到过许多包装器。我将其称为Python中的反模式,因为logging
包实际上是非常可扩展的,并且很少会超过its (extension) mechanisms特别是关于这个片段的一些观点
除非您想在运行时更改JSON配置文件,否则没有 每个记录器调用
logging.config.dictConfig
的点。叫它 一次性应用程序引导如果您确实想在运行时更改日志记录配置,请注意 可能需要设置
disable_existing_loggers=False
。有一个警告 关于这一点,请参阅文件:Incremental Configuration还有以下警告:
如果仍要继续^{} 可以是
灵感
你不需要},{},{},{}。揭露他们
在日志中,以字符串或子类的格式引用它们
get_callerInfo
LogRecord
有这些{a4}:{logging.Formatter
因为您需要一些格式化逻辑要将日志记录写入新介质,例如Postgres(stdlib^{} 或第三方软件包尚不支持)?编写
logging.Handler
的子类。还请注意,记录到生产数据库可能很棘手。两个示例:logbeam(AWS CloudWatch日志的日志处理程序)和Chronologer(我编写的用MySQL和SQLite编写的Python客户机/服务器日志系统)感谢您的回复@saaj
我不需要在运行时更改配置。但是,这将在高度分布式的环境中运行(使用Celery)。 我不熟悉引导的详细工作原理,但我认为为了执行一些小任务而创建的芹菜工人并不是应用程序主执行线程的一部分(如果我在这里遗漏了什么,请纠正我)。我想说的是,在生成芹菜工人时,afaik没有引导过程,因此工人看不到配置。我没有看到任何情况下,我们希望在运行时更改配置,这些更改将以计划的方式进行,然后在整个应用程序重新启动后应用。 我真正想要的是能够为特定上下文创建日志记录程序(例如:两个密切相关的模块应该以相同的方式配置日志记录/记录到相同的特定文件)。 我不知道如何配置日志记录,以便具有不同名称值的模块都记录到同一个文件中
我之所以得到这样的配置,是因为它与我们配置应用程序其他部分的方式一致。我的团队希望所有配置都存储在一个高度保护的文件中。 它有点旧,在我被派去工作之前就是这样设计的。我想我不能改变它
我很确定我曾尝试在配置(logging.formatter)中公开这些,但没有找到正确的值。它只是显示有关日志库的信息,而不是与日志库相关的信息 调用日志包装器的模块
当我们想要登录到postgresql数据库时,我将看看如何创建logging.Handler的子类
我感谢你的反馈和建议
相关问题 更多 >
编程相关推荐