rename parsers, better journald integration
[logparse.git] / logparse / config.py
index 13d6d07099759e82c168304acb92aca437096404..00143fd059a0291cc31ec92467ebc1df6c54ae5c 100644 (file)
-#
-#   config.py
-#
-#   Default config values and basic wrapper for PyYaml. New config options
-#   should be added to the dictionary below, along with appropriate defaults.
-#
+"""
+This modules contains default config values and basic wrapper for ConfigParser.
+New config options should be added to the dictionary below, along with 
+appropriate defaults. Runtime configuration is done through the config file at
+/etc/logparse/logparse.conf (default) or the path specified in the "--config"
+argument. The file uses the INI syntax, with general options being declared in
+the [logparse] section and parser-specific options declared in their own
+sections.
 
-import yaml
-import types
-import os
+This module provides the following methods:
+    - `loadconf()`: set up ConfigParser and process config file
+"""
+
+from configparser import ConfigParser
 from pkg_resources import Requirement, resource_filename
-from types import SimpleNamespace
 
 import logparse
 import logging
 logger = logging.getLogger(__name__)
 
-def locate(filename):
-    logger.debug("Searching for {0}".format(filename))
-    loc = resource_filename(Requirement.parse(__package__), filename)
-    logger.debug("Found {0}".format(loc))
-    return loc
-
-class Configuration(dict):
-
-    def __init__(self, *arg, **kw):
-        super(Configuration, self).__init__(*arg, **kw)
-    
-    def _str2bool(x):
-        positives = ["yes", "true", "1", "y"]
-        negatives = ["no", "false", "0", "n"]
-        x = x.lower()
-        if x in positives:
-            return True
-        elif x in negatives:
-            return False
-        else:
-            raise ValueError("Unknown option %s" % x)
+global prefs
+prefs = None
 
