MSV FM

[email protected]: ~ $
Path : /usr/lib/fm-agent/plugins/
File Upload :
Current < : //usr/lib/fm-agent/plugins/disk.py

import agent_util
import sys
import os
import platform
from agent_util import float

import json

NETWORK_FS = ['ncpfs', 'nfs', 'ntfs', 'smb', 'vfat', 'smb2', 'cifs', 'nfs4']

# Timeout after 10 seconds, so we don't get hung on remote filesystems
TIMEOUT_LIMIT = 10

def get_findmnt_cmd(extra_args=""):
    timeout = ""
    if agent_util.which("timeout"):
        timeout = "timeout %s " % TIMEOUT_LIMIT
    return "%sfindmnt --fstab --df --bytes --raw --evaluate --all %s" % (timeout, extra_args)

def get_df_cmd(extra_arg=""):
    timeout = ""
    if agent_util.which("timeout"):
        timeout = "timeout %s " % TIMEOUT_LIMIT

    df_cmd = 'df -PkT'
    if "vmware" in sys.platform:
        df_cmd = 'df -kT'
    elif 'sunos' in sys.platform:
        df_cmd = 'df -kt'
    elif "darwin" in sys.platform or "aix" in sys.platform or 'freebsd' in sys.platform:
        df_cmd = "df -Pk"
    
    return "%s%s %s" % (timeout, df_cmd, extra_arg)


def get_idf_cmd(extra_arg=""):
    timeout = ""
    if agent_util.which("timeout"):
        timeout = "timeout %s " % TIMEOUT_LIMIT

    idf_cmd = 'df -iPT'
    if 'sunos' in sys.platform or "vmware" in sys.platform:
        idf_cmd = 'df -iT'
    elif 'aix' == sys.platform:
        idf_cmd = 'df -ik'
    elif 'darwin' == sys.platform or 'freebsd' in sys.platform:
        idf_cmd = 'df -Pik'
    
    return "%s%s %s" % (timeout, idf_cmd, extra_arg)

