Improve logging

Use proper loggers in os-faults modules.
Added NullHandler to avoid "No handler found" warnings.
Removed oslo_log from requirements.txt.

Change-Id: I5f17179078389c9415ab325549de8782ed5bb8d2
This commit is contained in:
Anton Studenov 2016-10-18 12:05:58 +03:00
parent 553086f51c
commit 7bb995c1ec
10 changed files with 75 additions and 56 deletions

View File

@ -14,6 +14,7 @@ import os
import appdirs
import jsonschema
import logging
import pbr.version
import yaml
@ -22,6 +23,11 @@ from os_faults.api import error
from os_faults.api import human
from os_faults import registry
LOG = logging.getLogger(__name__)
# Set default logging handler to avoid "No handler found" warnings.
LOG.addHandler(logging.NullHandler())
def get_version():
return pbr.version.VersionInfo('os_faults').version_string()

View File

@ -11,8 +11,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import namedtuple
import collections
import copy
import logging
import os
from ansible.executor import task_queue_manager
@ -21,7 +22,6 @@ from ansible.parsing import dataloader
from ansible.playbook import play
from ansible.plugins import callback as callback_pkg
from ansible.vars import VariableManager
from oslo_log import log as logging
from os_faults.api import error
@ -47,8 +47,8 @@ class AnsibleExecutionUnreachable(AnsibleExecutionException):
pass
AnsibleExecutionRecord = namedtuple('AnsibleExecutionRecord',
['host', 'status', 'task', 'payload'])
AnsibleExecutionRecord = collections.namedtuple(
'AnsibleExecutionRecord', ['host', 'status', 'task', 'payload'])
class MyCallback(callback_pkg.CallbackBase):
@ -111,12 +111,13 @@ def add_module_paths(paths):
MODULE_PATHS.update(dirs)
Options = namedtuple('Options',
['connection', 'password', 'module_path', 'forks',
'remote_user', 'private_key_file',
'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
'scp_extra_args', 'become', 'become_method',
'become_user', 'verbosity', 'check'])
Options = collections.namedtuple(
'Options',
['connection', 'password', 'module_path', 'forks',
'remote_user', 'private_key_file',
'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
'scp_extra_args', 'become', 'become_method',
'become_user', 'verbosity', 'check'])
class AnsibleRunner(object):

View File