-defaults = Configuration({
-    'output': '/var/www/logparse/summary.html',
-    'header':  '/etc/logparse/header.html',
-    'css': '/etc/logparse/main.css',
-    'title': logparse.__name__,
-    'maxlist': 10,
-    'maxcmd': 3,
-    'resolve-domains': 'fqdn',
-    'mail': {
-        'to': '',
-        'from': '',
-        'subject': 'logparse from $hostname$',
-        'mailbin': '/usr/bin/mail',
-    },
-    'rotate': 'n',
-    'verbose': 'n',
-    'hddtemp': {
-        'drives': ['/dev/sda'],
-        'host': '127.0.0.1',
-        'separator': '|',
-        'timeout': 10,
-        'port': 7634,
-        'show-model': False, 
-    },
-    'apache': {
-        'resolve-domains': '',
-    },
-    'sshd': {
-        'resolve-domains': '',
-    },
-    'smbd': {
-        'resolve-domains': '',
-    },
-    'httpd': {
-        'resolve-domains': '',
-    },
-    'du': {
-        'paths': ['/', '/etc', '/home'],
-        'force-write': 'n',
-    },
-    'hostname-path': '/etc/hostname',
-    'logs': {
-        'auth': '/var/log/auth.log',
-        'cron': '/var/log/cron.log',
-        'sys': '/var/log/syslog',
-        'smb': '/var/log/samba',
-        'zfs': '/var/log/zpool.log',
-        'alloc': '/var/log/du.log',
-        'postfix': '/var/log/mail.log',
-        'httpd': '/var/log/apache2'
-    }
-})
+defaults = {
+        'logparse': {
+            'output': '',
+            'overwrite': False,
+            'title': logparse.__name__,
+            'maxlist': 10,
+            'maxcmd': 6,
+            'resolve-domains': 'fqdn',
+            'rotate': False,
+            'verbose': False, 
+            'quiet': False,
+            'hostname-path': '/etc/hostname',
+            'parsers': '',
+            'ignore-parsers': '',
+            'period': '1 week',
+            'datetime-format': "%%b %%d %%H:%%M:%%S",
+            'journald': True
+        },
+        'html': {
+            'header':  '/etc/logparse/header.html',
+            'css': '/etc/logparse/main.css',
+            'embed-styles': False,
+            'css-relpath': True
+        },
+        'plain': {
+            'plain': False,
+            'linewidth': 80
+        },
+        'logs': {
+            'auth': '/var/log/auth.log',
+            'cron': '/var/log/cron.log',
+            'cpuinfo': '/proc/cpuinfo',
+            'meminfo': '/proc/meminfo',
+            'uptime': '/proc/uptime',
+            'sys': '/var/log/syslog',
+            'smbd': '/var/log/samba',
+            'zfs': '/var/log/zpool.log',
+            'alloc': '/var/log/du.log',
+            'postfix': '/var/log/mail.log',
+            'httpd-access': '/var/log/apache2/access.log',
+            'httpd-error': '/var/log/apache2/error.log'
+        },
+        'cron': {
+            'summary': False,
+            'list-users': True,
+            'period': '',
+            'datetime-format': '',
+            'truncate-commands': True,
+            'users': '.*',
+            'commands': '.*'
+        },
+        'mail': {
+            'to': '',
+            'from': '',
+            'subject': 'logparse from $hostname',
+            'mailbin': '/usr/bin/mail'
+        },
+        'temperatures': {
+            'drives': ['/dev/sda'],
+            'host': '127.0.0.1',
+            'separator': '|',
+            'timeout': 10,
+            'port': 7634,
+            'show-model': False, 
+            'period': ''
+        },
+        'sshd': {
+            'sshd-resolve-domains': '',
+            'period': ''
+        },
+        'smbd': {
+            'shares': '^((?!IPC\$).)*$',
+            'users': '.*',
+            'smbd-resolve-domains': '',
+            'period': ''
+        },
+        'httpd': {
+            'httpd-resolve-domains': '',
+            'datetime-format': "%%d/%%b/%%Y:%%H:%%M:%%S %%z",
+            'period': '',
+            'clients': '.*',
+            'files': '.*',
+            'referrers': '.*',
+            'access-format': "%%h %%l %%u %%t \"%%r\" %%>s %%O \"%%{Referer}i\" \"%%{User-Agent}i\""
+        },
+        'du': {
+            'paths': ['/', '/etc', '/home'],
+            'force-write': False
+        },
+        'ufw': {
+            'ufw-resolve-domains': '',
+            'period': ''
+        },
+        'sudo': {
+            'journald': '',
+            'datetime-format': '',
+            'period': '',
+            'list-users': True,
+            'summary': True,
+            'truncate-commands': True,
+            'init-users': '.*',
+            'superusers': '.*',
+            'commands': '.*',
+            'directories': '.*'
 
-def verify(raw_dict, defaults):
-    for key, value in raw_dict.items():
-        if key in defaults: # valid key
-            logger.debug("Found valid key {0} with value {1}".format(key, value))
-            if (isinstance(value, dict)):
-                verify(value, defaults[key])   # recurse nested dictionaries
+        },
+        'systemd': {
+            'period': '',
+            'show-all': True
+        }
+}
 
-        else:               # invalid key
-            logger.warning("Invalid key {0} with value {1}".format(key, value))
 
-def loadconf(argparser, configfile = "/etc/logparse/logparse.conf"):
-    logger.debug("Getting config from {0}".format(configfile))
+def loadconf(configpaths):
+    """
+    Initial setup for a ConfigParser object. `configpaths` should be a list of
+    configuration files to load (typically only one). To use the generated
+    ConfigParser, use `import logparse.config` and then `config.prefs.get(..)`.
+    The prefs object is returned after creation as a convenience but this method
+    should only be called once per runtime.
+    """
+    prefs= ConfigParser()
+    prefs.read_dict(defaults)
     try:
-        raw_dict = yaml.safe_load(open(configfile))
-        # verify fields
-        verify(raw_dict, defaults)
-        prefs = defaults
-        for value in raw_dict:
-            if(isinstance(raw_dict[value], dict)):
-                for key in raw_dict[value].items():
-                    logger.debug("Inserting key {0} with value {1}".format(key[0], key[1]))
-                    if not value in prefs:
-                        prefs[value] = {}
-                    prefs[value][key[0]] = key[1]
-            else:
-                prefs[value] = raw_dict[value]
-        if argparser.parse_args().to is not None:
-            prefs['mail']['to'] = argparser.parse_args().to
-        if not prefs['mail']['to']:
-            logger.info("No recipient address provided, outputting to stdout")
-        else:
-            logger.info("Email will be sent to " + prefs['mail']['to'])
-        return prefs 
+        success = prefs.read(configpaths)
+        logger.debug("Loaded {0} config file(s): {1}".format(
+                str(len(success)), str(success)))
     except Exception as e:
         logger.warning("Error processing config: " + str(e))
+    return prefs