MSV FM

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

"""
FortiMonitor Monitoring Agent Oracle Database Plugin
Copyright 2023 Fortinet, Inc. All Rights Reserved.
[email protected]

To Configure:

The following configuration options need to be set under the [oracle] block in the
agent configuration file:

- oracle_home - ORACLE_HOME value that points to the local database installation
- oracle_sid - name of the database instance to be used for connections
- username - username for user that the agent should use when connecting to the database
- password - password for user that the agent should use when connecting to the database
- tns_listener_ip (optional) - IP address that the TNS listenener service is running on

The user that will be used by the agent needs the following permission grants to fully operate:

GRANT CREATE SESSION TO <USER> ;
GRANT SELECT ON dba_data_files TO <USER> ;
GRANT SELECT ON dba_segments TO <USER> ;
GRANT SELECT ON dba_free_space, v$resource_limit to <USER> ;
GRANT SELECT ON v_$resource_limit to <USER> ;
"""

import agent_util
import os
import os.path
import sys
import tempfile
from agent_util import float

import logging

logger = logging.getLogger(__name__)

tablespace_query = """select b.tablespace_name, tbs_size SizeMb, a.free_space FreeMb from  (select tablespace_name, round(sum(bytes)/1024/1024 ,2)
     as free_space from dba_free_space group by tablespace_name) a, (select tablespace_name, sum(bytes)/1024/1024 as tbs_size
     from dba_data_files group by tablespace_name) b where a.tablespace_name(+)=b.tablespace_name;
"""
resource_query = """select resource_name, current_utilization, max_utilization from v$resource_limit;"""

def execute_query(sid, config, query, tnsname=None):
    "Run an Oracle query via sqlplus and parse the results"

    # Generate a temporary file for the query script
    (file, filename) = tempfile.mkstemp()
    orig_filename = filename
    filename += ".sql"
    f = open(filename, 'w')
    f.write("set pages 1000;\nset linesize 1000;\n %s\nquit;" % query)
    f.close()
    # Build the SQL*PLUS command and call it
    global_vars = "LD_LIBRARY_PATH=%s/lib ORACLE_HOME=%s ORACLE_SID=%s " % (config['oracle_home'], config['oracle_home'], sid)
    command = os.path.join(config.get("oracle_home"), "bin", "sqlplus")
    command_format = ' -S %s/'
    command_arguments = (config.get('username'), config.get('password'), filename)
    command_format += '\\"%s\\"'
    if tnsname:
        command_format += '@%s'
        command_arguments = (config.get('username'), config.get('password'), tnsname, filename)
    elif config.get('rds_end_point'):
        command_format += '@//%s:1521/orcl'
        command_arguments = (config.get('username'), config.get('password'), config.get('rds_end_point'), filename)

    command_format += ' @%s'
    cmd = global_vars + command + command_format % command_arguments
    status, output = agent_util.execute_command(cmd, timeout=10)
    # Remove our temporary file
    os.remove(filename)
    os.remove(orig_filename)

    # Parse the output
    results = []
    lines = output.strip().split("\n")
    columns = lines[0].lower().split()
    for line in lines[2:]:
        line = line.strip()
        if not line: continue
        if line.endswith("rows selected."): continue
        values = line.split()
        results.append(dict(zip(columns, values)))
    return results


