/usr/lib/python2.7/dist-packages/nagiosplugin/result.py is in python-nagiosplugin 1.2.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | # Copyright (c) gocept gmbh & co. kg
# See also LICENSE.txt
"""Outcomes from evaluating metrics in contexts.
The :class:`Result` class is the base class for all evaluation results.
The :class:`Results` class (plural form) provides a result container with
access functions and iterators.
Plugin authors may create their own :class:`Result` subclass to
accomodate for special needs. :class:`~.context.Context` constructors
accept custom Result subclasses in the `result_cls` parameter.
"""
import collections
import numbers
import warnings
class Result(collections.namedtuple('Result', 'state hint metric')):
"""Evaluation outcome consisting of state and explanation.
A Result object is typically emitted by a
:class:`~nagiosplugin.context.Context` object and represents the
outcome of an evaluation. It contains a
:class:`~nagiosplugin.state.ServiceState` as well as an explanation.
Plugin authors may subclass Result to implement specific features.
"""
def __new__(cls, state, hint=None, metric=None):
"""Creates a Result object.
:param state: state object
:param hint: reason why this result arose
:param metric: reference to the
:class:`~nagiosplugin.metric.Metric` from which this result
was derived
"""
return tuple.__new__(cls, (state, hint, metric))
def __str__(self):
"""Textual result explanation.
The result explanation is taken from :attr:`metric.description`
(if a metric has been passed to the constructur), followed
optionally by the value of :attr:`hint`. This method's output
should consist only of a text for the reason but not for the
result's state. The latter is rendered independently.
:returns: result explanation or empty string
"""
if self.metric and self.metric.description:
desc = self.metric.description
else:
desc = None
if self.hint and desc:
return '{0} ({1})'.format(desc, self.hint)
elif self.hint:
return self.hint
elif desc:
return desc
else:
return ''
@property
def resource(self):
"""Reference to the resource used to generate this result."""
if self.metric:
return self.metric.resource
@property
def context(self):
"""Reference to the metric used to generate this result."""
if self.metric:
return self.metric.contextobj
class ScalarResult(Result): # pragma: no cover
"""Special-case result for evaluation in a ScalarContext.
DEPRECATED: use Result instead.
"""
def __new__(cls, state, hint, metric):
warnings.warn('ScalarResult is deprecated, use Result instead!',
DeprecationWarning)
return tuple.__new__(cls, (state, hint, metric))
class Results:
"""Container for result sets.
Basically, this class manages a set of results and provides
convenient access methods by index, name, or result state. It is
meant to make queries in :class:`~.summary.Summary`
implementations compact and readable.
The constructor accepts an arbitrary number of result objects and
adds them to the container.
"""
def __init__(self, *results):
self.results = []
self.by_state = collections.defaultdict(list)
self.by_name = {}
if results:
self.add(*results)
def add(self, *results):
"""Adds more results to the container.
Besides passing :class:`Result` objects in the constructor,
additional results may be added after creating the container.
:raises ValueError: if `result` is not a :class:`Result` object
"""
for result in results:
if not isinstance(result, Result):
raise ValueError(
'trying to add non-Result to Results container', result)
self.results.append(result)
self.by_state[result.state].append(result)
try:
self.by_name[result.metric.name] = result
except AttributeError:
pass
return self
def __iter__(self):
"""Iterates over all results.
The iterator is sorted in order of decreasing state
significance (unknown > critical > warning > ok).
:returns: result object iterator
"""
for state in reversed(sorted(self.by_state)):
for result in self.by_state[state]:
yield result
def __len__(self):
"""Number of results in this container."""
return len(self.results)
def __getitem__(self, item):
"""Access result by index or name.
If *item* is an integer, the *item*\ th element in the
container is returned. If *item* is a string, it is used to
look up a result with the given name.
:returns: :class:`Result` object
:raises KeyError: if no matching result is found
"""
if isinstance(item, numbers.Number):
return self.results[item]
return self.by_name[item]
def __contains__(self, name):
"""Tests if a result with given name is present.
:returns: boolean
"""
return name in self.by_name
@property
def most_significant_state(self):
"""The "worst" state found in all results.
:returns: :obj:`~nagiosplugin.state.ServiceState` object
:raises ValueError: if no results are present
"""
return max(self.by_state.keys())
@property
def most_significant(self):
"""Returns list of results with most significant state.
From all results present, a subset with the "worst" state is
selected.
:returns: list of :class:`Result` objects or empty list if no
results are present
"""
try:
return self.by_state[self.most_significant_state]
except ValueError:
return []
@property
def first_significant(self):
"""Selects one of the results with most significant state.
:returns: :class:`Result` object
:raises IndexError: if no results are present
"""
return self.most_significant[0]
|