Обратите внимание, что если threading
модуля обезьяна заплат, потоки в значительной степени преобразуется в greenlets. В частности, исправление обезьяны заменяет _start_new_thread()
(так что вместо этого запускается новая зелень), а также _get_ident()
(так что идентификатор Greenlet возвращается всякий раз, когда запрашивается идентификатор потока). Благодаря этому сопоставлению, всякий раз, когда вы спрашиваете о текущем потоке, на самом деле вы получаете экземпляр объекта dunky Thread
, связанный с текущей запущенной зеленью!
Таким образом, вполне возможно сделать следующее:
import gevent.monkey
gevent.monkey.patch_thread()
from threading import current_thread
# and then, at the start of the greenlet
current_thread().name = "MyNewName"
Теперь, когда logging
код извлекает текущее имя нити, он получает за-greenlet имя. Я должен признать, что это немного взломанный, но в моем текущем проекте он очень хорошо работает.
И вот доказательство концепции:
import gevent.monkey
gevent.monkey.patch_thread()
import logging
from threading import current_thread
logger = logging.getLogger()
def foo():
current_thread().name = "MyFoo"
logger.debug('Running in foo')
gevent.sleep(0)
logger.debug('Explicit context switch to foo again')
def bar():
current_thread().name = "MyBar"
logger.debug('Explicit context to bar')
gevent.sleep(0)
logger.debug('Implicit context switch back to bar')
logging.basicConfig(level=logging.DEBUG,
format='%(levelname)s %(threadName)s %(message)s')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
При выполнении, он печатает:
DEBUG MyFoo Running in foo
DEBUG MyBar Explicit context to bar
DEBUG MyFoo Explicit context switch to foo again
DEBUG MyBar Implicit context switch back to bar
Просто убедитесь, что threading
модуль пропатчен перед любым другим импортом (см this answer).
Это должен быть принятый ответ. Поскольку он использует адаптер протоколирования и стандартную функциональность gevent. – Realistic