Merge "Add trace facility"

This commit is contained in:
Jenkins 2016-07-13 01:21:21 +00:00 committed by Gerrit Code Review
commit d5fe51cb54
4 changed files with 106 additions and 6 deletions

View File

@ -111,6 +111,7 @@ connector_list = [
] ]
@utils.trace
def get_connector_properties(root_helper, my_ip, multipath, enforce_multipath, def get_connector_properties(root_helper, my_ip, multipath, enforce_multipath,
host=None, execute=None): host=None, execute=None):
"""Get the connection properties for all protocols. """Get the connection properties for all protocols.
@ -148,7 +149,6 @@ def get_connector_properties(root_helper, my_ip, multipath, enforce_multipath,
if (utils.platform_matches(props['platform'], connector.platform) and if (utils.platform_matches(props['platform'], connector.platform) and
utils.os_matches(props['os_type'], connector.os_type)): utils.os_matches(props['os_type'], connector.os_type)):
LOG.debug("Fetching connector for %s", connector.__name__)
props = utils.merge_dict(props, props = utils.merge_dict(props,
connector.get_connector_properties( connector.get_connector_properties(
root_helper, root_helper,
@ -621,6 +621,7 @@ class ISCSIConnector(BaseLinuxConnector, BaseISCSIConnector):
"""Where do we look for iSCSI based volumes.""" """Where do we look for iSCSI based volumes."""
return '/dev/disk/by-path' return '/dev/disk/by-path'
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
"""Get the list of existing paths for a volume. """Get the list of existing paths for a volume.
@ -895,6 +896,7 @@ class ISCSIConnector(BaseLinuxConnector, BaseISCSIConnector):
run_as_root=True, run_as_root=True,
root_helper=self._root_helper) root_helper=self._root_helper)
@utils.trace
@synchronized('extend_volume') @synchronized('extend_volume')
def extend_volume(self, connection_properties): def extend_volume(self, connection_properties):
"""Update the local kernel's size information. """Update the local kernel's size information.
@ -914,6 +916,7 @@ class ISCSIConnector(BaseLinuxConnector, BaseISCSIConnector):
{'props': connection_properties}) {'props': connection_properties})
raise exception.VolumePathsNotFound() raise exception.VolumePathsNotFound()
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Attach the volume to instance_name. """Attach the volume to instance_name.
@ -983,10 +986,9 @@ class ISCSIConnector(BaseLinuxConnector, BaseISCSIConnector):
device_info['multipath_id'] = multipath_id device_info['multipath_id'] = multipath_id
device_info['path'] = host_device device_info['path'] = host_device
LOG.debug("connect_volume returning %s", device_info)
return device_info return device_info
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach the volume from instance_name. """Detach the volume from instance_name.
@ -1429,6 +1431,7 @@ class FibreChannelConnector(BaseLinuxConnector):
host_paths = self._get_host_devices(possible_devs, lun) host_paths = self._get_host_devices(possible_devs, lun)
return host_paths return host_paths
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
volume_paths = [] volume_paths = []
# first fetch all of the potential paths that might exist # first fetch all of the potential paths that might exist
@ -1443,6 +1446,7 @@ class FibreChannelConnector(BaseLinuxConnector):
return volume_paths return volume_paths
@utils.trace
@synchronized('extend_volume') @synchronized('extend_volume')
def extend_volume(self, connection_properties): def extend_volume(self, connection_properties):
"""Update the local kernel's size information. """Update the local kernel's size information.
@ -1459,6 +1463,7 @@ class FibreChannelConnector(BaseLinuxConnector):
{'props': connection_properties}) {'props': connection_properties})
raise exception.VolumePathsNotFound() raise exception.VolumePathsNotFound()
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Attach the volume to instance_name. """Attach the volume to instance_name.
@ -1543,7 +1548,6 @@ class FibreChannelConnector(BaseLinuxConnector):
device_path = self.host_device device_path = self.host_device
device_info['path'] = device_path device_info['path'] = device_path
LOG.debug("connect_volume returning %s", device_info)
return device_info return device_info
def _get_host_devices(self, possible_devs, lun): def _get_host_devices(self, possible_devs, lun):
@ -1590,6 +1594,7 @@ class FibreChannelConnector(BaseLinuxConnector):
raw_devices.append((pci_num, target_wwn)) raw_devices.append((pci_num, target_wwn))
return raw_devices return raw_devices
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach the volume from instance_name. """Detach the volume from instance_name.
@ -1730,6 +1735,7 @@ class AoEConnector(BaseLinuxConnector):
def get_search_path(self): def get_search_path(self):
return '/dev/etherd' return '/dev/etherd'
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
aoe_device, aoe_path = self._get_aoe_info(connection_properties) aoe_device, aoe_path = self._get_aoe_info(connection_properties)
volume_paths = [] volume_paths = []
@ -1748,6 +1754,7 @@ class AoEConnector(BaseLinuxConnector):
'device': aoe_device} 'device': aoe_device}
return aoe_device, aoe_path return aoe_device, aoe_path
@utils.trace
@lockutils.synchronized('aoe_control', 'aoe-') @lockutils.synchronized('aoe_control', 'aoe-')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Discover and attach the volume. """Discover and attach the volume.
@ -1804,6 +1811,7 @@ class AoEConnector(BaseLinuxConnector):
return device_info return device_info
@utils.trace
@lockutils.synchronized('aoe_control', 'aoe-') @lockutils.synchronized('aoe_control', 'aoe-')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach and flush the volume. """Detach and flush the volume.
@ -1913,10 +1921,12 @@ class RemoteFsConnector(BaseLinuxConnector):
path = mount_point + '/' + connection_properties['name'] path = mount_point + '/' + connection_properties['name']
return path return path
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
path = self._get_volume_path(connection_properties) path = self._get_volume_path(connection_properties)
return [path] return [path]
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Ensure that the filesystem containing the volume is mounted. """Ensure that the filesystem containing the volume is mounted.
@ -1935,6 +1945,7 @@ class RemoteFsConnector(BaseLinuxConnector):
path = self._get_volume_path(connection_properties) path = self._get_volume_path(connection_properties)
return {'path': path} return {'path': path}
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""No need to do anything to disconnect a volume in a filesystem. """No need to do anything to disconnect a volume in a filesystem.
@ -1996,6 +2007,7 @@ class RBDConnector(BaseLinuxConnector):
linuxrbd.RBDImageMetadata(rbd_volume, pool, user, conf)) linuxrbd.RBDImageMetadata(rbd_volume, pool, user, conf))
return rbd_handle return rbd_handle
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect to a volume. """Connect to a volume.
@ -2008,6 +2020,7 @@ class RBDConnector(BaseLinuxConnector):
rbd_handle = self._get_rbd_handle(connection_properties) rbd_handle = self._get_rbd_handle(connection_properties)
return {'path': rbd_handle} return {'path': rbd_handle}
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Disconnect a volume. """Disconnect a volume.
@ -2071,6 +2084,7 @@ class LocalConnector(BaseLinuxConnector):
# TODO(walter-boring): not sure what to return here. # TODO(walter-boring): not sure what to return here.
return [] return []
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect to a volume. """Connect to a volume.
@ -2090,6 +2104,7 @@ class LocalConnector(BaseLinuxConnector):
'path': connection_properties['device_path']} 'path': connection_properties['device_path']}
return device_info return device_info
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Disconnect a volume from the local host. """Disconnect a volume from the local host.
@ -2130,6 +2145,7 @@ class DRBDConnector(BaseLinuxConnector):
return super(DRBDConnector, self).check_valid_device(path, run_as_root) return super(DRBDConnector, self).check_valid_device(path, run_as_root)
@utils.trace
def get_all_available_volumes(self, connection_properties=None): def get_all_available_volumes(self, connection_properties=None):
base = "/dev/" base = "/dev/"
@ -2160,6 +2176,7 @@ class DRBDConnector(BaseLinuxConnector):
return (out, err) return (out, err)
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Attach the volume.""" """Attach the volume."""
@ -2173,12 +2190,14 @@ class DRBDConnector(BaseLinuxConnector):
return device_info return device_info
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach the volume.""" """Detach the volume."""
self._drbdadm_command("down", connection_properties, self._drbdadm_command("down", connection_properties,
connection_properties['provider_auth']) connection_properties['provider_auth'])
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
path = connection_properties['device'] path = connection_properties['device']
return [path] return [path]
@ -2227,10 +2246,12 @@ class HuaweiStorHyperConnector(BaseLinuxConnector):
# look for Huawei volumes to show up? # look for Huawei volumes to show up?
return None return None
@utils.trace
def get_all_available_volumes(self, connection_properties=None): def get_all_available_volumes(self, connection_properties=None):
# TODO(walter-boring): what to return here for all Huawei volumes ? # TODO(walter-boring): what to return here for all Huawei volumes ?
return [] return []
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
volume_path = None volume_path = None
try: try:
@ -2250,6 +2271,7 @@ class HuaweiStorHyperConnector(BaseLinuxConnector):
raise exception.BrickException(message=msg) raise exception.BrickException(message=msg)
return out['dev_addr'] return out['dev_addr']
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect to a volume. """Connect to a volume.
@ -2280,6 +2302,7 @@ class HuaweiStorHyperConnector(BaseLinuxConnector):
'path': volume_path} 'path': volume_path}
return device_info return device_info
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Disconnect a volume from the local host. """Disconnect a volume from the local host.
@ -2290,7 +2313,6 @@ class HuaweiStorHyperConnector(BaseLinuxConnector):
:param device_info: historical difference, but same as connection_props :param device_info: historical difference, but same as connection_props
:type device_info: dict :type device_info: dict
""" """
LOG.debug("Disconnect_volume: %s.", connection_properties)
out = self._detach_volume(connection_properties['volume_id']) out = self._detach_volume(connection_properties['volume_id'])
if not out or int(out['ret_code']) not in (self.attached_success_code, if not out or int(out['ret_code']) not in (self.attached_success_code,
self.vbs_unnormal_code, self.vbs_unnormal_code,
@ -2424,6 +2446,7 @@ class HGSTConnector(BaseLinuxConnector):
def get_search_path(self): def get_search_path(self):
return "/dev" return "/dev"
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
path = ("%(path)s/%(name)s" % path = ("%(path)s/%(name)s" %
{'path': self.get_search_path(), {'path': self.get_search_path(),
@ -2433,6 +2456,7 @@ class HGSTConnector(BaseLinuxConnector):
volume_path = path volume_path = path
return [volume_path] return [volume_path]
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Attach a Space volume to running host. """Attach a Space volume to running host.
@ -2469,6 +2493,7 @@ class HGSTConnector(BaseLinuxConnector):
return device_info return device_info
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach and flush the volume. """Detach and flush the volume.
@ -2547,6 +2572,7 @@ class ScaleIOConnector(BaseLinuxConnector):
def get_search_path(self): def get_search_path(self):
return "/dev/disk/by-id" return "/dev/disk/by-id"
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
self.get_config(connection_properties) self.get_config(connection_properties)
volume_paths = [] volume_paths = []
@ -2753,6 +2779,7 @@ class ScaleIOConnector(BaseLinuxConnector):
'path': self.volume_path} 'path': self.volume_path}
return device_info return device_info
@utils.trace
@lockutils.synchronized('scaleio', 'scaleio-') @lockutils.synchronized('scaleio', 'scaleio-')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect the volume. """Connect the volume.
@ -2882,6 +2909,7 @@ class ScaleIOConnector(BaseLinuxConnector):
return device_info return device_info
@utils.trace
@lockutils.synchronized('scaleio', 'scaleio-') @lockutils.synchronized('scaleio', 'scaleio-')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Disconnect the ScaleIO volume. """Disconnect the ScaleIO volume.
@ -2993,6 +3021,7 @@ class DISCOConnector(BaseLinuxConnector):
"""Get directory path where to get DISCO volumes.""" """Get directory path where to get DISCO volumes."""
return "/dev" return "/dev"
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
"""Get config for DISCO volume driver.""" """Get config for DISCO volume driver."""
self.get_config(connection_properties) self.get_config(connection_properties)
@ -3005,6 +3034,7 @@ class DISCOConnector(BaseLinuxConnector):
volume_paths.append(path) volume_paths.append(path)
return volume_paths return volume_paths
@utils.trace
def get_all_available_volumes(self, connection_properties=None): def get_all_available_volumes(self, connection_properties=None):
"""Return all DISCO volumes that exist in the search directory.""" """Return all DISCO volumes that exist in the search directory."""
path = self.get_search_path() path = self.get_search_path()
@ -3029,10 +3059,10 @@ class DISCOConnector(BaseLinuxConnector):
'path': disco_dev} 'path': disco_dev}
return device_info return device_info
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect the volume. Returns xml for libvirt.""" """Connect the volume. Returns xml for libvirt."""
LOG.debug("Enter in DISCO connect_volume")
device_info = self.get_config(connection_properties) device_info = self.get_config(connection_properties)
LOG.debug("Device info : %s.", device_info) LOG.debug("Device info : %s.", device_info)
disco_id = connection_properties['disco_id'] disco_id = connection_properties['disco_id']
@ -3042,6 +3072,7 @@ class DISCOConnector(BaseLinuxConnector):
self._mount_disco_volume(disco_dev, disco_id) self._mount_disco_volume(disco_dev, disco_id)
return device_info return device_info
@utils.trace
@synchronized('connect_volume') @synchronized('connect_volume')
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Detach the volume from instance.""" """Detach the volume from instance."""
@ -3181,6 +3212,7 @@ class SheepdogConnector(BaseLinuxConnector):
host, port, name) host, port, name)
return sheepdog_handle return sheepdog_handle
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
"""Connect to a volume. """Connect to a volume.
@ -3193,6 +3225,7 @@ class SheepdogConnector(BaseLinuxConnector):
sheepdog_handle = self._get_sheepdog_handle(connection_properties) sheepdog_handle = self._get_sheepdog_handle(connection_properties)
return {'path': sheepdog_handle} return {'path': sheepdog_handle}
@utils.trace
def disconnect_volume(self, connection_properties, device_info): def disconnect_volume(self, connection_properties, device_info):
"""Disconnect a volume. """Disconnect a volume.

