End user logging for audit traceabilty

Changes for Client to support new end user header
and add end user name to logs.

Change-Id: Iea1e42eafa573960735415ce337a1558b864edfc
This commit is contained in:
Smruti Soumitra Khuntia 2019-02-20 15:22:37 +05:30
parent 407ba6c47e
commit d12aa27712
5 changed files with 27 additions and 3 deletions

View File

@ -71,13 +71,15 @@ class BaseResource(object):
resp.status = status_code resp.status = status_code
def log_error(self, ctx, level, msg): def log_error(self, ctx, level, msg):
extra = {'user': 'N/A', 'req_id': 'N/A', 'external_ctx': 'N/A'} extra = {'user': 'N/A', 'req_id': 'N/A', 'external_ctx': 'N/A',
'end_user': 'N/A'}
if ctx is not None: if ctx is not None:
extra = { extra = {
'user': ctx.user, 'user': ctx.user,
'req_id': ctx.request_id, 'req_id': ctx.request_id,
'external_ctx': ctx.external_marker, 'external_ctx': ctx.external_marker,
'end_user': ctx.end_user,
} }
self.logger.log(level, msg, extra=extra) self.logger.log(level, msg, extra=extra)
@ -130,6 +132,7 @@ class DrydockRequestContext(object):
self.request_id = str(uuid.uuid4()) self.request_id = str(uuid.uuid4())
self.external_marker = '' self.external_marker = ''
self.policy_engine = None self.policy_engine = None
self.end_user = None # Initial User
@classmethod @classmethod
def from_dict(cls, d): def from_dict(cls, d):
@ -160,6 +163,7 @@ class DrydockRequestContext(object):
'authenticated': self.authenticated, 'authenticated': self.authenticated,
'request_id': self.request_id, 'request_id': self.request_id,
'external_marker': self.external_marker, 'external_marker': self.external_marker,
'end_user': self.end_user,
} }
def set_log_level(self, level): def set_log_level(self, level):
@ -187,6 +191,9 @@ class DrydockRequestContext(object):
def set_policy_engine(self, engine): def set_policy_engine(self, engine):
self.policy_engine = engine self.policy_engine = engine
def set_end_user(self, end_user):
self.end_user = end_user
def to_policy_view(self): def to_policy_view(self):
policy_dict = {} policy_dict = {}

View File

@ -87,10 +87,18 @@ class ContextMiddleware(object):
ctx = req.context ctx = req.context
ext_marker = req.get_header('X-Context-Marker') ext_marker = req.get_header('X-Context-Marker')
end_user = req.get_header('X-End-User')
if ext_marker is not None and self.marker_re.fullmatch(ext_marker): if ext_marker is not None and self.marker_re.fullmatch(ext_marker):
ctx.set_external_marker(ext_marker) ctx.set_external_marker(ext_marker)
# Set end user from req header in context obj if available
# else set the user as end user.
if end_user is not None:
ctx.set_end_user(end_user)
else:
ctx.set_end_user(ctx.user)
class LoggingMiddleware(object): class LoggingMiddleware(object):
def __init__(self): def __init__(self):
@ -101,6 +109,7 @@ class LoggingMiddleware(object):
'user': req.context.user, 'user': req.context.user,
'req_id': req.context.request_id, 'req_id': req.context.request_id,
'external_ctx': req.context.external_marker, 'external_ctx': req.context.external_marker,
'end_user': req.context.end_user,
} }
self.logger.info( self.logger.info(
"Request: %s %s %s" % (req.method, req.uri, req.query_string), "Request: %s %s %s" % (req.method, req.uri, req.query_string),
@ -112,6 +121,7 @@ class LoggingMiddleware(object):
'user': ctx.user, 'user': ctx.user,
'req_id': ctx.request_id, 'req_id': ctx.request_id,
'external_ctx': ctx.external_marker, 'external_ctx': ctx.external_marker,
'end_user': ctx.end_user,
} }
resp.append_header('X-Drydock-Req', ctx.request_id) resp.append_header('X-Drydock-Req', ctx.request_id)
self.logger.info( self.logger.info(

View File

@ -63,7 +63,8 @@ def start_drydock(enable_keystone=True):
config.config_mgr.conf.logging.control_logger_name) config.config_mgr.conf.logging.control_logger_name)
logger.propagate = False logger.propagate = False
formatter = logging.Formatter( formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' "%(asctime)s - %(levelname)s - %(user)s - %(req_id)s"
" - %(external_ctx)s - %(end_user)s - %(message)s"
) )
ch = logging.StreamHandler() ch = logging.StreamHandler()

View File

@ -39,6 +39,7 @@ class DrydockSession(object):
scheme='http', scheme='http',
auth_gen=None, auth_gen=None,
marker=None, marker=None,
end_user=None,
timeout=None): timeout=None):
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.__session = requests.Session() self.__session = requests.Session()
@ -47,8 +48,12 @@ class DrydockSession(object):
self.set_auth() self.set_auth()
self.marker = marker self.marker = marker
self.end_user = end_user
self.__session.headers.update({'X-Context-Marker': marker}) self.__session.headers.update({'X-Context-Marker': marker})
if end_user:
self.__session.headers.update({'X-End-User': end_user})
self.host = host self.host = host
self.scheme = scheme self.scheme = scheme

View File

@ -123,7 +123,8 @@ def setup_logging():
logger = logging.getLogger('drydock.control') logger = logging.getLogger('drydock.control')
logger.propagate = False logger.propagate = False
formatter = logging.Formatter( formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' "%(asctime)s - %(levelname)s - %(user)s - %(req_id)s"
" - %(external_ctx)s - %(end_user)s - %(message)s"
) )
ch = logging.StreamHandler() ch = logging.StreamHandler()