gpt4 book ai didi

python:日志记录:我们可以向记录器添加多个过滤器吗?考虑哪一个

转载 作者:太空宇宙 更新时间:2023-11-04 01:51:58 27 4
gpt4 key购买 nike

我试图了解 Python 日志记录中的多个过滤器(一个在配置中定义,另一个在代码中定义)是如何工作的。

我正在开发一个 Django 项目,下面是我在 settings.py 中的记录器配置

我的目标是随时打开关闭 记录器。所以使用过滤器我试图通过返回 False (0) 来关闭记录器

1) 启动时关闭记录器

class StartFilter(object):
def filter(self, record):
"""
Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0 for no, nonzero for
yes. If deemed appropriate, the record may be modified in-place.
"""
return 0

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(funcName)s() %(pathname)s[:%(lineno)s] %(name)s \n%(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'formatter': 'verbose',
'class': 'logging.StreamHandler',
},
},
'filters': {
'myfilter': {
'()': StartFilter,
}
},
'loggers': {
'log_testing': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
'filters': ['myfilter']
},
}
}

我已将过滤器添加到记录器。 '过滤器':['myfilter']

2) 在我希望看到日志记录的 views.py 文件中打开和关闭记录器

# to switch on logger
class LoggerGateStart(object):
def filter(self, record):
"""
Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0 for no, nonzero for
yes. If deemed appropriate, the record may be modified in-place.
"""
return 1

# to switch off logger
class LoggerGateStop(object):
def filter(self, record):
"""
Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0 for no, nonzero for
yes. If deemed appropriate, the record may be modified in-place.
"""
return 0

import logging
logger = logging.getLogger("log_testing")


...
logging.debug("Some text Before) # i dont want this to be logged
...



gatestart = LoggerGateStart()
logger_database.addFilter(gatestart)

...
logging.debug("Some text) # i want this to be logged
...

gatestop = LoggerGateStop()
logger_database.addFilter(gatestop)

...
logging.debug("Some text after") # i dont want this to be logged even
if it exist
...

我发现它不是这样工作的。它只考虑 StartFilter,不考虑 LoggerGateStart 或 LoggerGateStop,也不向控制台打印任何日志

我该怎么做

我根据 Gabriel C 的回答使用的回答

我的目标是使用 django 记录 sql django.db.backends .但它的问题是它会记录所有的sqls。我只想在代码的特定部分或任何我想查看 sql 的地方记录 sql。所以我可以通过以下方式做到这一点。

在 settings.py 中记录配置:

# Filter class to stop or start logging for "django.db.backends"
class LoggerGate:
def __init__(self, state='closed'):
# We found that the settings.py runs twice and the filters are created twice. So we have to keep only one. So we delete all the previous filters before we create the new one
import logging
logger_database = logging.getLogger("django.db.backends")
try:
for filter in logger_database.filters:
logger_database.removeFilter(filter)
except Exception as e:
pass
self.state = state

def open(self):
self.state = 'open'

def close(self):
self.state = 'closed'

def filter(self, record):
"""
Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0/False for no, nonzero/True for
yes. If deemed appropriate, the record may be modified in-place.
"""
return self.state == 'open'

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'sql': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
}
},
'filters': {
'myfilter': {
'()': LoggerGate,
}
},
'loggers': {
'django.db.backends': {
'handlers': ['sql'],
'level': 'DEBUG',
'propagate': False,
'filters': ['myfilter']
}
}
}

然后在views.py中

import logging
logger = logging.getLogger(__name__)
logger_database = logging.getLogger("django.db.backends")

def test1(request):


logger_database.filters[0].open()
#Will allow priting of sql satatements from here

from django import db
user_set = User.objects.all()

for user in user_set: # Here sql is executed and is printed to console
pass
#Will stop priting of sql satatements after this
logger_database.filters[0].close()

from django import db
user_set = User.objects.all()

for user in user_set: # Here sql is executed and is not printed to console
pass

now = datetime.datetime.now()
html = "<html><body>Internal purpose</body></html>"
return HttpResponse(html)

如果想以格式化和彩色的方式打印 sql,请在 settings.py 中使用它

# SQL formatter to be used for the handler used in logging "django.db.backends"
class SQLFormatter(logging.Formatter):
def format(self, record):

# Check if Pygments is available for coloring
try:
import pygments
from pygments.lexers import SqlLexer
from pygments.formatters import TerminalTrueColorFormatter
except ImportError:
pygments = None

# Check if sqlparse is available for indentation
try:
import sqlparse
except ImportError:
sqlparse = None

# Remove leading and trailing whitespaces
sql = record.sql.strip()

if sqlparse:
# Indent the SQL query
sql = sqlparse.format(sql, reindent=True)

if pygments:
# Highlight the SQL query
sql = pygments.highlight(
sql,
SqlLexer(),
#TerminalTrueColorFormatter(style='monokai')
TerminalTrueColorFormatter()
)

# Set the record's statement to the formatted query
record.statement = sql
return super(SQLFormatter, self).format(record)




# Filter class to stop or start logging for "django.db.backends"
class LoggerGate:
def __init__(self, state='closed'):
# We found that the settings.py runs twice and the filters are created twice. So we have to keep only one. So we delete all the previous filters before we create the new one
import logging
logger_database = logging.getLogger("django.db.backends")
try:
for filter in logger_database.filters:
logger_database.removeFilter(filter)
except Exception as e:
pass
self.state = state

def open(self):
self.state = 'open'

def close(self):
self.state = 'closed'

def filter(self, record):
"""
Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0/False for no, nonzero/True for
yes. If deemed appropriate, the record may be modified in-place.
"""
return self.state == 'open'

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'sql': {
'()': SQLFormatter,
'format': '[%(duration).3f] %(statement)s',
}
},
'handlers': {
'sql': {
'class': 'logging.StreamHandler',
'formatter': 'sql',
'level': 'DEBUG',
}
},
'filters': {
'myfilter': {
'()': LoggerGate,
}
},
'loggers': {
'django.db.backends': {
'handlers': ['sql'],
'level': 'DEBUG',
'propagate': False,
'filters': ['myfilter']
}
}
}

最佳答案

只创建一个过滤器并使用它的实例来控制是否应接受日志。

from logging import getLogger

class LoggerGate(object):

def __init__(self):
self.started = False

def start(self):
self.started = True

def stop(self):
self.started = False

def filter(self, record):
"""
Determine if the specified record is to be logged.

Returns True is this LoggerGate is started, False otherwise.
"""
return self.started


logger_database = getLogger("log_testing")
logger_gate = LoggerGate()
logger_database.addFilter(logger_gate)

logger_database.critical('this is not logged')
logger_gate.start()
logger_database.critical('this is logged')
logger_gate.stop()
logger_database.critical('this is not logged')

关于python:日志记录:我们可以向记录器添加多个过滤器吗?考虑哪一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57795153/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com