Yuvipanda has submitted this change and it was merged. Change subject: Extend Exim diamond collector for Tool Labs ......................................................................
Extend Exim diamond collector for Tool Labs - forked and extended existing exim collector - extended queue information - added paniclog information - moved sudo configuration to collector manifest - updated tool labs mail relay for new collector Bug: T96898 Change-Id: I1d0517e41d61201e7f6c9b85c116f952658f73a3 --- A modules/diamond/files/collector/extendedexim.py A modules/diamond/manifests/collector/extendedexim.pp M modules/toollabs/manifests/mailrelay.pp 3 files changed, 211 insertions(+), 11 deletions(-) Approvals: Yuvipanda: Verified; Looks good to me, approved diff --git a/modules/diamond/files/collector/extendedexim.py b/modules/diamond/files/collector/extendedexim.py new file mode 100644 index 0000000..87f63e8 --- /dev/null +++ b/modules/diamond/files/collector/extendedexim.py @@ -0,0 +1,173 @@ +# coding=utf-8 + +""" +Exim collector. Collects queue properties and paniclog size. + +Queue properties: + - queue.oldest: age of oldest e-mail in queue (seconds) + - queue.youngest: age of youngest e-mail in queue (seconds) + - queue.size: total size of the queue (bytes) + - queue.length: total number of e-mails in the queue + - queue.num_frozen: number of frozen e-mails in the queue + +Paniclog properties: + - paniclog.length: number of lines in /var/log/exim4/paniclog + +Queue length is retrieved from exim; the paniclog is read directly. +Both support the use of sudo, so diamond can run as unprivileged user. + +#### History +Based on EximCollector bundled with Diamond (collectors/exim/exim.py) +Extended by Merlijn van Deen <valhall...@arctus.nl> + +#### Dependencies + * /usr/sbin/exim + +""" + +import diamond.collector +import subprocess +import os +from datetime import timedelta +from collections import namedtuple +from diamond.collector import str_to_bool + + +class EximCollectorException(Exception): + pass + + +EximQueueLine = namedtuple('EximQueueLine', + ['age', 'size', 'mail_id', 'frozen']) + + +class ExtendedEximCollector(diamond.collector.Collector): + def get_default_config_help(self): + config_help = super(ExtendedEximCollector, self).get_default_config_help() # noqa + config_help.update({ + 'bin': 'The path to the exim binary', + 'use_sudo': 'Use sudo?', + 'sudo_cmd': 'Path to sudo', + 'sudo_user': 'User to sudo as', + }) + return config_help + + def get_default_config(self): + """ + Returns the default collector settings + """ + config = super(ExtendedEximCollector, self).get_default_config() + config.update({ + 'path': 'exim', + 'bin': '/usr/sbin/exim', + 'use_sudo': False, + 'sudo_cmd': '/usr/bin/sudo', + 'sudo_user': 'root', + }) + return config + + def _get_file(self, file): + if not str_to_bool(self.config['use_sudo']): + return open(file).read() + else: + command = [self.config['sudo_cmd'], "-u", self.config['sudo_user'], + "cat", file] + self.log.debug('Running %s' % (' '.join(command))) + try: + return subprocess.check_output( + command, + stderr=subprocess.STDOUT + ) + except subprocess.CalledProcessError as e: + raise IOError(e) + + def _get_queue(self): + if not os.access(self.config['bin'], os.X_OK): + raise EximCollectorException('exim not found') + + command = [self.config['bin'], '-bpr'] + + if str_to_bool(self.config['use_sudo']): + command = [ + self.config['sudo_cmd'], + '-u', + self.config['sudo_user'] + ] + command + self.log.debug('Running %s' % (' '.join(command))) + queue = subprocess.check_output(command) + + # remove empty lines + queue = [l.strip() for l in queue.split("\n")] + queue = [l for l in queue if l] + + # remove indented lines + queue = [l for l in queue if l[0] != " "] + + return queue + + def _parse_age(self, age): + postfix = age[-1] + if postfix == "m": + return timedelta(minutes=int(age[:-1])) + elif postfix == "h": + return timedelta(hours=int(age[:-1])) + elif postfix == "d": + return timedelta(days=int(age[:-1])) + elif postfix == "w": + return timedelta(weeks=int(age[:-1])) + + def _parse_size(self, size): + postfix = size[-1] + if postfix == "K": + return float(size[:-1]) * 1024 + elif postfix == "M": + return float(size[:-1]) * 1024 + else: + return float(size) + + def _parse_line(self, line): + parts = [x for x in line.split(" ") if x] + age = self._parse_age(parts[0]) + size = self._parse_size(parts[1]) + mail_id = parts[2] + frozen = "*** frozen ***" in line + + return EximQueueLine(age=age, size=size, + mail_id=mail_id, frozen=frozen) + + def collect_queue(self): + try: + queue = self._get_queue() + except EximCollectorException: + return + + parsed_queue = [self._parse_line(line) for line in queue] + + if parsed_queue: + oldest = max(l.age for l in parsed_queue) + youngest = min(l.age for l in parsed_queue) + size = sum(l.size for l in parsed_queue) + length = len(parsed_queue) + num_frozen = sum(l.frozen for l in parsed_queue) + else: + oldest = youngest = size = length = num_frozen = 0 + + self.publish('queue.oldest', oldest) + self.publish('queue.youngest', youngest) + self.publish('queue.size', size) + self.publish('queue.length', length) + self.publish('queue.num_frozen', num_frozen) + + def collect_paniclog(self): + try: + contents = self._get_file('/var/log/exim4/paniclog') + except IOError: + self.log.warning('Cannot open Exim paniclog!') + return + + num_lines = contents.count("\n") + self.publish('paniclog.length', num_lines) + + def collect(self): + self.collect_queue() + self.collect_paniclog() diff --git a/modules/diamond/manifests/collector/extendedexim.pp b/modules/diamond/manifests/collector/extendedexim.pp new file mode 100644 index 0000000..aff8d58 --- /dev/null +++ b/modules/diamond/manifests/collector/extendedexim.pp @@ -0,0 +1,37 @@ +# == Define: diamond::collector::extendedexim +# +# Exim collector. Collects queue properties and paniclog size. +# +# Queue properties: +# - queue.oldest: age of oldest e-mail in queue (seconds) +# - queue.youngest: age of youngest e-mail in queue (seconds) +# - queue.size: total size of the queue (bytes) +# - queue.length: total number of e-mails in the queue +# - queue.num_frozen: number of frozen e-mails in the queue +# +# Paniclog properties: +# - paniclog.length: number of lines in /var/log/exim4/paniclog + +include stdlib + +define diamond::collector::extendedexim( + $settings = {}, + $ensure = present, +) { + $default_settings = {'use_sudo' => 'true'} + $merged_settings = merge($default_settings, $settings) + + diamond::collector { 'ExtendedExim': + settings => $merged_settings, + source => 'puppet:///modules/diamond/collector/extendedexim.py', + ensure => $ensure, + } + + if str2bool($merged_settings[use_sudo]) { + sudo::user { 'diamond_sudo_for_exim': + user => 'diamond', + privileges => ['ALL=(root) NOPASSWD: /usr/sbin/exim, /bin/cat /var/log/exim4/paniclog'], + ensure => $ensure, + } + } +} diff --git a/modules/toollabs/manifests/mailrelay.pp b/modules/toollabs/manifests/mailrelay.pp index e68f01a..46e1b9c 100644 --- a/modules/toollabs/manifests/mailrelay.pp +++ b/modules/toollabs/manifests/mailrelay.pp @@ -62,15 +62,5 @@ notify => Service['exim4'], } - # Diamond user needs sudo to access exim - sudo::user { 'diamond_sudo_for_exim': - user => 'diamond', - privileges => ['ALL=(root) NOPASSWD: /usr/sbin/exim'] - } - - diamond::collector { 'Exim': - settings => { - use_sudo => 'true', # used in a template, not a puppet bool - } - } + diamond::collector::extendedexim { 'extended_exim_collector': } } -- To view, visit https://gerrit.wikimedia.org/r/206118 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1d0517e41d61201e7f6c9b85c116f952658f73a3 Gerrit-PatchSet: 10 Gerrit-Project: operations/puppet Gerrit-Branch: production Gerrit-Owner: Merlijn van Deen <valhall...@arctus.nl> Gerrit-Reviewer: Dzahn <dz...@wikimedia.org> Gerrit-Reviewer: Merlijn van Deen <valhall...@arctus.nl> Gerrit-Reviewer: Yuvipanda <yuvipa...@gmail.com> Gerrit-Reviewer: coren <mpellet...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits