регистрация переменной с поддержкой сопрограмм - PullRequest
1 голос
/ 08 марта 2019

Я следую примеру работника, приведенному в asyncio.Queue. В функциях, вызываемых worker_task(), я бы хотел записать текущее имя работника, не передавая его везде.

Я подозреваю, что через некоторую комбинацию LoggerAdapter и ContextVar он может делать то, что я хочу.

Что-то вроде следующего ...

import logging
logging.basicConfig(format="%(worker_name)s %(message)s")
logger = logging.getLogger(__name__)

async def sub_function():
    logger.info("a message") # worker-1: a message

async def worker_task(queue, worker_name):
    logger.do_something(worker_name) # HELP HERE PLEASE
    await sub_function()

queue = asyncio.Queue()

workers = [
    loop.create_task(worker_task(queue, "worker-1"),
    loop.create_task(worker_task(queue, "worker-2"),
]

1 Ответ

3 голосов
/ 08 марта 2019

Вы можете использовать что-то вроде этого:

import logging
import asyncio
from contextvars import ContextVar

WorkerName = ContextVar('worker_name')

logging.basicConfig(format='%(worker_name)s %(message)s', level=logging.INFO)

class WorkerAdapter(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        kwargs.setdefault('extra', {})['worker_name'] = WorkerName.get()
        return msg, kwargs

logger = WorkerAdapter(logging.getLogger(__name__), None)


async def sub_function():
    logger.info('a message')

async def worker_task(worker_name):
    WorkerName.set(worker_name)
    await sub_function()

loop = asyncio.get_event_loop()

workers = [
    loop.create_task(worker_task('worker-1')),
    loop.create_task(worker_task('worker-2')),
]

loop.run_until_complete(asyncio.gather(*workers))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...