class OraclePlugin(agent_util.Plugin):
    textkey = "oracle"
    label = "Oracle"

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

        # Make sure they provided an oracle configuration block
        if not config:
            self.log.info("No oracle configuration block found")
            return {}

        # Check to see if Oracle block has been setup in the configuration file - if not, no op
        if not ("oracle_home" in config and "oracle_sid" in config and "username" in config and "password" in config):
            msg = "One or more Oracle configuration parameters missing from the agent config file"
            self.log.info(msg)
            status = agent_util.MISCONFIGURED

        # Make sure the sqlplus executable is installed and executable
        if status == agent_util.SUPPORTED and not os.path.exists(os.path.join(config.get("oracle_home"), "bin", "sqlplus")):
            msg = "Oracle sqlplus executable not found in directory specified in agent config file."
            self.log.info(msg)
            status = agent_util.MISCONFIGURED

        if status == agent_util.MISCONFIGURED:
            data = {
                "tnslistener": {
                    "label": "Whether TNS listener is active and rechable",
                    "options": None,
                    "status": status,
                    "error_message": msg
                }
            }
            return data

        data = {}
        sid_list = [s.strip() for s in config.get('oracle_sid').split(',')]
        # Verify that the tnsping executable is present
        if os.path.exists(
                os.path.join(config.get("oracle_home"), "bin", "tnsping")):
            data['tnslistener'] = {
                "label": "Whether TNS listener is active and reachable",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": "",
            }

        """
        To support mapping the query parameter to the sid, introduce the oracle_servicenames_ keyset. The SID 
        name should be lower() for the oracle_servicenames_ keys. This can be either service names or
        tnsnames, but need verification.
        [oracle]
        oracle_sids = SID1, SID2
        oracle_servicenames_sid1 = pdb1, pdb2
        oracle_servicenames_sid2 = pdb3, pdb4
        """

        # Gather up the available tablespaces that can be reported on
        spaces = []
        for sid in sid_list:
            tsname_key = 'oracle_servicenames_{}'.format(sid.lower())
            tsnames = config.get(tsname_key, None)
            if tsnames:
                tnsnames = [ts.strip() for ts in tsnames.split(',')]
                for tnsname in tnsnames:
                    results = execute_query(sid, config, tablespace_query, tnsname)
                    key = '{}:{}'.format(sid, tnsname)
                    for r in results:
                        spaces.append('{}:{}'.format(key, r["tablespace_name"]))
            
            elif config.get('tnsname'):
                results = execute_query(sid, config, tablespace_query, config.get('tnsname'))
                for r in results:
                    spaces.append('{}:{}'.format(sid, r["tablespace_name"]))

            elif config.get('rds_end_point'):
                results = execute_query(sid, config, tablespace_query)
                for r in results:
                    spaces.append('{}:{}'.format(sid, r["tablespace_name"]))
            
           
        if spaces:
            data['tablespace.size'] = {
                "label": "Size of tablespace in MB",
                "options": spaces,
                "status": agent_util.SUPPORTED,
                "error_message": "",
                "units": "MB"
            }
            data['tablespace.free'] = {
                "label": "Free space of tablespace in MB",
                "options": spaces,
                "status": agent_util.SUPPORTED,
                "error_message": "",
                "units": "MB"
            }
            data['tablespace.percent_free'] = {
                "label": "Percent of tablespace free",
                "options": spaces,
                "status": agent_util.SUPPORTED,
                "error_message": "",
                "units": "percent"
            }

        # Gather up the resource utilization metrics
        results = execute_query(sid_list[0], config, resource_query)
        resources = [r["resource_name"] for r in results]
        if results:
            data["resource.process.current"] = {
                "label": "Number of current processes",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.process.max"] = {
                "label": "Maximum number of processes",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }

            data["resource.session.current"] = {
                "label": "Number of current sessions",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.session.max"] = {
                "label": "Maximum number of sessions",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.enqueue_lock.current"] = {
                "label": "Number of current enqueue locks",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.enqueue_lock.max"] = {
                "label": "Maximum number of enqueue locks",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.enqueue_resource.current"] = {
                "label": "Number of current enqueue resources",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.enqueue_resource.max"] = {
                "label": "Maximum number of enqueue resources",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_lock.current"] = {
                "label": "Number of current Global Enqueue Service locks",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_lock.max"] = {
                "label": "Maximum number of Global Enqueue Service locks",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_proc.current"] = {
                "label": "Number of current Global Enqueue Service processes ",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_proc.max"] = {
                "label": "Maximum number of Global Enqueue Service processes",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_resource.current"] = {
                "label": "Number of Global Enqueue Service resources",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.ges_resource.max"] = {
                "label": "Maximum number of Global Enqueue Service resources",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.max_shared_servers.current"] = {
                "label": "Current number of Maximum Shared Servers",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.max_shared_servers.max"] = {
                "label": "Maximum number of Maximum Shared Servers",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.transactions.current"] = {
                "label": "Current number of transactions",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }
            data["resource.transactions.max"] = {
                "label": "Maximum number of transactions",
                "options": sid_list,
                "status": agent_util.SUPPORTED,
                "error_message": ""
            }

        return data

    def check(self, textkey, data, config):

        if not data:
            msg = "Resource option is missing for metric type `%s`." % textkey
            self.log.info(msg)

        if textkey.startswith("resource."):
            sid = data
            junk, metric, kind = textkey.split('.')
            metric_mapping = {
                "process": "processes",
                "session": "sessions",
                "enqueue_lock": "enqueue_locks",
                "enqueue_resource": "enqueue_resources",
                "ges_lock": "ges_locks",
                "ges_proc": "ges_procs",
                "ges_resource": "ges_ress",
                "max_shared_servers": "max_shared_servers",
                "transactions": "transactions",
            }

            results = execute_query(sid, config, resource_query)
            for r in results:
                if r["resource_name"] == metric_mapping.get(metric, None):
                    if kind == "current":
                        return int(r["current_utilization"])
                    elif kind == "max":
                        return int(r["max_utilization"])

        elif textkey.startswith("tablespace"):
            sid = None 
            tablespace = None
            tsname = None
            items = data.split(':')
            if 2 == len(items):
                sid = items[0]
                tablespace = items[1]
                tsname = config.get('tsname', None)
            elif 3 == len(items):
                sid = items[0]
                tsname = items[1]
                tablespace = items[2]

            if sid is None or tablespace is None:
                raise Exception("Unrecognized option {}".format(data))
            results = execute_query(sid, config, tablespace_query, tsname)
            for r in results:
                if r["tablespace_name"] == tablespace:
                    if textkey.endswith(".size"):
                        return float(r["sizemb"])
                    elif textkey.endswith(".free"):
                        return float(r["freemb"])
                    elif textkey.endswith(".percent_free"):
                        if float(r["sizemb"]) == 0: return 0.
                        else:
                            return float(r["freemb"]) * 100. / float(r["sizemb"])

            # If we got here, the target tablespace wasn't found
            return 0

        elif textkey == "tnslistener":
            sid = data
            ip_address = config.get("tns_listener_ip", "127.0.0.1")
            cmd = "ORACLE_HOME=%s ORACLE_SID=%s " % (config['oracle_home'], sid)
            cmd += "%s %s" % (os.path.join(config.get("oracle_home"), "bin", "tnsping"), ip_address)
            status, output = agent_util.execute_command(cmd)
            if "OK" in output: return 1
            else: return 0

        else:
            msg = "Unknown metric type `%s` retuning `%s` as value." % (textkey, 0)
            self.log.info(msg)

            # Unknown metric type, return 0 by default
            return 0
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 *