@ -18,6 +18,8 @@ import random
from os_faults.api import error
from os_faults.api.util import public
LOG = logging.getLogger(__name__)
Host = collections.namedtuple('Host', ['ip', 'mac', 'fqdn'])
@ -65,7 +67,7 @@ class NodeCollection(object):
:param raise_on_error: throw exception in case of error
:return: AnsibleExecutionRecord with results of task
"""
logging.info('Run task: %s on nodes: %s', task, self)
LOG.info('Run task: %s on nodes: %s', task, self)
return self.cloud_management.execute_on_cloud(
self.get_ips(), task, raise_on_error=raise_on_error)
@ -74,7 +76,7 @@ class NodeCollection(object):
"""Reboot all nodes gracefully
"""
logging.info('Reboot nodes: %s', self)
LOG.info('Reboot nodes: %s', self)
task = {'command': 'reboot now'}
self.cloud_management.execute_on_cloud(self.get_ips(), task)
@ -90,7 +92,7 @@ class NodeCollection(object):
"""Power off all nodes abruptly
"""
logging.info('Power off nodes: %s', self)
LOG.info('Power off nodes: %s', self)
self.power_management.poweroff(self.get_macs())
@public
@ -98,7 +100,7 @@ class NodeCollection(object):
"""Power on all nodes abruptly
"""
logging.info('Power on nodes: %s', self)
LOG.info('Power on nodes: %s', self)
self.power_management.poweron(self.get_macs())
@public
@ -106,7 +108,7 @@ class NodeCollection(object):
"""Reset (cold restart) all nodes
"""
logging.info('Reset nodes: %s', self)
LOG.info('Reset nodes: %s', self)
self.power_management.reset(self.get_macs())
@public

View File

@ -19,6 +19,8 @@ from os_faults.api import error
from os_faults.api import service
from os_faults import utils
LOG = logging.getLogger(__name__)
class ServiceAsProcess(service.Service):
@ -36,7 +38,7 @@ class ServiceAsProcess(service.Service):
err = False
for result in results:
if result.status != executor.STATUS_OK:
logging.error(
LOG.error(
'Task {} failed on node {}'.format(task, result.host))
err = True
if err:
@ -59,15 +61,15 @@ class ServiceAsProcess(service.Service):
@utils.require_variables('RESTART_CMD', 'SERVICE_NAME')
def restart(self, nodes=None):
nodes = nodes if nodes is not None else self.get_nodes()
logging.info("Restart '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
LOG.info("Restart '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
self._run_task({'command': self.RESTART_CMD}, nodes)
@utils.require_variables('GREP', 'SERVICE_NAME')
def kill(self, nodes=None):
nodes = nodes if nodes is not None else self.get_nodes()
logging.info("Kill '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
LOG.info("Kill '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
cmd = {'kill': {'grep': self.GREP, 'sig': signal.SIGKILL}}
self._run_task(cmd, nodes)
@ -78,23 +80,23 @@ class ServiceAsProcess(service.Service):
cmd = {'freeze': {'grep': self.GREP, 'sec': sec}}
else:
cmd = {'kill': {'grep': self.GREP, 'sig': signal.SIGSTOP}}
logging.info("Freeze '%s' service %son nodes: %s", self.SERVICE_NAME,
('for %s sec ' % sec) if sec else '', nodes.get_ips())
LOG.info("Freeze '%s' service %son nodes: %s", self.SERVICE_NAME,
('for %s sec ' % sec) if sec else '', nodes.get_ips())
self._run_task(cmd, nodes)
@utils.require_variables('GREP', 'SERVICE_NAME')
def unfreeze(self, nodes=None):
nodes = nodes if nodes is not None else self.get_nodes()
logging.info("Unfreeze '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
LOG.info("Unfreeze '%s' service on nodes: %s", self.SERVICE_NAME,
nodes.get_ips())
cmd = {'kill': {'grep': self.GREP, 'sig': signal.SIGCONT}}
self._run_task(cmd, nodes)
@utils.require_variables('PORT', 'SERVICE_NAME')
def plug(self, nodes=None):
nodes = nodes if nodes is not None else self.get_nodes()
logging.info("Open port %d for '%s' service on nodes: %s",
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
LOG.info("Open port %d for '%s' service on nodes: %s",
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
self._run_task({'iptables': {'protocol': self.PORT[0],
'port': self.PORT[1],
'action': 'unblock',
@ -103,8 +105,8 @@ class ServiceAsProcess(service.Service):
@utils.require_variables('PORT', 'SERVICE_NAME')
def unplug(self, nodes=None):
nodes = nodes if nodes is not None else self.get_nodes()
logging.info("Close port %d for '%s' service on nodes: %s",
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
LOG.info("Close port %d for '%s' service on nodes: %s",
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
self._run_task({'iptables': {'protocol': self.PORT[0],
'port': self.PORT[1],
'action': 'block',

View File

@ -18,6 +18,8 @@ from os_faults.api import cloud_management
from os_faults.api import node_collection
from os_faults.common import service
LOG = logging.getLogger(__name__)
class DevStackNode(node_collection.NodeCollection):
@ -73,8 +75,8 @@ class DevStackManagement(cloud_management.CloudManagement):
task = {'command': 'hostname'}
hostname = self.execute_on_cloud(
[self.address], task)[0].payload['stdout']
logging.debug('DevStack hostname: %s', hostname)
logging.info('Connected to cloud successfully')
LOG.debug('DevStack hostname: %s', hostname)
LOG.info('Connected to cloud successfully')
def execute_on_cloud(self, hosts, task, raise_on_error=True):
"""Execute task on specified hosts within the cloud.

View File

