Adding domain to context and log
Add support for upcoming "domain" concept in Keystone V3 API in both logging and context. Closes-Bug: #1248936 Implements: blueprint add-domain-info-to-context Change-Id: Ic2cf3e52cfcc0b8adccdf9c59afaa4014708a303
This commit is contained in:
parent
9feea9c15e
commit
c50d3d633b
@ -36,12 +36,18 @@ class RequestContext(object):
|
|||||||
accesses the system, as well as additional request information.
|
accesses the system, as well as additional request information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, auth_token=None, user=None, tenant=None, is_admin=False,
|
user_idt_format = '{user} {tenant} {domain} {user_domain} {p_domain}'
|
||||||
|
|
||||||
|
def __init__(self, auth_token=None, user=None, tenant=None, domain=None,
|
||||||
|
user_domain=None, project_domain=None, is_admin=False,
|
||||||
read_only=False, show_deleted=False, request_id=None,
|
read_only=False, show_deleted=False, request_id=None,
|
||||||
instance_uuid=None):
|
instance_uuid=None):
|
||||||
self.auth_token = auth_token
|
self.auth_token = auth_token
|
||||||
self.user = user
|
self.user = user
|
||||||
self.tenant = tenant
|
self.tenant = tenant
|
||||||
|
self.domain = domain
|
||||||
|
self.user_domain = user_domain
|
||||||
|
self.project_domain = project_domain
|
||||||
self.is_admin = is_admin
|
self.is_admin = is_admin
|
||||||
self.read_only = read_only
|
self.read_only = read_only
|
||||||
self.show_deleted = show_deleted
|
self.show_deleted = show_deleted
|
||||||
@ -51,14 +57,25 @@ class RequestContext(object):
|
|||||||
self.request_id = request_id
|
self.request_id = request_id
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
user_idt = (
|
||||||
|
self.user_idt_format.format(user=self.user or '-',
|
||||||
|
tenant=self.tenant or '-',
|
||||||
|
domain=self.domain or '-',
|
||||||
|
user_domain=self.user_domain or '-',
|
||||||
|
p_domain=self.project_domain or '-'))
|
||||||
|
|
||||||
return {'user': self.user,
|
return {'user': self.user,
|
||||||
'tenant': self.tenant,
|
'tenant': self.tenant,
|
||||||
|
'domain': self.domain,
|
||||||
|
'user_domain': self.user_domain,
|
||||||
|
'project_domain': self.project_domain,
|
||||||
'is_admin': self.is_admin,
|
'is_admin': self.is_admin,
|
||||||
'read_only': self.read_only,
|
'read_only': self.read_only,
|
||||||
'show_deleted': self.show_deleted,
|
'show_deleted': self.show_deleted,
|
||||||
'auth_token': self.auth_token,
|
'auth_token': self.auth_token,
|
||||||
'request_id': self.request_id,
|
'request_id': self.request_id,
|
||||||
'instance_uuid': self.instance_uuid}
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'user_identity': user_idt}
|
||||||
|
|
||||||
|
|
||||||
def get_admin_context(show_deleted=False):
|
def get_admin_context(show_deleted=False):
|
||||||
|
@ -130,7 +130,7 @@ generic_log_opts = [
|
|||||||
log_opts = [
|
log_opts = [
|
||||||
cfg.StrOpt('logging_context_format_string',
|
cfg.StrOpt('logging_context_format_string',
|
||||||
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
||||||
'%(name)s [%(request_id)s %(user)s %(tenant)s] '
|
'%(name)s [%(request_id)s %(user_identity)s] '
|
||||||
'%(instance)s%(message)s',
|
'%(instance)s%(message)s',
|
||||||
help='format string to use for log messages with context'),
|
help='format string to use for log messages with context'),
|
||||||
cfg.StrOpt('logging_default_format_string',
|
cfg.StrOpt('logging_default_format_string',
|
||||||
@ -332,10 +332,12 @@ class ContextAdapter(BaseLoggerAdapter):
|
|||||||
elif instance_uuid:
|
elif instance_uuid:
|
||||||
instance_extra = (CONF.instance_uuid_format
|
instance_extra = (CONF.instance_uuid_format
|
||||||
% {'uuid': instance_uuid})
|
% {'uuid': instance_uuid})
|
||||||
extra.update({'instance': instance_extra})
|
extra['instance'] = instance_extra
|
||||||
|
|
||||||
extra.update({"project": self.project})
|
extra.setdefault('user_identity', kwargs.pop('user_identity', None))
|
||||||
extra.update({"version": self.version})
|
|
||||||
|
extra['project'] = self.project
|
||||||
|
extra['version'] = self.version
|
||||||
extra['extra'] = extra.copy()
|
extra['extra'] = extra.copy()
|
||||||
return msg, kwargs
|
return msg, kwargs
|
||||||
|
|
||||||
|
@ -370,6 +370,43 @@ class FancyRecordTestCase(test.BaseTestCase):
|
|||||||
(ctxt.request_id, ctxt.instance_uuid)))
|
(ctxt.request_id, ctxt.instance_uuid)))
|
||||||
|
|
||||||
|
|
||||||
|
class DomainTestCase(test.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(DomainTestCase, self).setUp()
|
||||||
|
self.config = self.useFixture(config.Config()).config
|
||||||
|
self.config(logging_context_format_string="[%(request_id)s]: "
|
||||||
|
"%(user_identity)s "
|
||||||
|
"%(message)s")
|
||||||
|
self.mylog = log.getLogger()
|
||||||
|
self.stream = six.StringIO()
|
||||||
|
handler = logging.StreamHandler(self.stream)
|
||||||
|
handler.setFormatter(log.ContextFormatter())
|
||||||
|
self.mylog.logger.addHandler(handler)
|
||||||
|
self.mylog.logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
def _validate_keys(self, ctxt, keyed_log_string):
|
||||||
|
infoexpected = "%s info\n" % (keyed_log_string)
|
||||||
|
warnexpected = "%s warn\n" % (keyed_log_string)
|
||||||
|
|
||||||
|
self.mylog.info("info", context=ctxt)
|
||||||
|
self.assertEqual(infoexpected, self.stream.getvalue())
|
||||||
|
|
||||||
|
self.mylog.warn("warn", context=ctxt)
|
||||||
|
self.assertEqual(infoexpected + warnexpected, self.stream.getvalue())
|
||||||
|
|
||||||
|
def test_domain_in_log_msg(self):
|
||||||
|
ctxt = _fake_context()
|
||||||
|
ctxt.domain = 'mydomain'
|
||||||
|
ctxt.project_domain = 'myprojectdomain'
|
||||||
|
ctxt.user_domain = 'myuserdomain'
|
||||||
|
user_identity = ctxt.to_dict()['user_identity']
|
||||||
|
self.assertTrue(ctxt.domain in user_identity)
|
||||||
|
self.assertTrue(ctxt.project_domain in user_identity)
|
||||||
|
self.assertTrue(ctxt.user_domain in user_identity)
|
||||||
|
self._validate_keys(ctxt, ('[%s]: %s' %
|
||||||
|
(ctxt.request_id, user_identity)))
|
||||||
|
|
||||||
|
|
||||||
class SetDefaultsTestCase(test.BaseTestCase):
|
class SetDefaultsTestCase(test.BaseTestCase):
|
||||||
class TestConfigOpts(cfg.ConfigOpts):
|
class TestConfigOpts(cfg.ConfigOpts):
|
||||||
def __call__(self, args=None):
|
def __call__(self, args=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user