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 inspect 13import logging 14import os 15from pkg_resources import Requirement, resource_filename 16import re 17import socket 18from systemd import journal 19 20from logparse import config 21 22 23logger = logging.getLogger(__name__) 24 25 26def hostname(path): # get the hostname of current server 27 """ 28 Get the hostname of the current machine using the file supplied in the 29 `hostname-path` config option. 30 """ 31 32 hnfile = open(path, 'r') 33 hn = re.search('^(\w*)\n*', hnfile.read()).group(1) 34 return hn 35 36 37def getlocaldomain(): # get the parent fqdn of current server 38 """ 39 Get parent domain name (possibly FQDN) of the current machine. Note: if 40 `socket.fetfqdn()` returns localhost, make sure the first entry in the 41 hostname file includes the FQDN. 42 """ 43 44 domain = socket.getfqdn().split('.', 1) 45 if len(domain) != 2: 46 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"))) 47 return 'localdomain' 48 else: 49 return domain[-1] 50 51 52def resolve(ip, fqdn=None): # try to resolve an ip to hostname 53 """ 54 Attempt to resolve an IP into a hostname or FQDN. 55 Possible values for fqdn: 56 - fqdn show full hostname and domain 57 - fqdn-implicit show hostname and domain unless local 58 - host-only only show hostname 59 - ip never resolve anything 60 Note resolve-domains settings defined in individual sections of the config 61 take priority over the global config (this is enforced in parser modules) 62 """ 63 64 if not fqdn: 65 fqdn = config.prefs.get("logparse", "resolve-domains") 66 67 if fqdn == 'ip': 68 return(ip) 69 70 try: 71 socket.inet_aton(ip) # succeeds if text contains ip 72 hn = socket.gethostbyaddr(ip)[0] # resolve ip to hostname 73 if fqdn == 'fqdn-implicit' and hn.split('.', 1)[1] == getlocaldomain(): 74 return(hn.split('.')[0]) 75 elif fqdn == 'fqdn' or fqdn == 'fqdn-implicit': 76 return(hn) 77 elif fqdn == 'host-only': 78 return(hn.split('.')[0]) 79 else: 80 logger.warning("Invalid value for FQDN config") 81 return(hn) 82 except socket.herror: 83 # cannot resolve ip 84 logger.debug(ip + " cannot be found, might not exist anymore") 85 return(ip) 86 except (OSError, socket.error): # socket.error for Python 2 compatibility 87 # already a hostname 88 logger.debug(ip + " is already a hostname") 89 return(ip) 90 except Exception as err: 91 logger.warning("failed to resolve hostname for " + ip + ": " + str(err)) 92 return(ip) # return ip if no hostname exists 93 94 95def readlog(path = None, mode = 'r'): 96 """ 97 Read a logfile from disk and return string 98 """ 99 100 if (path == None): 101 logger.error("No path provided") 102 return 1 103 else: 104 if (os.path.isfile(path) is False): 105 logger.error("Log at {0} was requested but does not exist".format(path)) 106 return '' 107 else: 108 try: 109 return open(path, mode).read() 110 except IOError or OSError as e: 111 logger.warning("Error reading log at {0}: {1}".format(path, e.strerror)) 112 return 1