@ -20,11 +20,13 @@ from os_faults.api import error
from os_faults.api import node_collection
from os_faults.common import service
LOG = logging.getLogger(__name__)
class FuelNodeCollection(node_collection.NodeCollection):
def connect(self, network_name):
logging.info("Connect network '%s' on nodes: %s", network_name, self)
LOG.info("Connect network '%s' on nodes: %s", network_name, self)
task = {'fuel_network_mgmt': {
'network_name': network_name,
'operation': 'up',
@ -32,8 +34,8 @@ class FuelNodeCollection(node_collection.NodeCollection):
self.cloud_management.execute_on_cloud(self.get_ips(), task)
def disconnect(self, network_name):
logging.info("Disconnect network '%s' on nodes: %s",
network_name, self)
LOG.info("Disconnect network '%s' on nodes: %s",
network_name, self)
task = {'fuel_network_mgmt': {
'network_name': network_name,
'operation': 'down',
@ -170,15 +172,15 @@ class FuelManagement(cloud_management.CloudManagement):
def verify(self):
"""Verify connection to the cloud."""
hosts = self._get_cloud_hosts()
logging.debug('Cloud nodes: %s', hosts)
LOG.debug('Cloud nodes: %s', hosts)
task = {'command': 'hostname'}
host_addrs = [host.ip for host in hosts]
task_result = self.execute_on_cloud(host_addrs, task)
logging.debug('Hostnames of cloud nodes: %s',
[r.payload['stdout'] for r in task_result])
LOG.debug('Hostnames of cloud nodes: %s',
[r.payload['stdout'] for r in task_result])
logging.info('Connected to cloud successfully!')
LOG.info('Connected to cloud successfully!')
def _get_cloud_hosts(self):
if not self.cached_cloud_hosts:
@ -225,7 +227,7 @@ class FuelManagement(cloud_management.CloudManagement):
hosts = self._get_cloud_hosts()
if fqdns:
logging.debug('Trying to find nodes with FQDNs: %s', fqdns)
LOG.debug('Trying to find nodes with FQDNs: %s', fqdns)
hosts = list()
for fqdn in fqdns:
if fqdn in self.fqdn_to_hosts:
@ -233,7 +235,7 @@ class FuelManagement(cloud_management.CloudManagement):
else:
raise error.NodeCollectionError(
'Node with FQDN \'%s\' not found!' % fqdn)
logging.debug('The following nodes were found: %s', hosts)
LOG.debug('The following nodes were found: %s', hosts)
return self.NODE_CLS(cloud_management=self,
power_management=self.power_management,

View File

@ -20,6 +20,8 @@ from os_faults.api import error
from os_faults.api import power_management
from os_faults import utils
LOG = logging.getLogger(__name__)
class IPMIDriver(power_management.PowerManagement):
NAME = 'ipmi'
@ -67,10 +69,10 @@ class IPMIDriver(power_management.PowerManagement):
except pyghmi_exception.IpmiException:
msg = 'IPMI cmd {!r} failed on bmc {!r}, Node({})'.format(
cmd, bmc['address'], mac_address)
logging.error(msg)
LOG.error(msg, exc_info=True)
raise
logging.debug('IPMI response: {}'.format(ret))
LOG.debug('IPMI response: {}'.format(ret))
if ret.get('powerstate') != expected_state or 'error' in ret:
msg = ('Failed to change power state to {!r} on bmc {!r}, '
'Node({})'.format(expected_state,
@ -79,23 +81,23 @@ class IPMIDriver(power_management.PowerManagement):
raise error.PowerManagementError(msg)
def _poweroff(self, mac_address):
logging.info('Power off Node with MAC address: %s', mac_address)
LOG.debug('Power off Node with MAC address: %s', mac_address)
self._run_set_power_cmd(
mac_address, cmd='off', expected_state='off')
logging.info('Node(%s) was powered off' % mac_address)
LOG.info('Node powered off: %s', mac_address)
def _poweron(self, mac_address):
logging.info('Power on Node with MAC address: %s', mac_address)
LOG.debug('Power on Node with MAC address: %s', mac_address)
self._run_set_power_cmd(
mac_address, cmd='on', expected_state='on')
logging.info('Node(%s) was powered on' % mac_address)
LOG.info('Node powered on: %s', mac_address)
def _reset(self, mac_address):
logging.info('Reset Node with MAC address: %s', mac_address)
LOG.debug('Reset Node with MAC address: %s', mac_address)
# boot -- If system is off, then 'on', else 'reset'
self._run_set_power_cmd(mac_address, cmd='boot')
# NOTE(astudenov): This command does not wait for node to boot
logging.info('Node(%s) was reset' % mac_address)
LOG.info('Node reset: %s', mac_address)
def poweroff(self, mac_addresses_list):
utils.run(self._poweroff, mac_addresses_list)

View File

@ -17,6 +17,8 @@ from os_faults.api import error
from os_faults.api import power_management
from os_faults import utils
LOG = logging.getLogger(__name__)
class LibvirtDriver(power_management.PowerManagement):
NAME = 'libvirt'
@ -60,22 +62,22 @@ class LibvirtDriver(power_management.PowerManagement):
'Domain with MAC address %s not found!' % mac_address)
def _poweroff(self, mac_address):
logging.info('Power off domain with MAC address: %s', mac_address)
LOG.debug('Power off domain with MAC address: %s', mac_address)
domain = self._find_domain_by_mac_address(mac_address)
domain.destroy()
logging.info('Domain(%s) was powered off' % mac_address)
LOG.info('Domain powered off: %s', mac_address)
def _poweron(self, mac_address):
logging.info('Power on domain with MAC address: %s', mac_address)
LOG.debug('Power on domain with MAC address: %s', mac_address)
domain = self._find_domain_by_mac_address(mac_address)
domain.create()
logging.info('Domain(%s) was powered on' % mac_address)
LOG.info('Domain powered on: %s', mac_address)
def _reset(self, mac_address):
logging.info('Reset domain with MAC address: %s', mac_address)
LOG.debug('Reset domain with MAC address: %s', mac_address)
domain = self._find_domain_by_mac_address(mac_address)
domain.reset()
logging.info('Domain(%s) was reset' % mac_address)
LOG.info('Domain reset: %s', mac_address)
def poweroff(self, mac_addresses_list):
utils.run(self._poweroff, mac_addresses_list)

View File

@ -14,10 +14,11 @@
import functools
import logging
import threading
import traceback
from os_faults.api import error
LOG = logging.getLogger(__name__)
def run(target, mac_addresses_list):
tw = ThreadsWrapper(target)
@ -41,7 +42,7 @@ class ThreadsWrapper(object):
try:
self.target(**kwargs)
except Exception as exc:
logging.error(traceback.format_exc())
LOG.error('Target raised exception: %s', exc)
self.errors.append(exc)
def start_thread(self, **kwargs):

View File

@ -9,7 +9,6 @@ appdirs>=1.3.0 # MIT License
jsonschema>=2.0.0,!=2.5.0,<3.0.0 # MIT
iso8601>=0.1.9
oslo.i18n>=1.5.0 # Apache-2.0
oslo.log>=1.12.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils!=2.6.0,>=2.4.0 # Apache-2.0
pyghmi>=1.0.3 # Apache-2.0