Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以在登录时为gevent greenlet设置显示的自定义名称吗?_Python_Logging_Gevent_Greenlets - Fatal编程技术网

Python 我可以在登录时为gevent greenlet设置显示的自定义名称吗?

Python 我可以在登录时为gevent greenlet设置显示的自定义名称吗?,python,logging,gevent,greenlets,Python,Logging,Gevent,Greenlets,当我使用标准的logging包从greenlets中打印日志语句时,我得到如下文本: 2014-02-06 22:38:43,428 [INFO] (11396-Dummy-2) event_listener: About to block 我指的是11396-Dummy-2部分。例如,我想改为说“Main”或“listener1”。这可能吗?从当前的文档中,我看不到任何API可以这样做。我不确定日志中的11396-Dummy-2部分来自何处,但是如果您想向日志中添加上下文信息(如greenl

当我使用标准的
logging
包从greenlets中打印日志语句时,我得到如下文本:

2014-02-06 22:38:43,428 [INFO] (11396-Dummy-2) event_listener: About to block

我指的是
11396-Dummy-2
部分。例如,我想改为说“Main”或“listener1”。这可能吗?从当前的文档中,我看不到任何API可以这样做。

我不确定日志中的
11396-Dummy-2
部分来自何处,但是如果您想向日志中添加上下文信息(如greenlet标识符),则有很多方法可以这样做。下面是一个示例,使用
LoggerAdapter

import logging
import gevent

class Adapter(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        msg = '(%s) %s' % (gevent.getcurrent()._run.__name__, msg)
        return msg, kwargs

logger = Adapter(logging.getLogger(), {})

def foo():
    logger.debug('Running in foo')
    gevent.sleep(0)
    logger.debug('Explicit context switch to foo again')

def bar():
    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 MainThread (foo) Running in foo
DEBUG MainThread (bar) Explicit context to bar
DEBUG MainThread (foo) Explicit context switch to foo again
DEBUG MainThread (bar) Implicit context switch back to bar

我不确定日志中的
11396-Dummy-2
部分是从哪里来的,但是如果您想向日志中添加上下文信息(例如greenlet标识符),有很多方法。下面是一个示例,使用
LoggerAdapter

import logging
import gevent

class Adapter(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        msg = '(%s) %s' % (gevent.getcurrent()._run.__name__, msg)
        return msg, kwargs

logger = Adapter(logging.getLogger(), {})

def foo():
    logger.debug('Running in foo')
    gevent.sleep(0)
    logger.debug('Explicit context switch to foo again')

def bar():
    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 MainThread (foo) Running in foo
DEBUG MainThread (bar) Explicit context to bar
DEBUG MainThread (foo) Explicit context switch to foo again
DEBUG MainThread (bar) Implicit context switch back to bar

注意,如果
threading
module是monkey-patched,那么线程几乎映射到greenlet。特别是monkey patching替换了
\u start\u new\u thread()
(因此它会启动一个新的greenlet),以及
\u get\u ident()
(因此每当请求线程ID时都会返回greenlet ID)。由于这种映射,无论何时询问当前线程,实际上都会得到一个与当前运行的greenlet关联的虚拟
线程
对象实例

因此,完全可以执行以下操作:

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
code检索当前线程名称时,它都会获取每个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
模块进行了修补(请参阅)。

注意,如果
threading
模块进行了monkey修补,则线程几乎映射到greenlet。特别是monkey patching替换了
\u start\u new\u thread()
(因此它会启动一个新的greenlet),以及
\u get\u ident()
(因此每当请求线程ID时都会返回greenlet ID)。由于这种映射,无论何时询问当前线程,实际上都会得到一个与当前运行的greenlet关联的虚拟
线程
对象实例

因此,完全可以执行以下操作:

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
code检索当前线程名称时,它都会获取每个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

只需确保在任何其他导入之前对
线程
模块进行了修补(请参阅)。

这应该是可接受的答案。因为它使用日志适配器和标准gevent功能。这应该是公认的答案。因为它使用日志适配器和标准gevent功能。