"""
LogrotateConfAll - Combiner for logrotate configuration
=======================================================
Combiner for accessing all the logrotate configuration files. It collects all
LogrotateConf generated from each single logrotate configuration file.
There may be multiple logrotate configuration, and the main configuration file is
``/etc/logrotate.conf``. Only the options defined in this file are global
options, and all other options (if there are) will be discarded.
"""
import operator
import os
from fnmatch import fnmatch
from insights.core import ConfigCombiner
from insights.core.plugins import combiner
from insights.parsers.logrotate_conf import LogrotateConf, LogRotateConfPEG
from insights.parsr.query import eq
[docs]
@combiner(LogrotateConf)
class LogrotateConfAll(object):
"""
Class for combining all the logrotate configuration files.
Sample files::
# /etc/logrotate.conf:
compress
rotate 7
/var/log/messages {
rotate 5
weekly
postrotate
/sbin/killall -HUP syslogd
endscript
}
# /etc/logrotate.d/httpd
"/var/log/httpd/access.log" /var/log/httpd/error.log {
rotate 5
mail www@my.org
size=100k
sharedscripts
postrotate
/sbin/killall -HUP httpd
endscript
}
# /etc/logrotate.d/newscrit
/var/log/news/*.crit {
monthly
rotate 2
olddir /var/log/news/old
missingok
postrotate
kill -HUP `cat /var/run/inn.pid`
endscript
nocompress
}
Examples:
>>> all_lrt.global_options
['compress', 'rotate', 'include']
>>> all_lrt['rotate']
'7'
>>> '/var/log/httpd/access.log' in all_lrt.log_files
True
>>> all_lrt['/var/log/httpd/access.log']['rotate']
'5'
>>> all_lrt.configfile_of_logfile('/var/log/news/olds.crit')
'/etc/logrotate.d/newscrit'
>>> all_lrt.options_of_logfile('/var/log/httpd/access.log')['mail']
'www@my.org'
Attributes:
data(dict): All parsed options and log files are stored in this
dictionary
global_options(list): List of global options defined in
``/etc/logrotate.conf``
log_files(list): List of log files in all logrotate configuration files
"""
def __init__(self, lrt_conf):
self.data = {}
self.global_options = []
self.log_files = []
self._file_map = {}
self.include = None
for lrt in lrt_conf:
if lrt.file_path == "/etc/logrotate.conf":
self.data.update(lrt.data)
self.log_files.extend(lrt.log_files)
self._file_map[lrt.file_path] = lrt.log_files
self.global_options = lrt.options
if 'include' in lrt.options and lrt.data['include'].startswith('/etc/logrotate.d'):
self.include = lrt.data['include']
if self.include:
for lrt in lrt_conf:
if lrt.file_path == self.include or (lrt.file_path.startswith(self.include) and len(lrt.file_path.split(self.include)[-1].lstrip('/').split('/')) == 1) or fnmatch(lrt.file_path, self.include):
self.data.update(lrt.data)
self.log_files.extend(lrt.log_files)
self._file_map[lrt.file_path] = lrt.log_files
def __contains__(self, item):
return (item in self.global_options or
any(fnmatch(item, f) for f in self.log_files))
def __getitem__(self, item):
if item in self.global_options:
return self.data[item]
return self.data.get(self._get_match_logfile(item))
def _get_match_logfile(self, log_file, file_list=[]):
file_list = self.log_files if not file_list else file_list
for f in file_list:
if fnmatch(log_file, f):
return f
[docs]
def options_of_logfile(self, log_file):
"""
Get the options of ``log_file``.
Parameters:
log_file(str): The log files need to check.
Returns:
dict: Dictionary contains the options of ``log_file``. None when no
such ``log_file``.
"""
return self.data.get(self._get_match_logfile(log_file))
[docs]
def configfile_of_logfile(self, log_file):
"""
Get the configuration file path in which the ``log_file`` is configured.
Parameters:
log_file(str): The log files need to check.
Returns:
dict: The configuration file path of ``log_file``. None when no
such ``log_file``.
"""
for f, lfs in self._file_map.items():
for file in lfs:
if fnmatch(log_file, file):
return f
[docs]
@combiner(LogRotateConfPEG)
class LogRotateConfTree(ConfigCombiner):
"""
Exposes logrotate configuration through the parsr query interface.
See the :py:class:`insights.core.ConfigComponent` class for example usage.
"""
def __init__(self, confs):
include = eq("include")
main_file = "logrotate.conf"
super(LogRotateConfTree, self).__init__(confs, main_file, include)
@property
def conf_path(self):
return os.path.dirname(self.main.file_path)
def find_matches(self, confs, pattern):
results = []
for c in confs:
if c.file_path.startswith(pattern) and len(c.file_path.split(pattern)[-1].lstrip('/').split('/')) == 1:
results.append(c)
elif fnmatch(c.file_path, pattern):
results.append(c)
return sorted(results, key=operator.attrgetter("file_name"))