""" Commonly used general functions. This module provides the following methods: - `hostname`: get the current machine's hostname - `getlocaldomain`: get the current machine's domain name - `resolve`: attempt to convert a local/public IP to hostname - `readlog`: read contents of a log file from disk """ from datetime import datetime, timedelta import ipaddress import logging import os from pkg_resources import Requirement, resource_filename import re import socket from systemd import journal from logparse import config, formatting from logparse.timeparse import timeparse logger = logging.getLogger(__name__) def hostname(path): # get the hostname of current server """ Get the hostname of the current machine using the file supplied in the `hostname-path` config option. """ hnfile = open(path, 'r') hn = re.search('^(\w*)\n*', hnfile.read()).group(1) return hn def getlocaldomain(): # get the parent fqdn of current server """ Get parent domain name (possibly FQDN) of the current machine. Note: if `socket.fetfqdn()` returns localhost, make sure the first entry in the hostname file includes the FQDN. """ domain = socket.getfqdn().split('.', 1) if len(domain) != 2: logger.warning("Could not get domain of this server, only hostname. Please consider updating the hostname file at {0}".format(config.prefs.get("logparse", "hostname-path"))) return 'localdomain' else: return domain[-1] def resolve(ip, fqdn=None): # try to resolve an ip to hostname """ Attempt to resolve an IP into a hostname or FQDN. Possible values for fqdn: - fqdn show full hostname and domain - fqdn-implicit show hostname and domain unless local - host-only only show hostname - ip never resolve anything Note resolve-domains settings defined in individual sections of the config take priority over the global config (this is enforced in parser modules) """ if not fqdn: fqdn = config.prefs.get("logparse", "resolve-domains") if fqdn == 'ip': return(ip) try: ip_obj = ipaddress.ip_address(ip) except ValueError as err: logger.debug("Invalid format: " + str(err)) return ip try: hn = socket.gethostbyaddr(ip)[0] # resolve ip to hostname except socket.herror: # cannot resolve ip logger.debug(ip + " cannot be found, might not exist anymore") return(ip) except Exception as err: logger.warning("Failed to resolve hostname for " + ip + ": " + str(err)) return(ip) # return ip if no hostname exists if (fqdn == "host-only") or (fqdn == "fqdn-implicit" and ip_obj.is_private): return hn.split('.')[0] if fqdn == 'fqdn' or fqdn == 'fqdn-implicit': return hn return hn def readlog(path = None, mode = 'r'): """ Read a logfile from disk and return string """ if (path == None): logger.error("No path provided") return 1 else: if (os.path.isfile(path) is False): logger.error("Log at {0} was requested but does not exist".format(path)) return '' else: try: return open(path, mode).read() except IOError or OSError as e: logger.warning("Error reading log at {0}: {1}".format(path, e.strerror)) return 1 class LogPeriod: def __init__(self, section): if config.prefs.get(section.split("_")[0], "period"): self.startdate = datetime.now() - timeparse(config.prefs.get(section.split("_")[0], "period")) logger.debug("Parsing logs for {0} since {1}".format(section, self.startdate.strftime(formatting.DATEFMT + " " + formatting.TIMEFMT))) self.unique = True else: self.startdate = datetime.now() - timeparse(config.prefs.get("logparse", "period")) self.unique = False