Logo Search packages:      
Sourcecode: nagstamon version File versions  Download package

def Nagstamon::nagstamonObjects::NagiosServer::GetStatus (   self  ) 

get nagios status information from nagcgiurl and give it back
as dictionary

Definition at line 78 of file nagstamonObjects.py.

00078                        :
        """
        get nagios status information from nagcgiurl and give it back
        as dictionary
        """

        # set checking flag to be sure only one thread cares about this server
        self.isChecking = True
        
        # check if server is enabled, if not, do not get any status
        if str(self.conf.servers[self.name].enabled) == "False":
            self.WorstStatus = "OK"
            self.nagitems_filtered = {"services":{"CRITICAL":[], "WARNING":[], "UNKNOWN":[]}, "hosts":{"DOWN":[], "UNREACHABLE":[]}}
            self.isChecking = False          
            return True

        # create filters like described in
        # http://www.nagios-wiki.de/nagios/tips/host-_und_serviceproperties_fuer_status.cgi?s=servicestatustypes
        # hoststatus
        hoststatustypes = 12
        if str(self.conf.filter_all_down_hosts) == "True":
            hoststatustypes = hoststatustypes - 4
        if str(self.conf.filter_all_unreachable_hosts) == "True":
            hoststatustypes = hoststatustypes - 8
        # servicestatus
        servicestatustypes = 28
        if str(self.conf.filter_all_unknown_services) == "True":
            servicestatustypes = servicestatustypes - 8
        if str(self.conf.filter_all_warning_services) == "True":
            servicestatustypes = servicestatustypes - 4
        if str(self.conf.filter_all_critical_services) == "True":
            servicestatustypes = servicestatustypes - 16
        # serviceprops & hostprops both have the same values for the same states so I
        # group them together
        hostserviceprops = 0
        if str(self.conf.filter_acknowledged_hosts_services) == "True":
            hostserviceprops = hostserviceprops + 8
        if str(self.conf.filter_hosts_services_disabled_notifications) == "True":
            hostserviceprops = hostserviceprops + 8192
        if str(self.conf.filter_hosts_services_disabled_checks) == "True":
            hostserviceprops = hostserviceprops + 32
        if str(self.conf.filter_hosts_services_maintenance) == "True":
            hostserviceprops = hostserviceprops + 2
        
        # create Nagios items dictionary with to lists for services and hosts
        # every list will contain a dictionary for every failed service/host
        nagitems = {"services":[], "hosts":[]}

        # services (unknown, warning or critical?)
        nagcgiurl_services = self.nagios_cgi_url + "/status.cgi?host=all&servicestatustypes=" + str(servicestatustypes) + "&serviceprops=" + str(hostserviceprops)
        # hosts (up or down or unreachable)
        nagcgiurl_hosts = self.nagios_cgi_url + "/status.cgi?hostgroup=all&style=hostdetail&hoststatustypes=" + str(hoststatustypes) + "&hostprops=" + str(hostserviceprops)
        # fetching hosts in downtime and acknowledged hosts at once is not possible because these 
        # properties get added and nagios display ONLY hosts that have BOTH states
        # hosts that are in scheduled downtime, we will later omit services on those hosts
        # hostproperty 1 = HOST_SCHEDULED_DOWNTIME 
        nagcgiurl_hosts_in_maintenance = self.nagios_cgi_url + "/status.cgi?hostgroup=all&style=hostdetail&hostprops=1"
        # hosts that are acknowledged, we will later omit services on those hosts
        # hostproperty 4 = HOST_STATE_ACKNOWLEDGED 
        nagcgiurl_hosts_acknowledged = self.nagios_cgi_url + "/status.cgi?hostgroup=all&style=hostdetail&hostprops=4"

        # hosts - mostly the down ones
        # unfortunately the hosts status page has a different structure so
        # hosts must be analyzed separately
        try:
            htobj = self.FetchURL(nagcgiurl_hosts, giveback="dict")
            # workaround for Nagios < 2.7 which has an <EMBED> in its output
            # do a copy of a part of htobj into table to be able to delete htobj
            try:
                table = copy.copy(htobj.body.div.table)
            except:
                table = copy.copy(htobj.body.embed.div.table)
            
            # do some cleanup    
            del htobj

            for i in range(1, len(table.tr)):
                try:
                    # ignore empty <tr> rows
                    if not table.tr[i].countchildren() == 1:
                        n = {}
                        # host
                        try:
                            n["host"] = str(table.tr[i].td[0].table.tr.td.table.tr.td.a.text)
                        except:
                            n["host"] = str(nagitems[len(nagitems)-1]["host"])
                        # status
                        n["status"] = str(table.tr[i].td[1].text)
                        # last_check
                        n["last_check"] = str(table.tr[i].td[2].text)
                        # duration
                        n["duration"] = str(table.tr[i].td[3].text)
                        # status_information
                        n["status_information"] = str(table.tr[i].td[4].text)
                        # attempts are not shown in case of hosts so it defaults to "N/A"
                        n["attempt"] = "N/A"
                        
                        # add dictionary full of information about this host item to nagitems
                        nagitems["hosts"].append(n)
                        # after collection data in nagitems create objects from its informations
                        # host objects contain service objects
                        if not self.new_hosts.has_key(n["host"]):
                            self.new_hosts[n["host"]] = NagiosHost()
                            self.new_hosts[n["host"]].name = n["host"]
                            self.new_hosts[n["host"]].status = n["status"]
                            self.new_hosts[n["host"]].last_check = n["last_check"]
                            self.new_hosts[n["host"]].duration = n["duration"]
                            self.new_hosts[n["host"]].attempt = n["attempt"]
                            self.new_hosts[n["host"]].status_information= n["status_information"]
                except:
                    pass
                
            # do some cleanup
            del table
            
        except:
            # set checking flag back to False
            self.isChecking = False
            return "ERROR"

        # services
        try:
            htobj = self.FetchURL(nagcgiurl_services, giveback="dict")

            for i in range(1, len(htobj.body.table[2].tr)):
                try:
                    # ignore empty <tr> rows - there are a lot of them - a Nagios bug? 
                    if not htobj.body.table[2].tr[i].countchildren() == 1:
                        n = {}
                        # host
                        # the resulting table of Nagios status.cgi table omits the
                        # hostname of a failing service if there are more than one
                        # so if the hostname is empty the nagios status item should get
                        # its hostname from the previuos item - one reason to keep "nagitems"
                        try:
                            n["host"] = str(htobj.body.table[2].tr[i].td[0].table.tr.td.table.tr.td.a.text)
                        except:
                            n["host"] = str(nagitems["services"][len(nagitems["services"])-1]["host"])
                        # service
                        n["service"] = str(htobj.body.table[2].tr[i].td[1].table.tr.td.table.tr.td.a.text)
                        # status
                        n["status"] = str(htobj.body.table[2].tr[i].td[2].text)
                        # last_check
                        n["last_check"] = str(htobj.body.table[2].tr[i].td[3].text)
                        # duration
                        n["duration"] = str(htobj.body.table[2].tr[i].td[4].text)
                        # attempt
                        n["attempt"] = str(htobj.body.table[2].tr[i].td[5].text)
                        # status_information
                        n["status_information"] = str(htobj.body.table[2].tr[i].td[6].text)
                        # add dictionary full of information about this service item to nagitems - only if service
                        nagitems["services"].append(n)
                        
                        # after collection data in nagitems create objects of its informations
                        # host objects contain service objects
                        if not self.new_hosts.has_key(n["host"]):
                            self.new_hosts[n["host"]] = NagiosHost()
                            self.new_hosts[n["host"]].name = n["host"]
                            self.new_hosts[n["host"]].status = "OK"
                        # if a service does not exist create its object
                        if not self.new_hosts[n["host"]].services.has_key(n["service"]):
                            self.new_hosts[n["host"]].services[n["service"]] = NagiosService()
                            self.new_hosts[n["host"]].services[n["service"]].host = n["host"]
                            self.new_hosts[n["host"]].services[n["service"]].name = n["service"]
                            self.new_hosts[n["host"]].services[n["service"]].status = n["status"]
                            self.new_hosts[n["host"]].services[n["service"]].last_check = n["last_check"]
                            self.new_hosts[n["host"]].services[n["service"]].duration = n["duration"]
                            self.new_hosts[n["host"]].services[n["service"]].attempt = n["attempt"]
                            self.new_hosts[n["host"]].services[n["service"]].status_information = n["status_information"]
                except:
                    pass
                                
            # do some cleanup
            del htobj
            
        except:
            # set checking flag back to False
            self.isChecking = False
            return "ERROR"
       
         # hosts which are in scheduled downtime
        try:
            htobj = self.FetchURL(nagcgiurl_hosts_in_maintenance, giveback="dict")
           
            # workaround for Nagios < 2.7 which has an <EMBED> in its output
            try:
                table = copy.copy(htobj.body.div.table)
            except:
                table = copy.copy(htobj.body.embed.div.table)
            
            # do some cleanup    
            del htobj

            for i in range(1, len(table.tr)):
                try:
                    # ignore empty <tr> rows
                    if not table.tr[i].countchildren() == 1:
                        # host
                        try:
                            self.new_hosts_in_maintenance.append(str(table.tr[i].td[0].table.tr.td.table.tr.td.a.text))
                            # get real status of maintained host
                            if self.new_hosts.has_key(self.new_hosts_acknowledged[-1]):
                                self.new_hosts[self.new_hosts_acknowledged[-1]].status = str(table.tr[i].td[1].text)
                        except:
                            pass
                except:
                    pass

            # do some cleanup
            del table
        
        except:
            # set checking flag back to False
            self.isChecking = False
            return "ERROR"
        
        # hosts which are acknowledged
        try:
            htobj = self.FetchURL(nagcgiurl_hosts_acknowledged, giveback="dict")
            # workaround for Nagios < 2.7 which has an <EMBED> in its output
            try:
                table = copy.copy(htobj.body.div.table)
            except:
                table = copy.copy(htobj.body.embed.div.table)
            
            # do some cleanup    
            del htobj               

            for i in range(1, len(table.tr)):
                try:
                    # ignore empty <tr> rows
                    if not table.tr[i].countchildren() == 1:
                        # host
                        try:
                            self.new_hosts_acknowledged.append(str(table.tr[i].td[0].table.tr.td.table.tr.td.a.text))
                            # get real status of acknowledged host
                            if self.new_hosts.has_key(self.new_hosts_acknowledged[-1]):
                                self.new_hosts[self.new_hosts_acknowledged[-1]].status = str(table.tr[i].td[1].text)
                        except:
                            pass
                except:
                    pass

            # do some cleanup
            del table

        except:
            # set checking flag back to False
            self.isChecking = False
            return "ERROR"

        # this part has been before in GUI.RefreshDisplay() - wrong place 
        self.nagitems_filtered = {"services":{"CRITICAL":[], "WARNING":[], "UNKNOWN":[]}, "hosts":{"DOWN":[], "UNREACHABLE":[]}}
        
        # initialize counts for varios service/hosts states
        # count them with every miserable host/service respective to their meaning
        self.downs = 0
        self.unreachables = 0
        self.unknowns = 0
        self.criticals = 0
        self.warnings = 0

        for host in self.new_hosts.values():
            # filtering out hosts, sorting by severity
            if host.status == "DOWN" and nagstamonActions.HostIsFilteredOutByRE(host.name, self.conf) == False\
            and (not (host.name in self.new_hosts_in_maintenance and \
            str(self.conf.filter_hosts_services_maintenance) == "True") and \
            not (host.name in self.new_hosts_acknowledged and \
            str(self.conf.filter_acknowledged_hosts_services) == "True")): 
                self.nagitems_filtered["hosts"]["DOWN"].append(host)
                self.downs += 1
            if host.status == "UNREACHABLE" and nagstamonActions.HostIsFilteredOutByRE(host.name, self.conf) == False\
                and (not host.name in self.new_hosts_acknowledged and not host.name in self.new_hosts_in_maintenance): 
                self.nagitems_filtered["hosts"]["UNREACHABLE"].append(host)    
                self.unreachables += 1

            for service in host.services.values():
                # check hard/soft state, find out number of attempts and max attempts for
                # checking if soft state services should be shown
                real_attempt, max_attempt = service.attempt.split("/")
                # omit services on hosts in maintenance and acknowledged hosts
                if (not (host.name in self.new_hosts_in_maintenance and \
                str(self.conf.filter_hosts_services_maintenance) == "True") or \
                not (host.name in self.new_hosts_acknowledged and \
                str(self.conf.filter_acknowledged_hosts_services) == "True")) and \
                not (host.name in self.new_hosts_in_maintenance and\
                str(self.conf.filter_services_on_hosts_in_maintenance) == "True") and\
                not (real_attempt <> max_attempt and \
                str(self.conf.filter_services_in_soft_state) == "True") and \
                not (host.status == "DOWN" and \
                str(self.conf.filter_services_on_down_hosts) == "True") and \
                not (host.status == "UNREACHABLE" and \
                str(self.conf.filter_services_on_unreachable_hosts) == "True") and \
                nagstamonActions.HostIsFilteredOutByRE(host.name, self.conf) == False and \
                nagstamonActions.ServiceIsFilteredOutByRE(service.name, self.conf) == False:
                    # sort by severity
                    if service.status == "CRITICAL": 
                        self.nagitems_filtered["services"]["CRITICAL"].append(service)
                        self.criticals += 1
                    if service.status == "WARNING": 
                        self.nagitems_filtered["services"]["WARNING"].append(service)
                        self.warnings += 1
                    if service.status == "UNKNOWN": 
                        self.nagitems_filtered["services"]["UNKNOWN"].append(service)
                        self.unknowns += 1

        # find out if there has been some status change to notify user
        # compare sorted lists of filtered nagios items
        new_nagitems_filtered_list = []
        
        for i in self.nagitems_filtered["hosts"].values():
            for h in i:
                new_nagitems_filtered_list.append((h.name, h.status))   
            
        for i in self.nagitems_filtered["services"].values():
            for s in i:
                new_nagitems_filtered_list.append((s.host, s.name, s.status))  
                 
        # sort for better comparison
        new_nagitems_filtered_list.sort()

        # if both lists are identical there was no status change
        if (self.nagitems_filtered_list == new_nagitems_filtered_list):       
            self.WorstStatus = "OK"
        else:
            # if the new list is shorter than the first and there are no different hosts 
            # there one host/service must have been recovered, which is not worth a notification
            diff = []
            for i in new_nagitems_filtered_list:
                if not i in self.nagitems_filtered_list:
                    # collect differences
                    diff.append(i)
            if len(diff) == 0:
                self.WorstStatus = "OK"
            else:
                # if there are different hosts/services in list of new hosts there must be a notification
                # get list of states for comparison
                diff_states = []
                for d in diff:
                    diff_states.append(d[-1])
                # temporary worst state index   
                worst = 0
                for d in diff_states:
                    # only check worst state if it is valid
                    if d in self.States:
                        if self.States.index(d) > worst:
                            worst = self.States.index(d)
                            
                # final worst state is one of the predefined states
                self.WorstStatus = self.States[worst]
            
        # copy of listed nagitems for next comparison
        self.nagitems_filtered_list = copy.copy(new_nagitems_filtered_list)

        # do some cleanup
        self.hosts.clear()
        del self.hosts_acknowledged[::]
        del self.hosts_in_maintenance[::]

        # put new informations into respective dictionaries      
        self.hosts, self.hosts_acknowledged, self.hosts_in_maintenance = copy.copy(self.new_hosts), copy.copy(self.new_hosts_acknowledged), copy.copy(self.new_hosts_in_maintenance)
        
        # after all checks are done unset checking flag
        self.isChecking = False
        
        # do some cleanup
        del nagitems
        self.new_hosts.clear()
        del self.new_hosts_acknowledged[::]
        del self.new_hosts_in_maintenance[::]
        gc.collect()
        
        # return True if all worked well    
        return True
    
    
    def FetchURL(self, url, giveback="dict", cgi_data=None):


Generated by  Doxygen 1.6.0   Back to index