def test_create_metricdata(self): r = MetricData(name='name', messages={}) self.assertEqual('swiftlm.name', r.name) self.assertEqual('', r.message) self.assertEqual(None, r.value) self.assertIn('hostname', r.dimensions)
def test_dict_behaviour(self): r = MetricData(name='name', messages={}) r['test'] = 1000 # dimension values must be strings so we check they are converted # properly self.assertEqual('1000', r['test']) del r['test'] self.assertNotIn('test', r)
def test_child_msgkeys(self): r = MetricData(name='name', messages={ 'ok': 'test message', 'test': 'test with meta {test_value} and {test_value2}', }) c = r.child(dimensions={'test_value': '123'}, msgkeys={'test_value2': '456'}) c.message = 'test' self.assertEqual('test with meta 123 and 456', str(c))
def test_response_child(self): r = MetricData(name='name', messages={'a': 'b'}) r['test'] = 'test' c = r.child(dimensions={'test2': 'test2'}) self.assertIn('test', c) self.assertIn('test2', c) self.assertDictEqual({'a': 'b'}, c.messages) self.assertEqual('swiftlm.name', c.name) c = r.child() self.assertIn('test', c) self.assertNotIn('test2', c)
def test_message(self): r = MetricData(name='name', messages={ 'ok': 'test message', 'test': 'test with meta {test_value}', }) # Test automatic message assignment when a the Status Enum is used # as the value self.assertEqual('', r.message) r.value = Severity.ok self.assertEqual('test message', r.message) # Test that an error is raised when trying to use a message without # providing all of the dimension values first. with self.assertRaisesRegexp(ValueError, 'requires a dimension value'): r.message = 'test' r['test_value'] = '123' r.message = 'test' self.assertEqual('test with meta 123', str(r))
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import json from swiftlm.utils.metricdata import MetricData, timestamp, CheckFailure from swiftlm.utils.values import Severity, ServerType RECON_PATH = '/var/cache/swift/' TIMEOUT = 2 BASE_RESULT = MetricData( name=__name__, messages={} ) def _recon_check(st): """ Parses the blah.recon file and returns the last replication. :param st: ServerType, Used to determine the metric names and recon file name. :param replication_field_name: string, name of the field in the json file that hold the last replication data. """ results = [] if not st.is_instance: return results
def test_get_controller_info(self): expected_base = MetricData( name=hpssacli.__name__ + '.smart_array', messages=hpssacli.BASE_RESULT.messages, dimensions={ 'serial': 'PACCR0M9VZ41S4Q', 'model': 'Smart Array P410', 'slot': '1', 'component': 'controller', }) # List of tuples. # t[0] = Data set that hpssacli should return # t[1] = The failed component in the test data tests = [ (SMART_ARRAY_DATA, []), (SMART_ARRAY_CACHE_FAIL, ['cache']), (SMART_ARRAY_BATTERY_FAIL, ['battery/capacitor']), (SMART_ARRAY_CONTROLLER_FAIL, ['controller']), (SMART_ARRAY_BATTERY_COUNT_FAIL, ['battery/capacitor count']), ] for test_data, failures in tests: mock_command = mock.Mock() mock_command.return_value = CommandResult(0, test_data) with mock.patch('swiftlm.hp_hardware.hpssacli.run_cmd', mock_command): actual, actual_slots = hpssacli.get_smart_array_info() self.assertIsInstance(actual, list) self.assertEqual(len(actual), 5) expected_firmware = expected_base.child('firmware') expected_firmware.value = 6.60 actual = self.check_metrics(expected_firmware, actual) bcc = 'battery/capacitor count' if bcc in failures: expected_battery_count = expected_base.child(dimensions={ 'sub_component': bcc, 'count': '0'}) expected_battery_count.value = Severity.fail expected_battery_count.message = 'no_battery' else: expected_battery_count = expected_base.child(dimensions={ 'sub_component': bcc, 'count': '1'}) expected_battery_count.value = Severity.ok actual = self.check_metrics(expected_battery_count, actual) for submetric in ('battery/capacitor', 'controller', 'cache'): if submetric in failures: expected_status = expected_base.child(dimensions={ 'sub_component': submetric, 'status': 'FAIL'}) expected_status.value = Severity.fail expected_status.message = 'controller_status' else: expected_status = expected_base.child(dimensions={ 'sub_component': submetric, 'status': 'OK'}) expected_status.value = Severity.ok actual = self.check_metrics(expected_status, actual) self.assertFalse(actual, 'Got more metrics than expected')
def test_equality_behaviour(self): m_a = MetricData('name', self.messages, self.dimensions) m_b = MetricData('name', self.messages, self.dimensions) self.assertEqual(m_a, m_b) m_a = MetricData('name', self.messages, self.dimensions) m_b = MetricData('not-name', self.messages, self.dimensions) self.assertNotEqual(m_a, m_b) m_a = MetricData('name', {'a': 1}, self.dimensions) m_b = MetricData('name', {'b': 2}, self.dimensions) self.assertEqual( m_a, m_b, 'Message dictionaries should not ' 'affect equality of MetricData instances') m_a = MetricData('name', self.messages, self.dimensions) m_b = MetricData('name', self.messages, {}) self.assertNotEqual(m_a, m_b) m_a = MetricData('name', self.messages, self.dimensions) m_b = MetricData('name', self.messages, self.dimensions) m_a.message = 'ok' m_b.message = 'fail' self.assertNotEqual(m_a, m_b) m_a = MetricData('name', self.messages, self.dimensions) m_b = MetricData('name', self.messages, self.dimensions) m_a.value = 1 m_b.value = 2 self.assertNotEqual(m_a, m_b)
import ast import subprocess import os import ConfigParser from swiftlm.utils.metricdata import MetricData from swiftlm.utils.values import Severity ERRORS_PATTERN = 'drive-audit: Errors found:' DEVICES_PATTERN = 'drive-audit: Devices found:' DRIVE_AUDIT_CONF = '/etc/swift/drive-audit.conf' BASE_RESULT = MetricData( name=__name__, messages={ 'ok': 'No errors found on device mounted at: {mount_point}', 'warn': 'No devices found', 'fail': 'Errors found on device mounted at: {mount_point}', 'unknown': 'Unrecoverable error: {error}' }) def get_devices(output): """ Returns a list of devices as a dict of mount_point and device """ # TODO use drive_model.yml to determine drives to check lines = [s.strip() for s in output.split('\n') if s] for line in lines: if DEVICES_PATTERN in line: devs = line.split(DEVICES_PATTERN)[1].strip() devices = ast.literal_eval(devs)
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from swiftlm.utils.utility import server_type, get_all_proc_and_cmdlines,\ get_network_interface_conf,\ get_rsync_target_conf from swiftlm.utils.metricdata import MetricData, get_base_dimensions from swiftlm.utils.values import Severity BASE_RESULT = MetricData(name=__name__, messages={ 'fail': '{component} is not running', 'ok': '{component} is running', 'unknown': 'no swift services running', }) SERVICES = [ "account-auditor", "account-reaper", "account-replicator", "account-server", "container-replicator", "container-server", "container-updater", "container-auditor", "container-reconciler", "container-sync", "object-replicator", "object-server", "object-updater", "object-auditor", "object-reconstructor", "proxy-server" ] def services_to_check(): # Filter SERVICES down to what should be running on the node. # server_type returns a dict of {'object': bool, etc}
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import re from swiftlm.utils.metricdata import MetricData, CheckFailure from swiftlm.utils.values import Severity from swiftlm.utils.utility import run_cmd BASE_RESULT = MetricData( name='load.host', messages={} ) def _get_proc_file(path): return open(path, mode='r').read() def get_load_average(): r = BASE_RESULT.child(name='val.five') load_avg_data = _get_proc_file('/proc/loadavg') r.value = float(load_avg_data.split()[1]) return [r] def main():
from swiftlm.utils.utility import (get_ring_hosts, server_type, UtilityExeception) from swiftlm.utils.metricdata import MetricData, get_base_dimensions from swiftlm.utils.values import Severity, ServerType from swiftlm.utils.utility import run_cmd # Connectivity needs to report out target hostname and observer hostname # rather than the normal hostname dimension _base_dimensions = dict(get_base_dimensions()) _base_dimensions['observer_host'] = _base_dimensions['hostname'] del _base_dimensions['hostname'] BASE_RESULT = MetricData(name=__name__, messages={ 'ok': '{hostname}:{target_port} ok', 'warn': 'No hosts to check', 'fail': '{hostname}:{target_port} {fail_message}', 'unknown': 'Unrecoverable error: {error}', }, dimensions=_base_dimensions) MAX_THREAD_LIMIT = 10 SWIFT_PROXY_PATH = '/opt/stack/service/swift-proxy-server/etc' class HostPort(namedtuple('HostPort', ['host', 'port'])): @classmethod def from_string(cls, s): """ Create a HostPort instance from a string """ # Supports: # http://host.name, http://host.name:port # host.name, host.name:port
import configparser except ImportError: import ConfigParser as configparser from swiftlm.utils.metricdata import MetricData from swiftlm.utils.values import Severity from swiftlm.utils.utility import run_cmd from swiftlm import CONFIG_FILE LOCK_FILE_COMMAND = '/usr/bin/flock -w 10 /var/lock/hpssacli-swiftlm.lock ' BASE_RESULT = MetricData( name=__name__, messages={ 'no_battery': 'No cache battery', 'unknown': 'hpssacli command failed: {error}', 'controller_status': '{sub_component} status is {status}', 'physical_drive': 'Drive {serial}: {box}:{bay} has status: {status}', 'l_drive': 'Logical Drive {logical_drive} has status: {status}', 'l_cache': 'Logical Drive {logical_drive} has cache status: {caching}', 'ok': 'OK', 'fail': 'FAIL', }) def is_cont_heading(line): """ Returns "True" if the line is the controller heading example: Smart Array P410 in Slot 1 """ if ("Slot" in line) and (not line[0].isspace()): return True else:
try: import commands except ImportError: import subprocess as commands import string from swiftlm.utils.utility import get_swift_bind_ips, UtilityExeception from swiftlm.utils.utility import ip_to_interface from swiftlm.utils.metricdata import MetricData from swiftlm.utils.values import Severity BASE_RESULT = MetricData( name=__name__, messages={ 'fail': 'Could not discover a valid interface name' } ) def str_to_num(val): # if val is a number then convert it to a number literal try: return int(val) except ValueError: try: return float(val) except: return val
def is_valid_xfs(d, r): rc = run_cmd('xfs_info %s' % d.mount) if rc.exitcode == 0: return True else: return False BASE_RESULT = MetricData( name=__name__, messages={ is_mounted.__name__: '{device} not mounted at {mount}', is_mounted_775.__name__: ('{device} mounted at {mount} has permissions' ' {permissions} not 755'), is_ug_swift.__name__: ('{device} mounted at {mount} is not owned by' ' swift, has user: {user}, group: {group}'), is_valid_label.__name__: ('{device} mounted at {mount} has invalid ' 'label {label}'), is_xfs.__name__: '{device} mounted at {mount} is not XFS', is_valid_xfs.__name__: '{device} mounted at {mount} is corrupt', 'ok': '{device} mounted at {mount} ok', 'no_devices': 'No devices found' } ) def check_mounts(): results = [] checks = ( is_mounted, is_mounted_775, is_ug_swift,
except ImportError: import ConfigParser as configparser from collections import OrderedDict from swiftlm.utils.metricdata import MetricData from swiftlm.utils.values import Severity from swiftlm.utils.utility import run_cmd from swiftlm import CONFIG_FILE LOCK_FILE_COMMAND = '/usr/bin/flock -w 10 /var/lock/hpssacli-swiftlm.lock ' BASE_RESULT = MetricData( name=__name__, messages={ 'no_battery': 'No cache battery', 'unknown': 'hpssacli command failed', 'controller_status': '{sub_component} status is {status}', 'in_hba_mode': 'Controller is in HBA mode; performance will be poor', 'physical_drive': 'Drive {serial_number}: ' '{box}:{bay} has status: {status}', 'l_drive': 'Logical Drive {logical_drive} has status: {status}', 'l_cache': 'Logical Drive {logical_drive} has cache status: {caching}', 'ok': 'OK', 'fail': 'FAIL', }) # This is all the data we are looking for in the hpssacli output so we # will _only_ gather whatever values are in this list METRIC_KEYS = [ 'array', 'physicaldrive', 'logical_drive', 'caching', 'serial_number', 'slot', 'firmware_version', 'controller_mode', 'battery_capacitor_presence', 'battery_capacitor_status', 'controller_status', 'cache_status', 'box', 'bay', 'status', 'ld acceleration method'
import pwd from swiftlm.utils.utility import server_type from swiftlm.utils.metricdata import MetricData from swiftlm.utils.values import Severity, ServerType SWIFT_DIR = '/etc/swift' CONF_DIR = '/etc' NODE_DIR = '/srv/node' ZERO_BYTE_EXCLUDE = frozenset(['reload-trigger', 'swauth_to_tenant_map.gz']) SWIFT_OWNED_EXCLUDE = frozenset(['lost+found']) BASE_RESULT = MetricData(name=__name__, messages={ 'empty': 'Path: {path} should not be empty', 'ownership': 'Path: {path} is not owned by swift', 'missing': 'Path: {path} is missing', }) def add_result(results, path, reason): c = BASE_RESULT.child(dimensions={'path': path}) c.value = Severity.fail c.message = reason results.add(c) def _is_swift_owned(results, p): # True = good, False = bad owner = pwd.getpwuid(os.stat(p).st_uid).pw_name if owner == 'swift':
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import re from swiftlm.utils.metricdata import MetricData, CheckFailure from swiftlm.utils.values import Severity from swiftlm.utils.utility import run_cmd BASE_RESULT = MetricData(name=__name__, messages={ 'ok': 'OK', 'fail': 'ntpd not running: {error}', }) def check_status(): cmd_result = run_cmd('systemctl status ntp') r = BASE_RESULT.child() if cmd_result.exitcode != 0: r['error'] = cmd_result.output r.value = Severity.fail else: r.value = Severity.ok return [r]
from collections import namedtuple from swiftlm.utils.utility import (get_ring_hosts, server_type, UtilityExeception) from swiftlm.utils.metricdata import MetricData, get_base_dimensions from swiftlm.utils.values import Severity, ServerType from swiftlm.utils.utility import run_cmd # Connectivity needs to report out target hostname and observer hostname # rather than the normal hostname dimension _base_dimensions = dict(get_base_dimensions()) _base_dimensions['observer_host'] = socket.gethostname() BASE_RESULT = MetricData(name=__name__, messages={ 'ok': '{url} ok', 'fail': '{url} {fail_message}' }, dimensions=_base_dimensions) MAX_THREAD_LIMIT = 10 CONNECT_TIMEOUT = 2.0 JOIN_WAIT = 10.0 SWIFT_PROXY_PATH = '/opt/stack/service/swift-proxy-server/etc' MEMCACHE_CONF_PATH = '/etc/swift' SWIFTLM_SCAN_PATH = '/etc/swiftlm' class HostPort(namedtuple('HostPort', ['host', 'port'])): @classmethod def from_string(cls, s): """ Create a HostPort instance from a string """