我正在使用 python 3.7 编写一个应用程序,并且只想在其中使用f 字符串。
我正在使用 python 日志记录模块来正确记录我的应用程序,我想使用特定的格式,但文档(和网络)仅举例说明如何使用 %-strings 更改格式。我想知道是否有使用 f-strings 设置记录器格式的选项
LOG_FORAMT = ('%(levelname)s -10s %(asctime)s -10s %(message)s') # Known example
f-LOG_FORMAT = (f'{logger.levelname} -10s') # Something like that?
Run Code Online (Sandbox Code Playgroud) 这是我的日志配置settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
'file': {
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'logs', 'django.log'),
},
},
'loggers': {
'django': {
'handlers': ['file', 'console'],
'level': 'DEBUG',
},
'django.template': {
'handlers': ['file', 'console'],
'level': 'INFO',
},
'App': {
'handlers': ['file', 'console'],
'level': 'DEBUG',
},
},
}
Run Code Online (Sandbox Code Playgroud)
有一种我无法解释的行为:如果我运行,debug=True我可以看到所有 SQL 查询都记录到控制台,但是当debug=False这种情况没有发生时,即使我不更改上面的配置。
为什么是这样?如何在日志配置中确定 SQL 查询是否记录到控制台?
我正在尝试测试单元测试中是否记录了警告。看来以下测试应该失败:
import logging
import unittest
LOG_FORMAT = '%(levelname)-10s %(asctime)s: %(message)s'
def set_up_logger(app_name, level=logging.INFO, file="test.log"):
formatter = logging.Formatter(LOG_FORMAT)
log = logging.getLogger(app_name)
# The next line lets the test pass
log.setLevel(level)
return log
logger = set_up_logger(__name__)
class TestLogging(unittest.TestCase):
def test_logging(self):
with self.assertLogs(level=logging.WARNING):
logger.info('foo')
Run Code Online (Sandbox Code Playgroud)
然而,它通过了 python 3.8.5。
如果我删除该log.setLevel(level)行,测试就会失败,正如预期的那样。如果我将该logger.info行替换为pass,那么测试也会按预期失败。
为什么在记录器上设置级别会让测试错误地通过?
我有一个相当大的 Python 项目,目前在 Linux 上运行,但我正在尝试扩展到 Windows。我已将代码简化为一个完整的示例,可以运行它来说明我的问题:我有两个类,Parent 和 Child。首先初始化父级,创建一个记录器,并生成一个子级来执行工作:
import logging
import logging.config
import multiprocessing
class Parent( object ):
def __init__(self, logconfig):
logging.config.dictConfig(logconfig)
self.logger = logging.getLogger(__name__)
def spawnChild(self):
self.logger.info('One')
c = Child(self.logger)
c.start()
class Child(multiprocessing.Process):
def __init__(self, logger):
multiprocessing.Process.__init__(self)
self.logger = logger
def run(self):
self.logger.info('Two')
if __name__ == '__main__':
p = Parent({
'version':1,
"handlers": {
"console": {
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout"
},
},
"root": {
"level": "DEBUG",
"handlers": [
"console",
]
}
}
)
p.spawnChild()
Run Code Online (Sandbox Code Playgroud)
在 Linux(特别是 ubuntu 12.04)上,我得到以下(预期)输出:
user@ubuntu:~$ python …Run Code Online (Sandbox Code Playgroud) 拥有两个或多个不同的日志文件是很实用的。例如,对于 Rest 服务,有一个日志文件用于一般故障,另一个日志文件用于内容中的错误。
我尝试使用 INI 文件执行此操作,但由于某种原因,所有日志都会转到这两个文件。所以...
如果我希望 logger1 中的所有日志都转到logger1.log,而 logger2 中的所有日志都转到logger2.log ,那么logging.ini会是什么样子:
logging.config.fileConfig('logging.ini')
logger1 = logging.getLogger('name1')
logger2 = logging.getLogger('name2')
Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的日志文件和流设置不同的记录器级别,并且我(似乎)遵循了演示(https://docs.python.org/3/howto/logging-cookbook.html)到点。但是,在我的实际代码中它不起作用。在测试脚本中运行这个演示是可行的:
import logging
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
print(logger.handlers)
print(logger)
Run Code Online (Sandbox Code Playgroud)
结果是
alex@alexpc:~/Projects/claritydb$ …Run Code Online (Sandbox Code Playgroud) 我正在 Jupyter Notebook 服务器上运行 Python 笔记本。我正在使用 Pythonlogging模块进行日志记录,当前已连接到日志stdout,就像任何控制台应用程序一样,在 Jupyter Notebook 输出中显示日志消息。
但stdout基于默认的日志输出感觉有限。与纯文本/ANSI 输出相比,HTML 输出可以做更多的事情。
是否有任何高级 Jupyter Notebook 日志处理程序和格式化程序可以理解输出是 HTML 并进行相应调整?例如,提供更丰富的颜色和字体大小格式选项,并交互式地探索日志消息上下文参数,就像 Sentry 允许人们做的那样?
我一直在尝试使用unittest --buffer标志来抑制成功测试的日志并显示失败测试的日志。但无论如何它似乎都会显示日志输出。这是日志记录模块的怪癖吗?如何仅在失败的测试中获取日志输出?记录器上是否需要特殊配置?我发现的其他问题和答案采用了暴力方法来禁用测试期间的所有日志记录。
import logging
import unittest
import sys
logger = logging.getLogger('abc')
logging.basicConfig(
format = '%(asctime)s %(module)s %(levelname)s: %(message)s',
level = logging.INFO,
stream = sys.stdout)
class TestABC(unittest.TestCase):
def test_abc_pass(self):
logger.info('log abc in pass')
print('print abc in pass')
self.assertTrue(True)
def test_abc_fail(self):
logger.info('log abc in fail')
print('print abc in fail')
self.assertTrue(False)
Run Code Online (Sandbox Code Playgroud)
$ python -m unittest --buffer
2021-09-15 17:38:48,462 test INFO: log abc in fail
F
Stdout:
print abc in fail
2021-09-15 17:38:48,463 test INFO: log abc in pass …Run Code Online (Sandbox Code Playgroud) 我正在使用RichHanderPython 内部格式化日志输出。虽然这在本地工作得很好,但当我在 GitLab 中运行时,它似乎默认使用 80 个字符宽的终端。这使得输出相当难以快速阅读和扫描。我想更改 RichHandler 的默认宽度,但我没有找到方法。
有没有办法为 Python RichHandler 日志处理程序设置最小控制台宽度?
# Pseudocode:
import logging
from rich.logging import RichHandler
def setup_logging():
logger = logging.getLogger('myLogger')
richFormatter = logging.Formatter('%(message)s')
richHandler = RichHandler()
# Something like: richHandler.setMinimumWidth(255)
richHandler.setFormatter(richFormatter)
logger.addHandler(richHandler)
Run Code Online (Sandbox Code Playgroud) 当我main.py在下面运行时,它会打印出来HELLO WORLD(一切正常)。但是,如果我重命名为console,python 会抛出此错误:。为什么更改处理程序名称会导致发生这种情况以及如何修复它?LOGGING_CONFIGsAttributeError: 'ConvertingDict' object has no attribute 'handle'
我有一个需要日志记录的 asyncio 应用程序,但是“日志记录模块在发出记录时使用阻塞 I/O。 ”Python 是logging.handlers.QueueHandler为此构建的,我正在尝试实现QueueHandlerwith dictConfig。我使用底部参考部分中的链接进行组合main.py。
这是main.py。请注意,文件名main.py很重要,因为main.QueueListenerHandler在LOGGING_CONFIG.
# main.py
import logging
import logging.config
import logging.handlers
import queue
import atexit
# This function resolves issues when using `cfg://handlers.[name]` where
# QueueListenerHandler complains that `cfg://handlers.[name]` isn't a handler.
def _resolve_handlers(myhandlers):
if not isinstance(myhandlers, logging.config.ConvertingList): …Run Code Online (Sandbox Code Playgroud) python-logging ×10
python ×6
python-3.x ×6
logging ×4
django ×1
f-string ×1
gitlab ×1
ipython ×1
python-3.6 ×1
python-3.7 ×1
rich ×1
windows ×1