View File

@ -19,6 +19,7 @@ from oslo_log import log as logging
from os_brick import exception from os_brick import exception
from os_brick.i18n import _, _LE from os_brick.i18n import _, _LE
from os_brick.initiator import connector from os_brick.initiator import connector
from os_brick import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -93,6 +94,7 @@ class BaseWindowsConnector(connector.InitiatorConnector):
"it can lead to data corruption.") "it can lead to data corruption.")
raise exception.BrickException(err_msg % device_paths) raise exception.BrickException(err_msg % device_paths)
@utils.trace
def extend_volume(self, connection_properties): def extend_volume(self, connection_properties):
volume_paths = self.get_volume_paths(connection_properties) volume_paths = self.get_volume_paths(connection_properties)
if not volume_paths: if not volume_paths:

View File

@ -21,6 +21,7 @@ from os_brick import exception
from os_brick.i18n import _, _LE, _LI, _LW from os_brick.i18n import _, _LE, _LI, _LW
from os_brick.initiator import connector from os_brick.initiator import connector
from os_brick.initiator.windows import base as win_conn_base from os_brick.initiator.windows import base as win_conn_base
from os_brick import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -76,6 +77,7 @@ class WindowsISCSIConnector(win_conn_base.BaseWindowsConnector,
for initiator_name in initiator_list] for initiator_name in initiator_list]
return paths return paths
@utils.trace
def connect_volume(self, connection_properties): def connect_volume(self, connection_properties):
volume_connected = False volume_connected = False
for (initiator_name, for (initiator_name,
@ -125,6 +127,7 @@ class WindowsISCSIConnector(win_conn_base.BaseWindowsConnector,
'scsi_wwn': scsi_wwn} 'scsi_wwn': scsi_wwn}
return device_info return device_info
@utils.trace
def disconnect_volume(self, connection_properties): def disconnect_volume(self, connection_properties):
# We want to refresh the cached information first. # We want to refresh the cached information first.
self._diskutils.rescan_disks() self._diskutils.rescan_disks()
@ -138,6 +141,7 @@ class WindowsISCSIConnector(win_conn_base.BaseWindowsConnector,
if not luns or luns == [target_lun]: if not luns or luns == [target_lun]:
self._iscsi_utils.logout_storage_target(target_iqn) self._iscsi_utils.logout_storage_target(target_iqn)
@utils.trace
def get_volume_paths(self, connection_properties): def get_volume_paths(self, connection_properties):
device_paths = set() device_paths = set()

View File

@ -12,6 +12,11 @@
# #
"""Utilities and helper functions.""" """Utilities and helper functions."""
import functools
import inspect
import logging as py_logging
import time
from oslo_log import log as logging from oslo_log import log as logging
import retrying import retrying
import six import six
@ -95,3 +100,59 @@ def merge_dict(dict1, dict2):
dict3 = dict1.copy() dict3 = dict1.copy()
dict3.update(dict2) dict3.update(dict2)
return dict3 return dict3
def trace(f):
"""Trace calls to the decorated function.
This decorator should always be defined as the outermost decorator so it
is defined last. This is important so it does not interfere
with other decorators.
Using this decorator on a function will cause its execution to be logged at
`DEBUG` level with arguments, return values, and exceptions.
:returns: a function decorator
"""
func_name = f.__name__
@functools.wraps(f)
def trace_logging_wrapper(*args, **kwargs):
if len(args) > 0:
maybe_self = args[0]
else:
maybe_self = kwargs.get('self', None)
if maybe_self and hasattr(maybe_self, '__module__'):
logger = logging.getLogger(maybe_self.__module__)
else:
logger = LOG
# NOTE(ameade): Don't bother going any further if DEBUG log level
# is not enabled for the logger.
if not logger.isEnabledFor(py_logging.DEBUG):
return f(*args, **kwargs)
all_args = inspect.getcallargs(f, *args, **kwargs)
logger.debug('==> %(func)s: call %(all_args)r',
{'func': func_name, 'all_args': all_args})
start_time = time.time() * 1000
try:
result = f(*args, **kwargs)
except Exception as exc:
total_time = int(round(time.time() * 1000)) - start_time
logger.debug('<== %(func)s: exception (%(time)dms) %(exc)r',
{'func': func_name,
'time': total_time,
'exc': exc})
raise
total_time = int(round(time.time() * 1000)) - start_time
logger.debug('<== %(func)s: return (%(time)dms) %(result)r',
{'func': func_name,
'time': total_time,
'result': result})
return result
return trace_logging_wrapper