I am using python logging to write debug information to a file and print it to my screen :
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())
Everuthing runs fine, but on the end of my long code there is a code where logger.info or logger.warning runs ok.
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
But if I use logger.error, I get this!
---------------------------------------------------------------------------
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
Any tips? Is there any special requirements for logging.error!?
The issue arises because the emit method in your custom logging handler (MeuManipulador) refers to a log function that is not defined in your code:
log(mensagem = log_entry)
To resolve the NameError, you need to ensure that log is defined or replace it with the desired behavior. If you intend to log the error message differently or take specific action, define log appropriately or use a logger method.
If you simply want to log the error using another logger method:
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
logger.error(log_entry) # Log the error message