class DiskDFParser:
    def __init__(self, log, config):
        self.log = log
        self.device_ignore_list = ("tmpfs", "devtmpfs", "none", "proc", "swap", "devices", "cgroup", "/dev/loop")
        self.mountpoint_excludes = ()

        cfg_device_list = config.get("device_ignore_list", None)
        if cfg_device_list is not None:
            self.device_ignore_list = self.parse_ignore_list(cfg_device_list)
        
        if "aix" in sys.platform or "sunos" in sys.platform:
            self.device_ignore_list = self.device_ignore_list + ("/proc", "/swap", "/ahafs")
        
        if 'darwin' == sys.platform:
            self.mountpoint_excludes = ('/Library/Developer/CoreSimulator/Volumes', )
            mpe = config.get('mountpoint_excludes', None)
            if mpe is not None:
                self.mountpoint_excludes = self.parse_ignore_list(mpe)

    def __str__(self):
        return "Disk df parser"
    
    def parse_ignore_list(self, device_list):
        try:
            dl_type = type(device_list)
            if type(tuple) == dl_type:
                return device_list
            if type("") == dl_type:
                if '(' in device_list and ')' in device_list:
                    device_list_items = device_list.replace('(', '').replace(')', '').split(',')
                    items = [d.strip().strip('"') for d in device_list_items]
                    return tuple(items)
        except:
            self.log.error('Error parsing device list {}'.format(device_list))
        
        return ()
        
    def parse_df_output(self, output):
        outlines = output.splitlines()

        headers = self.build_header_data(outlines[0])
        df_table = {}
        for df_line in outlines[1:]:
            df_line = df_line.strip().split()
            mount_point = None
            mount_point_idx = headers.get('mounted on', None)
            if mount_point_idx:
                mount_point = ' '.join(df_line[mount_point_idx:])
            if not mount_point:
                self.log.warning('No mount point in {}'.format(df_line))
                continue
            df_table[mount_point] = {}
            for entry in headers.keys():
                val = df_line[headers[entry]]
                if 'mounted on' == entry:
                    val = mount_point
                
                df_table[mount_point][entry] = val
        
        return df_table

    def build_header_data(self, header_line):
        hdr_idx = 0
        headers = {}
        for hdr in header_line.split():
            #
            # For lines that end with 'Mounted on' - skip the last split
            #
            hdr = hdr.lower()
            
            if 'on' == hdr:
                continue
            if 'mounted' == hdr:
                hdr = 'mounted on'
            if hdr in ['iuse%', '%iused']:
                hdr = 'iuse_pct'
            elif hdr in ['available', 'avail']:
                hdr = 'available'
            headers[hdr] = hdr_idx
            hdr_idx += 1

        return headers

    
    def get_device_data(self, output, key_map, custom_network_fs):
        df_table = self.parse_df_output(output)
        devices = []
        max_disk = {}
        for mountpoint_table in df_table.values():
            try:
                device_key = key_map.get('device')
                device = mountpoint_table[device_key]
                fs_type_key = key_map.get('fs_type')
                filesystem = mountpoint_table.get(fs_type_key, '')
                skip_device = False
                for test_device in self.device_ignore_list:
                    if device.startswith(test_device) or filesystem.startswith(test_device):
                        self.log.debug("Skipping metadata for device %s" % device)
                        skip_device = True
                        break
                if skip_device:
                    continue

                mounted_key = key_map.get('mountpoint')
                mounted = mountpoint_table.get(mounted_key, None)
                if not mounted:
                    continue
                
                skip_mp = False
                for mp in self.mountpoint_excludes:
                    if mounted.startswith(mp):
                        self.log.debug('Skipping mountpoint {}'.format(mounted))
                        skip_mp = True
                        break
                if skip_mp:
                    continue

                desc = "%s mounted at %s" % (device, mounted)
                devices.append(
                    {
                        "device": device,
                        "mountpoint": mounted,
                        "filesystem": filesystem,
                        "resource": desc,
                        "is_network": filesystem in NETWORK_FS or filesystem in custom_network_fs
                    }
                )
                available_key = key_map.get('available')
                available = mountpoint_table.get(available_key, None)
                if available is not None:
                    max_disk[desc] = available
            except:
                self.log.error("Unable to parse df output")
                continue

        return devices, max_disk

