Skip to content

Commit

Permalink
Add examples from _logging.py as tests. This found a couple
Browse files Browse the repository at this point in the history
more issues in in the recorder code itself which were fixed.

Add new tests and fixe code error in recorder

1. Added several new tests that test WBEMConnection end-end against the
mocker.  These are largely from the  in the _logger.py doc string.

2. Found issue with output of single objects (ex. get_class) with
detail_level = `summary'

3. Found issue where when config_logger has only one logger defined
the other logger is never really setup in recorder.  The detail
level is never reset from None.  Fixed this by adding test to each
logger stage to not log if detail level is None.
This is independent of whether the logger itself is set.

This fixes TestLoggingExamples. (test_5 where basicconfig is set and we
try to log the api for which we did not set the detail level.
  • Loading branch information
KSchopmeyer committed Apr 8, 2018
1 parent af6db25 commit cef65eb
Show file tree
Hide file tree
Showing 2 changed files with 302 additions and 22 deletions.
53 changes: 37 additions & 16 deletions pywbem/_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,13 +555,15 @@ def __init__(self, conn_id, detail_levels=None):
self._conn_id = conn_id

self.detail_levels = {}

# logging only occurs if the corresponding detail level is not None
self.api_detail_level = None
self.http_detail_level = None
self.api_maxlen = None
self.http_maxlen = None
self.set_detail_level(detail_levels)

# build name for logger
# build name for logger for this connection
if conn_id:
self.apilogger = logging.getLogger(
'%s.%s' % (LOGGER_API_CALLS_NAME, conn_id))
Expand All @@ -575,7 +577,6 @@ def set_detail_level(self, detail_levels):
"""
Sets the detail levels from the input dictionary in detail_levels.
"""

if detail_levels is None:
return

Expand All @@ -593,17 +594,27 @@ def stage_wbem_connection(self, wbem_connection):
"""
Log connection information. This includes the connection id (conn_id)
that is output with the log entry. This entry is logged if either
http or api loggers are enable.
http or api loggers are enable. It honors both the logger and
detail level of either api logger if defined or http logger if defined.
If the api logger does not exist, the output shows this as an http
loggger output since we do not want to create an api logger for this
specific output
"""
self._conn_id = wbem_connection.conn_id

if self.enabled:
if self.api_detail_level or self.http_detail_level:
if self.api_detail_level == 'summary':
fmt_str = 'Connection:%s %s'
else:
fmt_str = 'Connection:%s %r'
self.apilogger.debug(fmt_str, self._conn_id, wbem_connection)
if self.api_detail_level is not None:
logger = self.apilogger
detail_level = self.api_detail_level
elif self.http_detail_level is not None:
logger = self.httplogger
detail_level = self.http_detail_level
else:
return

fmt_str = 'Connection:%s %s' if detail_level == 'summary' else \
'Connection:%s %r'
logger.debug(fmt_str, self._conn_id, wbem_connection)

def stage_pywbem_args(self, method, **kwargs):
"""
Expand All @@ -616,7 +627,8 @@ def stage_pywbem_args(self, method, **kwargs):
"""
# pylint: disable=attribute-defined-outside-init
self._pywbem_method = method
if self.enabled and self.apilogger.isEnabledFor(logging.DEBUG):
if self.enabled and self.api_detail_level is not None and \
self.apilogger.isEnabledFor(logging.DEBUG):

# TODO: future bypassed code to only ouput name and method if the
# detail is summary. We are not doing this because this is
Expand Down Expand Up @@ -655,11 +667,17 @@ def format_result(ret, max_len):
ret_type = type(ret[0]).__name__ if ret else ""
return 'list of %s; count=%s' % (ret_type, len(ret))
return 'Empty'

ret_type = type(ret).__name__
if hasattr(ret, 'classname'):
name = ret.classname
elif hasattr(ret, 'name'):
name = ret.name
else:
result = ret
result_fmt = '{0!r}'.format(result)
name = ""
return '%s %s' % (ret_type, name)

if self.api_detail_level == 'paths':
elif self.api_detail_level == 'paths':
if isinstance(ret, list):
if ret:
if hasattr(ret[0], 'path'):
Expand All @@ -681,7 +699,8 @@ def format_result(ret, max_len):
result_fmt = result_fmt[:max_len] + '...'
return result_fmt

if self.enabled and self.apilogger.isEnabledFor(logging.DEBUG):
if self.enabled and self.api_detail_level is not None and \
self.apilogger.isEnabledFor(logging.DEBUG):
if exc: # format exception
# exceptions are always either all or reduced length
result = format_result(
Expand Down Expand Up @@ -735,7 +754,8 @@ def format_result(ret, max_len):
def stage_http_request(self, conn_id, version, url, target, method, headers,
payload):
"""Log request HTTP information including url, headers, etc."""
if self.enabled and self.httplogger.isEnabledFor(logging.DEBUG):
if self.enabled and self.http_detail_level is not None and \
self.httplogger.isEnabledFor(logging.DEBUG):
# pylint: disable=attribute-defined-outside-init
# if Auth header, mask data
if 'Authorization' in headers:
Expand Down Expand Up @@ -773,7 +793,8 @@ def stage_http_response2(self, payload):
# parameters. We ignore that
if not self._http_response_version and not payload:
return
if self.enabled and self.httplogger.isEnabledFor(logging.DEBUG):
if self.enabled and self.http_detail_level is not None and \
self.httplogger.isEnabledFor(logging.DEBUG):
if self._http_response_headers:
header_str = \
' '.join('{0}:{1!r}'.format(k, v)
Expand Down
Loading

0 comments on commit cef65eb

Please sign in to comment.