Issue
I minimal my problem as next:
logger.conf:
###################################
[loggers]
keys=root
[logger_root]
level=DEBUG
handlers=handlerScreen,handlerFile
###################################
[handlers]
keys=handlerScreen,handlerFile
[handler_handlerScreen]
class=StreamHandler
level=DEBUG
formatter=formScreen
args=(sys.stderr,)
[handler_handlerFile]
class=FileHandler
level=INFO
formatter=formFile
args=('%(log_file)s', 'a')
###################################
[formatters]
keys=formScreen,formFile
[formatter_formScreen]
format=%(asctime)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S
[formatter_formFile]
format=%(asctime)s %(filename)-21s[line:%(lineno)-3d] %(levelname)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S
fc.py:
import asyncio
import logging.config
logging.config.fileConfig("logger.conf", defaults=dict(log_file="run.log"))
async def fun():
print("1")
1/0
print("2")
async def action():
asyncio.create_task(fun())
print("do other tasks at once")
await asyncio.sleep(5)
asyncio.run(action())
Execution:
$ python3 fc.py
do other tasks at once
1
Question:
You could see 1/0
didn't print any error in screen, but as 2
not be print, so I guess the exception already happen, just I can't see anything in screen, why could that happen?
What I have tried?
Disable file logging:
import asyncio import logging.config # Disable file logging # logging.config.fileConfig("logger.conf", defaults=dict(log_file="run.log")) async def fun(): print("1") 1/0 print("2") async def action(): asyncio.create_task(fun()) print("do other tasks at once") await asyncio.sleep(5) asyncio.run(action())
Then it run as next:
$ python3 fc.py do other tasks at once 1 Task exception was never retrieved future: <Task finished name='Task-2' coro=<fun() done, defined at fc.py:6> exception=ZeroDivisionError('division by zero')> Traceback (most recent call last): File "fc.py", line 9, in fun 1/0 ZeroDivisionError: division by zero
Add
try...except
:import asyncio import logging.config logging.config.fileConfig("logger.conf", defaults=dict(log_file="run.log")) async def fun(): print("1") try: 1/0 except Exception as e: print(e) print("2") async def action(): asyncio.create_task(fun()) print("do other tasks at once") await asyncio.sleep(5) asyncio.run(action())
Then, it run as next:
$ python3 fc.py do other tasks at once 1 division by zero 2
So, how can I make the error be shown without disable file logging, meanwhile without using explicit try...catch
? If I could know why my situation happen, that will be better.
NOTE: await asyncio.create_task(fun())
is not what I need. In my scenario, I can't wait fun
be finished then do next actions. I use Python 3.8.10
if that mattered.
Solution
After check the source of asyncio
, I got the reason: asyncio also use logging
to print the exception:
asyncio/log.py:
import logging
logger = logging.getLogger(__package__)
asyncio/base_events.py:
def default_exception_handler(self, context):
"""Default exception handler.
This is called when an exception occurs and no exception
handler is set, and can be called by a custom exception
handler that wants to defer to the default behavior.
......
"""
......
logger.error('\n'.join(log_lines), exc_info=exc_info)
So, asyncio define a logger with name "asyncio" (__package__). However, in my logger.conf
, I just define a logger with keys=root
, this is the reason the error not be shown to screen.
So, change logger.conf
to next could work, although I didn't know how to let logger.conf
default handle all logger
without explictly specify them:
##################################
[loggers]
keys=root,asyncio
[logger_root]
level=DEBUG
handlers=handlerScreen,handlerFile
[logger_asyncio]
level=DEBUG
qualname=asyncio
handlers=handlerScreen,handlerFile
Answered By - atline
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.