1#
2# config.py
3#
4# Default config values and basic wrapper for PyYaml. New config options
5# should be added to the dictionary below, along with appropriate defaults.
6#
7
8import yaml
9import types
10import os
11from pkg_resources import Requirement, resource_filename
12from types import SimpleNamespace
13
14import logparse
15import logging
16logger = logging.getLogger(__name__)
17
18def locate(filename):
19 logger.debug("Searching for {0}".format(filename))
20 loc = resource_filename(Requirement.parse(__package__), filename)
21 logger.debug("Found {0}".format(loc))
22 return loc
23
24class Configuration(dict):
25
26 def __init__(self, *arg, **kw):
27 super(Configuration, self).__init__(*arg, **kw)
28
29 def _str2bool(x):
30 positives = ["yes", "true", "1", "y"]
31 negatives = ["no", "false", "0", "n"]
32 x = x.lower()
33 if x in positives:
34 return True
35 elif x in negatives:
36 return False
37 else:
38 raise ValueError("Unknown option %s" % x)
39
40defaults = Configuration({
41 'output': '',
42 'header': '/etc/logparse/header.html',
43 'css': '/etc/logparse/main.css',
44 'linewidth': 80,
45 'embed-styles': False,
46 'plain': False,
47 'overwrite': False,
48 'title': logparse.__name__,
49 'maxlist': 10,
50 'maxcmd': 6,
51 'resolve-domains': 'fqdn',
52 'mail': {
53 'to': '',
54 'from': '',
55 'subject': 'logparse from $hostname$',
56 'mailbin': '/usr/bin/mail',
57 },
58 'rotate': False,
59 'verbose': False,
60 'quiet': False,
61 'hddtemp': {
62 'drives': ['/dev/sda'],
63 'host': '127.0.0.1',
64 'separator': '|',
65 'timeout': 10,
66 'port': 7634,
67 'show-model': False,
68 },
69 'apache': {
70 'resolve-domains': '',
71 },
72 'sshd': {
73 'resolve-domains': '',
74 },
75 'smbd': {
76 'resolve-domains': '',
77 },
78 'httpd': {
79 'resolve-domains': '',
80 },
81 'du': {
82 'paths': ['/', '/etc', '/home'],
83 'force-write': False,
84 },
85 'hostname-path': '/etc/hostname',
86 'parsers': {},
87 'ignore-parsers': {},
88 'logs': {
89 'auth': '/var/log/auth.log',
90 'cron': '/var/log/cron.log',
91 'cpuinfo': '/proc/cpuinfo',
92 'meminfo': '/proc/meminfo',
93 'sys': '/var/log/syslog',
94 'smb': '/var/log/samba',
95 'zfs': '/var/log/zpool.log',
96 'alloc': '/var/log/du.log',
97 'postfix': '/var/log/mail.log',
98 'httpd': '/var/log/apache2'
99 }
100})
101
102def verify(raw_dict, defaults):
103 for key, value in raw_dict.items():
104 if key in defaults: # valid key
105 logger.debug("Found valid key {0} with value {1}".format(key, value))
106 if (isinstance(value, dict)):
107 verify(value, defaults[key]) # recurse nested dictionaries
108
109 else: # invalid key
110 logger.warning("Invalid key {0} with value {1}".format(key, value))
111
112def loadconf(argparser, configfile = "/etc/logparse/logparse.conf"):
113 logger.debug("Getting config from {0}".format(configfile))
114 try:
115 raw_dict = yaml.safe_load(open(configfile))
116 # verify fields
117 verify(raw_dict, defaults)
118 prefs = defaults
119 for value in raw_dict:
120 if(isinstance(raw_dict[value], dict)):
121 for key in raw_dict[value].items():
122 logger.debug("Inserting key {0} with value {1}".format(key[0], key[1]))
123 if not value in prefs:
124 prefs[value] = {}
125 prefs[value][key[0]] = key[1]
126 else:
127 prefs[value] = raw_dict[value]
128 if argparser.parse_args().to is not None:
129 prefs['mail']['to'] = argparser.parse_args().to
130 if not prefs['mail']['to']:
131 logger.info("No recipient address provided, outputting to stdout")
132 else:
133 logger.info("Email will be sent to " + prefs['mail']['to'])
134 return prefs
135 except Exception as e:
136 logger.warning("Error processing config: " + str(e))