logparse / util.pyon commit better log formatting and limit lines to 80 char (a12c41f)
   1"""
   2Commonly used general functions.
   3
   4This module provides the following methods:
   5    - `hostname`:       get the current machine's hostname
   6    - `getlocaldomain`: get the current machine's domain name
   7    - `resolve`:        attempt to convert a local/public IP to hostname
   8    - `readlog`:        read contents of a log file from disk
   9"""
  10
  11from datetime import datetime, timedelta
  12import copy
  13import ipaddress
  14import logging
  15import os
  16from pkg_resources import Requirement, resource_filename
  17import re
  18import socket
  19from systemd import journal
  20
  21from logparse import config, formatting
  22from logparse.timeparse import timeparse
  23
  24
  25logger = logging.getLogger(__name__)
  26
  27
  28def hostname(path): # get the hostname of current server
  29    """
  30    Get the hostname of the current machine using the file supplied in the
  31    `hostname-path` config option.
  32    """
  33
  34    hnfile = open(path, 'r')
  35    hn = re.search('^(\w*)\n*', hnfile.read()).group(1)
  36    return hn
  37
  38
  39def getlocaldomain(): # get the parent fqdn of current server
  40    """
  41    Get parent domain name (possibly FQDN) of the current machine. Note: if
  42    `socket.fetfqdn()` returns localhost, make sure the first entry in the
  43    hostname file includes the FQDN.
  44    """
  45
  46    domain = socket.getfqdn().split('.', 1)
  47    if len(domain) != 2:
  48        logger.warning("Could not get domain of this server, only hostname. "
  49            "Please consider updating the hostname file at {0}".format(
  50                config.prefs.get("logparse", "hostname-path")))
  51        return 'localdomain'
  52    else:
  53        return domain[-1]
  54
  55
  56def resolve(ip, fqdn=None):        # try to resolve an ip to hostname
  57    """
  58    Attempt to resolve an IP into a hostname or FQDN.
  59    Possible values for fqdn:
  60        - fqdn            show full hostname and domain
  61        - fqdn-implicit   show hostname and domain unless local
  62        - host-only       only show hostname
  63        - ip              never resolve anything
  64    Note resolve-domains settings defined in individual sections of the config
  65    take priority over the global config (this is enforced in parser modules)
  66    """
  67    
  68    if not fqdn:
  69        fqdn = config.prefs.get("logparse", "resolve-domains")
  70
  71    if fqdn == 'ip':
  72        return(ip)
  73
  74    try:
  75        ip_obj = ipaddress.ip_address(ip)
  76    except ValueError as err:
  77        logger.debug("Invalid format: " + str(err))
  78        return ip
  79
  80    try:
  81        hn = socket.gethostbyaddr(ip)[0] # resolve ip to hostname
  82    except socket.herror:
  83        # cannot resolve ip
  84        logger.debug(ip + " cannot be found, might not exist anymore")
  85        return(ip)
  86    except Exception as err:
  87        logger.warning("Failed to resolve hostname for " + ip + ": " + str(err))
  88        return(ip)  # return ip if no hostname exists
  89
  90    if (fqdn == "host-only") or (fqdn == "fqdn-implicit" and ip_obj.is_private):
  91        return hn.split('.')[0]
  92    if fqdn == 'fqdn' or fqdn == 'fqdn-implicit':
  93        return hn
  94    return hn
  95
  96
  97
  98def readlog(path = None, mode = 'r'):
  99    """
 100    Read a logfile from disk and return string
 101    """
 102    
 103    if (path == None):
 104        logger.error("No path provided")
 105        return 1
 106    else:
 107        if (os.path.isfile(path) is False):
 108            logger.error("Log at {0} was requested but does not exist"
 109                    .format(path))
 110            return ''
 111        else:
 112            try:
 113                return open(path, mode).read()
 114            except IOError or OSError as e:
 115                logger.warning("Error reading log at {0}: {1}"
 116                        .format(path, e.strerror))
 117                return 1
 118
 119class LogPeriod:
 120
 121    def __init__(self, section):
 122        if config.prefs.get(section.split("_")[0], "period"):
 123            self.startdate = datetime.now() \
 124                - timeparse(config.prefs.get(section.split("_")[0], "period"))
 125            logger.debug("Parsing logs for {0} since {1}".format(
 126                section, self.startdate.strftime(formatting.DATEFMT
 127                    + " " + formatting.TIMEFMT)))
 128            self.unique = True
 129        else:
 130            self.startdate = datetime.now() \
 131                - timeparse(config.prefs.get("logparse", "period"))
 132            self.unique = False