class DiskUsagePlugin(agent_util.Plugin):
    textkey = "disk"
    label = "Disk"
    darwin_fstype_excludes = 'nullfs,nodev,devfs,autofs'

    # adding min for disk usage
    min_capacity = 0

    if "AIX" in os.uname():
        sys.platform = "aix"

    @classmethod
    def dump_disk_output(self, config, cmd, raw_output):
        if config.get("debug", False):
            self.log.debug('#####################################################')
            self.log.debug("Disk command '%s' output :" % cmd)
            self.log.debug(raw_output)
            self.log.debug('#####################################################')

    @classmethod
    def get_metadata(self, config):
        status = agent_util.SUPPORTED
        msg = None

        if not agent_util.which("df", exc=False):
            self.log.warning("df binary not found")
            status = agent_util.UNSUPPORTED
            
        if agent_util.SUPPORTED != status:
            return {}

        # See if there are custom DF flags specified in the config file
        extra_df_arg = self.gather_extra_df_arg(config=config)

        # See if the config file specifies to use findmnt to identify expected disks
        use_findmnt = config.get("use_findmnt") and agent_util.which("findmnt")
        extra_findmnt_arg = config.get("extra_findmnt_arg", "")

        custom_network_fs = config.get('network_fs', [])
        if custom_network_fs:
            custom_network_fs = custom_network_fs.split(',')
        
        table_keys = {
            'device' : 'filesystem',
            'fs_type' : 'type',
            'mountpoint': 'mounted on',
            'available' : 'available',
        }

        if use_findmnt:
            table_keys = {
                'device' : 'source',
                'fs_type' : 'fstype',
                'mountpoint' : 'target',
                'available' : 'avail',
            }
            block_query = get_findmnt_cmd(extra_findmnt_arg)
            inode_query = block_query
        else:
            block_query = get_df_cmd(extra_df_arg)
            inode_query = get_idf_cmd(extra_df_arg)

       

        parser = DiskDFParser(self.log, config)
        ret_code, block_result = agent_util.execute_command(block_query, cache_timeout=agent_util.DEFAULT_CACHE_TIMEOUT)
        if 0 != ret_code:
            devices = []
            max_disk = {}
            msg = 'Command exit status {}'.format(ret_code)
            self.log.error('{} exit status {}'.format(block_query, ret_code))
            status = agent_util.UNSUPPORTED
        else:
            self.dump_disk_output(config, block_query, block_result)
            devices, max_disk = parser.get_device_data(
                block_result, table_keys, custom_network_fs 
            )

        inode_status = agent_util.SUPPORTED
        idevices = []
        imax_disk = {}
        inode_status_msg = None
        if 'sunos' in sys.platform or 'hp-ux' in sys.platform or 'aix' in sys.platform:
            inode_status = agent_util.UNSUPPORTED
            inode_status_msg = 'Unsupported on this platform'
        else:
            ret_code, inode_result = agent_util.execute_command(inode_query, cache_timeout=agent_util.DEFAULT_CACHE_TIMEOUT)
            if 0 != ret_code:
                inode_status_msg = 'Command exit status {}'.format(ret_code)
                self.log.error('{} exit status {}'.format(inode_query, ret_code))
                inode_status = agent_util.UNSUPPORTED
            else:
                if not use_findmnt:
                    table_keys['available'] = 'ifree'
                self.dump_disk_output(config, inode_query, inode_result)
                idevices, imax_disk = parser.get_device_data(
                    inode_result, table_keys, custom_network_fs 
                )
        
        options_schema = {
            'device': 'string',
            'mountpoint': 'string',
            'filesystem': 'string',
            'resource': 'string',
            'is_network': 'boolean'
        }
        data = {
            "usage.percent_used": {
                "label": "Percentage of disk used",
                "options": devices,
                "options_schema": options_schema,
                "status": status,
                "error_message": msg,
                "unit": "percent",
                "min_value": 0,
                "max_value": 100,
            },
            "usage.kb_available": {
                "label": "Disk space available",
                "options": devices,
                "options_schema": options_schema,
                "status": status,
                "error_message": msg,
                "unit": "kB",
                "min_value": 0,
                "max_value": max_disk,
            },
            "filesystem.mounted": {
                "label": "Filesystem mounted",
                "options": devices,
                "options_schema": options_schema,
                "status": status,
                "error_message": msg,
            },
            "inode.percent_used": {
                "label": "Inodes percent used",
                "options": idevices,
                "options_schema": options_schema,
                "status": inode_status,
                "error_message": inode_status_msg,
                "unit": "percent",
                "min_value": 0,
                "max_value": 100,
            },
            "inode.used": {
                "label": "Inode used",
                "options": idevices,
                "options_schema": options_schema,
                "status": inode_status,
                "error_message": inode_status_msg,
                "unit": "Inodes",
                "min_value": 0,
                "max_value": imax_disk,
            },
            "inode.available": {
                "label": "Inodes Available",
                "options": idevices,
                "options_schema": options_schema,
                "status": inode_status,
                "error_message": inode_status_msg,
                "unit": "Inodes",
                "min_value": 0,
                "max_value": imax_disk,
            },
        }

        # no inodes for vmware
        to_del = []
        if 'vmware' in sys.platform:
            for k in data.keys():
                if 'inode' in k:
                    to_del.append(k)

        for d in to_del:
            del data[d]

        return data
    
    def collect_vmware(self, textkey, mounted):
        ret, output = agent_util.execute_command("stat -f %s" % mounted, cache_timeout=agent_util.DEFAULT_CACHE_TIMEOUT)
        # make sure it's mounted first
        if ret != 0 and textkey != 'filesystem.mounted':
            self.log.error("Unable to find disk %s, is it mounted?!" % mounted)
            self.log.error(output)
            return None
        elif ret != 0 and textkey == 'filesystem.mounted':
            return 0

        block_size = 0
        metrics = {}
        for line in output.split('\n'):
            l = str(line).strip().lower()
            if l.startswith('file:') or l.startswith('id:'):
                continue
            elif l.startswith('block size:'):
                block_size = l.split()[-1]
            if l.startswith('blocks:'):
                try:
                    btext, ttext, total_size, ftext, free_size, atext, avail_size = l.split()
                except:
                    self.log.error("Unable to parse disk output!")
                    self.log.error(output)
                    return None
                metrics['usage.percent_used'] = 100. - ((float(free_size) / float(total_size)) * 100)
                metrics['usage.kb_available'] = float(free_size) * float(block_size)
        return metrics[str(textkey)]
    
    @classmethod
    def gather_extra_df_arg(self, config):
        extra_df_arg = config.get("extra_df_arg", "")
        if 'darwin' in sys.platform:
            configKey = 'ignore_fstypes'
            ignores = self.darwin_fstype_excludes
            if config.get(configKey, None):
                ignores = '{},{}'.format(ignores, config.get(configKey))
            extra_df_arg ='{} -T no{}'.format(extra_df_arg, ignores)

        return extra_df_arg
    
    def check(self, textkey, dev_mount, config):
        dev_mount = dev_mount.split()
        mounted = ' '.join(dev_mount[3:])

        extra_df_arg = self.gather_extra_df_arg(config)

        if "vmware" in sys.platform:
            return self.collect_vmware(textkey, mounted)

        is_inode_query = False
        if textkey.startswith("i"):
            df_cmd = get_idf_cmd(extra_df_arg)
            is_inode_query = True
        else:
            df_cmd = get_df_cmd(extra_df_arg)

        rc, output = agent_util.execute_command(df_cmd, cache_timeout=agent_util.DEFAULT_CACHE_TIMEOUT)
        if 0 != rc:
            return None
        self.log.debug(u"%s output: %s" % (df_cmd, output))

        parser = DiskDFParser(self.log, config)
        df_data = parser.parse_df_output(output)
        mountpoint_data = df_data.get(mounted, None)
        if not mountpoint_data:
            self.log.error("Mountpoint %r not found" % mounted)
            if textkey == "filesystem.mounted": 
                return False
            return None

        def convert_capacity_field(capacity):
            if capacity is None:
                return None
            if capacity == '-':
                return 0
            else:
                return int(capacity.rstrip('%'))

        if 'filesystem.mounted' == textkey: 
            return True
        if textkey in ['usage.percent_used', "inode.percent_used"]:
            key = 'capacity'
            if is_inode_query:
                key = 'iuse_pct'
            return convert_capacity_field(mountpoint_data.get(key, None))

        key = None      
        if "inode.used" == textkey: 
            key = 'iused'
        elif "inode.available" == textkey:
            key = 'ifree'
        elif 'usage.kb_available' == textkey:
            key = 'available'
        if not key:
            return None
        mv = mountpoint_data.get(key, None)
        if mv is None:
            return None
        if '-' == mv:
            return 0

        return int(mv)
