我正在使用 python 日志记录将调试信息写入文件并将其打印到屏幕上:
logger=logging.getLogger()
logger.setLevel(logging.INFO)
file_handler = logging.FileHandler("std.log", mode='w')
file_handler.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
logger.addHandler(file_handler)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))
class MeuManipulador(logging.Handler):
def emit(self, record):
if record.levelno == logging.ERROR:
log_entry = self.format(record)
if "No such comm target registered" in str(record.msg):
return
log(mensagem = log_entry)
logger.addHandler(MeuManipulador())
一切都运行良好,但在我的长代码的末尾有一个代码,其中 logger.info 或 logger.warning 运行正常。
logger.info('Dropando a tabela anterior')
with enginedb2 as conn:
try:
sql = ''' drop table DB2I023A.CNFC_CNV_HST_CTBL'''
conn.execute(text(sql))
conn.commit()
logger.info(f'comando SQL {sql} executado com sucesso')
time.sleep(1)
except ResourceClosedError as error:
logger.warning(f'comando SQL {sql} não foi executado com sucesso, resultando no erro : {error}')
pass
但是如果我使用 logger.error,我就会出现这个!
---------------------------------------------------------------------------
ResourceClosedError Traceback (most recent call last)
File <timed exec>:5
File /projeto/libs/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1418, in Connection.execute(self, statement, parameters, execution_options)
1417 else:
-> 1418 return meth(
1419 self,
1420 distilled_parameters,
1421 execution_options or NO_OPTIONS,
1422 )
File /projeto/libs/lib/python3.11/site-packages/sqlalchemy/sql/elements.py:515, in ClauseElement._execute_on_connection(self, connection, distilled_params, execution_options)
514 assert isinstance(self, Executable)
--> 515 return connection._execute_clauseelement(
516 self, distilled_params, execution_options
517 )
518 else:
File /projeto/libs/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1640, in Connection._execute_clauseelement(self, elem, distilled_parameters, execution_options)
1632 compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
1633 dialect=dialect,
1634 compiled_cache=compiled_cache,
(...)
1638 linting=self.dialect.compiler_linting | compiler.WARN_LINTING,
1639 )
-> 1640 ret = self._execute_context(
1641 dialect,
1642 dialect.execution_ctx_cls._init_compiled,
1643 compiled_sql,
1644 distilled_parameters,
1645 execution_options,
1646 compiled_sql,
1647 distilled_parameters,
1648 elem,
1649 extracted_params,
1650 cache_hit=cache_hit,
1651 )
1652 if has_events:
File /projeto/libs/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1813, in Connection._execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
1812 if conn is None:
-> 1813 conn = self._revalidate_connection()
1815 context = constructor(
1816 dialect, self, conn, execution_options, *args, **kw
1817 )
File /projeto/libs/lib/python3.11/site-packages/sqlalchemy/engine/base.py:680, in Connection._revalidate_connection(self)
679 return self._dbapi_connection
--> 680 raise exc.ResourceClosedError("This Connection is closed")
ResourceClosedError: This Connection is closed
During handling of the above exception, another exception occurred:
NameError Traceback (most recent call last)
File <timed exec>:10
File /usr/local/lib/python3.11/logging/__init__.py:1518, in Logger.error(self, msg, *args, **kwargs)
1509 """
1510 Log 'msg % args' with severity 'ERROR'.
1511
(...)
1515 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1516 """
1517 if self.isEnabledFor(ERROR):
-> 1518 self._log(ERROR, msg, args, **kwargs)
File /usr/local/lib/python3.11/logging/__init__.py:1634, in Logger._log(self, level, msg, args, exc_info, extra, stack_info, stacklevel)
1631 exc_info = sys.exc_info()
1632 record = self.makeRecord(self.name, level, fn, lno, msg, args,
1633 exc_info, func, extra, sinfo)
-> 1634 self.handle(record)
File /usr/local/lib/python3.11/logging/__init__.py:1644, in Logger.handle(self, record)
1637 """
1638 Call the handlers for the specified record.
1639
1640 This method is used for unpickled records received from a socket, as
1641 well as those created locally. Logger-level filtering is applied.
1642 """
1643 if (not self.disabled) and self.filter(record):
-> 1644 self.callHandlers(record)
File /usr/local/lib/python3.11/logging/__init__.py:1706, in Logger.callHandlers(self, record)
1704 found = found + 1
1705 if record.levelno >= hdlr.level:
-> 1706 hdlr.handle(record)
1707 if not c.propagate:
1708 c = None #break out
File /usr/local/lib/python3.11/logging/__init__.py:978, in Handler.handle(self, record)
976 self.acquire()
977 try:
--> 978 self.emit(record)
979 finally:
980 self.release()
File <timed exec>:17, in emit(self, record)
NameError: name 'log' is not defined
有什么建议吗?logging.error! 有什么特殊要求吗?
出现此问题是因为您的自定义日志处理程序(MeuManipulador)中的 emit 方法引用了代码中未定义的日志函数:
要解决 NameError,您需要确保已定义 log 或将其替换为所需行为。如果您打算以不同的方式记录错误消息或采取特定操作,请适当定义 log 或使用记录器方法。
如果您只是想使用另一种记录器方法记录错误:
log()
我认为,您应该在自定义处理程序类之前定义函数。你可以这样定义,