openstack 基础库之 oslo_context
官方使用
- 例1:增加日志的上下文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from oslo_config import cfg
from oslo_context import context
from oslo_log import log as logging
CONF = cfg.CONF
DOMAIN = "demo"
logging.register_options(CONF)
logging.setup(CONF, DOMAIN)
LOG = logging.getLogger(__name__)
LOG.info("Message without context")
# ids in Openstack are 32 characters long
# For readability a shorter id value is used
context.RequestContext(user='6ce90b4d',
tenant='d6134462',
project_domain='a6b9360e')
LOG.info("Message with context") - 输出:会加上上下文信息
1
22016-01-21 17:30:50.263 12201 INFO __main__ [-] Message without context
2016-01-21 17:30:50.264 12201 INFO __main__ [req-e591e881-36c3-4627-a5d8-54df200168ef 6ce90b4d d6134462 - - a6b9360e] Message with context - 思考:
context.RequestContext()
仅仅新建一个对象为什么能够改变Log
的行为?
context 实现原理
oslo.context
包代码比较少,只有一个类,如下:
1 |
|
- 构造方法:将构造参数设置为实例的属性值,最后再用这一行调用对这些设置的值进行存储
self.update_store()
1 |
|
_request_store
是一个模块级的变量,在模块加载的时候初始化1
2import threading
_request_store = threading.local()线程本地存储
(Thread-local Storage)
是一种机制,允许每个线程在共享相同全局变量的情况下,拥有自己的独立变量副本。通过线程本地存储,每个线程可以独立地访问和修改自己的变量副本,而不会影响其他线程的副本
_request_store
用于在多线程环境下存储与请求相关的数据,以便每个线程可以访问和修改自己的请求数据,而不会与其他线程的数据发生冲突
- 在一个线程中
_request_store
相当于一个全局的变量 - 在不通的线程中,
_request_store
相互隔离
log 使用
oslo_log
有一个ContextFormatter
他就是用来 context 来格式化日志输出的,他会引用线程本地存储。
openstack 基础库之 oslo_context
http://mybestcheng.site/2023/08/31/openstack/oslo/context/