Bethany
Bethany
0%

THE FINEST HOTEL NEAR LAKE KIVU

The Perfect Base For You

Required fields are followed by *





EC1A68011

About Us

Delicious Interior With The Pinch Of Everything

Bethany Investment group is Presbyterian church in Rwanda(EPR) company that manage Hotel and Guest house in Karongi (Bethany Hotel), ISANO branch in GIKONDO(Kigali), Kiyovu branch(Kigali), AMIZERO branch(Nyagatare-East) and Gisenyi Branch(Rubavu).

Accomodation

Get a Comfortable Room
Feel The Comfort

Get a comfortable room and feel our hotel’s comfort. Bethany Hotel features a variety of fully furnished rooms with extra space, Executive rooms, Deluxe rooms with a beautiful lake view and garden space, Deluxe rooms, comfort rooms, family rooms and standard rooms at your service.

Standard Single

Services

We Provide Top Class Facility
Especially For You

Beach BBQ Party

Kick back on the beach& and enjoy our berbecue from our masterchef

Breakfast

Kick back at our hotels& enjoy our breakfast from our masterchef

Conference Hall

Kick back at our hotels& enjoy our conference halls from all bethany branches

Enjoy with your partner

Honeymoon Package

80%

Get In Touch

Don’t Miss Any Update

    +

    Search your Room

    Required fields are followed by *