Exemple #1
0
def get_effective_service_level() -> ServiceState:
    """Get the service level that applies to the current service.
    This can only be used within check functions, not during discovery nor parsing."""
    config_cache = _config.get_config_cache()
    service_level = config_cache.service_level_of_service(host_name(), service_description())
    if service_level is not None:
        return service_level

    service_level = config_cache.get_host_config(host_name()).service_level
    if service_level is not None:
        return service_level

    return 0
Exemple #2
0
def get_agent_data_time():
    # type: () -> Optional[float]
    """Use this function to get the age of the agent data cache file
    of tcp or snmp hosts or None in case of piggyback data because
    we do not exactly know the latest agent data. Maybe one time
    we can handle this. For cluster hosts an exception is raised."""
    return _agent_cache_file_age(host_name(), check_type())
Exemple #3
0
def check_levels(value: Union[int, float],
                 dsname: Union[None, MetricName],
                 params: Any,
                 unit: str = "",
                 factor: Union[int, float] = 1.0,
                 scale: Union[int, float] = 1.0,
                 statemarkers: bool = False,
                 human_readable_func: Optional[Callable] = None,
                 infoname: Optional[str] = None,
                 boundaries: Optional[Tuple] = None) -> ServiceCheckResult:
    """Generic function for checking a value against levels

    This also supports predictive levels.

    value:   currently measured value
    dsname:  name of the datasource in the RRD that corresponds to this value
             or None in order to skip perfdata
    params:  None or Tuple(None, None) -> no level checking.
             Tuple variants with non-None values:
             Tuple[warn_upper, crit_upper] -> upper level checking only.
             Tuple[warn_upper, crit_upper, warn_lower, crit_lower]
             -> upper and lower level checking.
             If a Dict is passed to check_levels, predictive levels are used
             automatically. The following constellations are possible:
             Dict containing "lower" as key -> lower level checking.
             Dict containing "upper" or "levels_upper_min" as key -> upper level checking.
             Dict containing "lower" and "upper"/"levels_upper_min" as key ->
             lower and upper level checking.
    unit:    unit to be displayed in the plugin output.
             Be aware: if a (builtin) human_readable_func is stated which already
             provides a unit info, then this unit is not necessary. An additional
             unit info is useful if a rate is calculated, eg.
                unit="/s",
                human_readable_func=get_bytes_human_readable,
             results in 'X B/s'.
    factor:  the levels are multiplied with this factor before applying
             them to the value. This is being used for the CPU load check
             currently. The levels here are "per CPU", so the number of
             CPUs is used as factor.
    scale:   Scale of the levels in relation to "value" and the value in the RRDs.
             For example if the levels are specified in GB and the RRD store KB, then
             the scale is 1024*1024.
    human_readable_func: Single argument function to present in a human readable fashion
                         the value. Builtin human_readable-functions already provide a unit:
                         - get_percent_human_readable
                         - get_age_human_readable
                         - get_bytes_human_readable
                         - get_filesize_human_readable
                         - get_nic_speed_human_readable
                         - get_timestamp_human_readable
                         - get_relative_date_human_readable
    infoname: Perf value name for infotext like a title.
    boundaries: Add minimum and maximum to performance data.
    """
    if unit.startswith('/'):
        unit_info: str = unit
    elif unit:
        unit_info = " %s" % unit
    else:
        unit_info = ""

    if human_readable_func is None:
        human_readable_func = lambda x: "%.2f" % (x / scale)

    def scale_value(v: Union[None, int, float]) -> Union[None, int, float]:
        if v is None:
            return None
        return v * factor * scale

    infotext = "%s%s" % (human_readable_func(value), unit_info)
    if infoname:
        infotext = "%s: %s" % (infoname, infotext)

    # {}, (), None, (None, None), (None, None, None, None) -> do not check any levels
    if not params or set(params) <= {None}:
        # always add warn/crit, because the call-site may not know it passed None,
        # and therefore expect a quadruple.
        perf = _build_perfdata(dsname, value, scale_value, (None, None), boundaries)
        return 0, infotext, perf

    # Pair of numbers -> static levels
    if isinstance(params, tuple):
        levels = tuple(scale_value(v) for v in _normalize_levels(params))
        ref_value = None

    # Dictionary -> predictive levels
    else:
        if not dsname:
            raise TypeError("Metric name is empty/None")

        try:
            ref_value, levels = _prediction.get_levels(host_name(),
                                                       service_description(),
                                                       dsname,
                                                       params,
                                                       "MAX",
                                                       levels_factor=factor * scale)
            if ref_value:
                predictive_levels_msg = "predicted reference: %s" % human_readable_func(ref_value)
            else:
                predictive_levels_msg = "no reference for prediction yet"

        except MKGeneralException as e:
            ref_value = None
            levels = (None, None, None, None)
            predictive_levels_msg = "no reference for prediction (%s)" % e

        except Exception as e:
            if _debug.enabled():
                raise
            return 3, "%s" % e, []

        if predictive_levels_msg:
            infotext += " (%s)" % predictive_levels_msg

    state, levelstext = _do_check_levels(value, levels, human_readable_func, unit_info)
    infotext += levelstext
    if statemarkers:
        infotext += state_markers[state]

    perfdata = _build_perfdata(dsname, value, scale_value, levels, boundaries, ref_value)

    return state, infotext, perfdata
