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
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(metric_name, value) try: ref_value, levels_tuple = cmk.base.prediction.get_levels( plugin_contexts.host_name(), plugin_contexts.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)
def get_agent_data_time() -> 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())
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