-
-
Notifications
You must be signed in to change notification settings - Fork 251
Open
Labels
Description
This is based on @PrieJos's helpful analysis in #693 (comment)
In async log methods, callsite collection happens in the async logger thread which makes its thread-related information worthless:
# /// script
# dependencies = [
# "structlog",
# ]
# ///
import asyncio
import logging
import sys
import structlog
sl = structlog.get_logger()
logger = logging.getLogger()
logging.basicConfig(
stream=sys.stdout,
format=(
"%(process)d %(processName)s %(module)s"
" %(funcName)s:%(lineno)d %(threadName)s %(taskName)s"
" %(message)s"
),
datefmt=r"%Y-%m-%dT%H:%M:%S",
level=logging.INFO,
encoding="utf-8",
)
structlog.configure(
processors=[
structlog.processors.CallsiteParameterAdder(
[
structlog.processors.CallsiteParameter.PROCESS,
structlog.processors.CallsiteParameter.PROCESS_NAME,
structlog.processors.CallsiteParameter.MODULE,
structlog.processors.CallsiteParameter.FILENAME,
structlog.processors.CallsiteParameter.FUNC_NAME,
structlog.processors.CallsiteParameter.LINENO,
structlog.processors.CallsiteParameter.THREAD_NAME,
]
),
structlog.processors.LogfmtRenderer(),
],
)
async def afunc():
await sl.ainfo("async")
logger.info("stdlib async")
def func():
sl.info("sync")
logger.info("stdlib sync")
asyncio.run(afunc())
func()
Notably, thread name is wrong and so would be a task name as shown in #698:
event=async process=55347 process_name=n/a module=t filename=t.py func_name=afunc lineno=47 thread_name=asyncio_0
55347 MainProcess t afunc:48 MainThread Task-1 stdlib async
event=sync process=55347 process_name=n/a module=t filename=t.py func_name=func lineno=51 thread_name=MainThread
55347 MainProcess t func:52 MainThread None stdlib sync
Not sure how to deal with this most elegantly – I feel like we'll have to pass thread/task objects into the event_dict or something?
I think the process_name
is in fact correct, since logging
just sets it unconditionally and we get n/a
in sync code too. Happy to be corrected, though.