Exemple #4
0
def check_levels_predictive(
    value: float,
    *,
    levels: Dict[str, Any],
    metric_name: str,
    render_func: Optional[Callable[[float], str]] = None,
    label: Optional[str] = None,
    boundaries: Optional[Tuple[Optional[float], Optional[float]]] = None,
) -> Generator[Union[Result, Metric], None, None]:
    """Generic function for checking a value against levels.

    Args:

        value:        Currently measured value
        levels:       Predictive levels. These are used automatically.
                      Lower levels are imposed if the passed dictionary contains "lower"
                      as key, upper levels are imposed if it contains "upper" or
                      "levels_upper_min" as key.
                      If value is lower/higher than these, the service goes to **WARN**
                      or **CRIT**, respecively.
        metric_name:  Name of the datasource in the RRD that corresponds to this value
        render_func:  Single argument function to convert the value from float into a
                      human readable string.
                      readable fashion
        label:        Label to prepend to the output.
        boundaries:   Minimum and maximum to add to the metric.

    """
    if render_func is None:
        render_func = "%.2f".format

    # validate the metric name, before we can get the levels.
    Metric.validate_name(metric_name)

    try:
        ref_value, levels_tuple = cmk.base.prediction.get_levels(
            check_api_utils.host_name(),
            check_api_utils.service_description(),
            metric_name,
            levels,
            "MAX",
        )
        if ref_value:
            predictive_levels_msg = " (predicted reference: %s)" % render_func(ref_value)
        else:
            predictive_levels_msg = " (no reference for prediction yet)"

    except MKGeneralException as e:
        ref_value = None
        levels_tuple = (None, None, None, None)
        predictive_levels_msg = " (no reference for prediction: %s)" % e

    except Exception as e:
        if cmk.utils.debug.enabled():
            raise
        yield Result(state=State.UNKNOWN, summary="%s" % e)
        return

    levels_upper = (None if levels_tuple[0] is None or levels_tuple[1] is None else
                    (levels_tuple[0], levels_tuple[1]))

    levels_lower = (None if levels_tuple[2] is None or levels_tuple[3] is None else
                    (levels_tuple[2], levels_tuple[3]))

    value_state, levels_text = _do_check_levels(value, levels_upper, levels_lower, render_func)

    if label:
        info_text = "%s: %s%s" % (label, render_func(value), predictive_levels_msg)
    else:
        info_text = "%s%s" % (render_func(value), predictive_levels_msg)

    yield Result(state=value_state, summary=info_text + levels_text)
    yield Metric(metric_name, value, levels=levels_upper, boundaries=boundaries)
    if ref_value:
        yield Metric("predict_%s" % metric_name, ref_value)
Exemple #5
0
def check_levels_predictive(
        value,  # type: float
        _sentinel=_SENTINEL,  # type: Any # enforce keyword usage, remove with CMK-3983 # *,
        levels=None,  # tpye: Optional[Dict[str, Any]] # will be mandatory CMK-3983
        metric_name=None,  # type: Optional[str] # will be mandatory CMK-3983
        render_func=None,  # type: Optional[Callable[[float], str]]
        label=None,  # type: Optional[str]
        boundaries=None,  # type: Optional[Tuple[Optional[float], Optional[float]]]
):
    # type: (...) -> Generator[Union[Result, Metric], None, None]
    """Generic function for checking a value against levels.

    :param value:        Currently measured value
    :param levels:       Predictive levels. These are used automatically.
                         Lower levels are imposed if the passed dictionary contains "lower"
                         as key, upper levels are imposed if it contains "upper" or
                         "levels_upper_min" as key.
                         If value is lower/higher than these, the service goes to **WARN**
                         or **CRIT**, respecively.
    :param metric_name:  Name of the datasource in the RRD that corresponds to this value
    :param render_func:  Single argument function to convert the value from float into a
                         human readable string.
                         readable fashion
    :param label:        Label to prepend to the output.
    :param boundaries:   Minimum and maximum to add to the metric.
    """
    # TODO (mo): unhack this CMK-3983
    if _sentinel is not _SENTINEL:
        raise TypeError(
            "check_levels_predictive only accepts one positional argument")
    if levels is None:
        raise TypeError("'levels' must not be None")
    if metric_name is None:
        raise TypeError("'metric_name' must not be None")

    if render_func is None:
        render_func = "%.2f".format

    # validate the metric name, before we can get the levels.
    Metric.validate_name(metric_name)

    try:
        ref_value, levels_tuple = cmk.base.prediction.get_levels(
            check_api_utils.host_name(),
            check_api_utils.service_description(),
            metric_name,
            levels,
            "MAX",
        )
        if ref_value:
            predictive_levels_msg = " (predicted reference: %s)" % render_func(
                ref_value)
        else:
            predictive_levels_msg = " (no reference for prediction yet)"

    except MKGeneralException as e:
        ref_value = None
        levels_tuple = (None, None, None, None)
        predictive_levels_msg = " (no reference for prediction: %s)" % e

    except Exception as e:
        if cmk.utils.debug.enabled():
            raise
        yield Result(state=state.UNKNOWN, summary="%s" % e)
        return

    levels_upper = (None if levels_tuple[0] is None or levels_tuple[1] is None
                    else (levels_tuple[0], levels_tuple[1]))

    levels_lower = (None if levels_tuple[2] is None or levels_tuple[3] is None
                    else (levels_tuple[2], levels_tuple[3]))

    value_state, levels_text = _do_check_levels(value, levels_upper,
                                                levels_lower, render_func)

    if label:
        info_text = "%s: %s%s" % (label, render_func(value),
                                  predictive_levels_msg)
    else:
        info_text = "%s%s" % (render_func(value), predictive_levels_msg)

    yield Result(state=value_state, summary=info_text + levels_text)
    yield Metric(metric_name,
                 value,
                 levels=levels_upper,
                 boundaries=boundaries)
    if ref_value:
        Metric("predict_%s" % metric_name, ref_value)