Skip to content
Permalink
Browse files

Added new internal function for displaying correct precision in Perf-…

…O-Meters
  • Loading branch information
MathiasKettner committed Feb 8, 2015
1 parent 440a450 commit 3fc5ac780d403ffd5fcd9a2df73b02d82221b810
Showing with 192 additions and 22 deletions.
  1. +2 −2 checks/adva_fsp_current
  2. +123 −2 web/htdocs/metrics.py
  3. +63 −15 web/plugins/metrics/check_mk.py
  4. +4 −3 web/plugins/views/perfometer.py
@@ -36,8 +36,8 @@ def check_adva_fsp_current(item, _no_params, info):
for line in info:
if len(line) == 5 and line[4] == item:
current, high, power, descr = line[0:4]
current = float(current)/1000
high = float(high)/1000
current = float(current) / 1000.0
high = float(high) / 1000

infotext = "%.3f A (limit at %.3f A) at %s" % (current, high, descr)
perfdata = [ ("current", current, "", str(high), ) ]
@@ -52,6 +52,15 @@ def load_plugins():
loaded_with_language = current_language


# Definitions to be used in the actual metric declarations

KB = 1024
MB = 1024 * 1024
GB = 1024 * 1024 * 1024
TB = 1024 * 1024 * 1024 * 1024
PB = 1024 * 1024 * 1024 * 1024 * 1024


# Convert perf_data_string into perf_data, extract check_command
def parse_perf_data(perf_data_string, check_command=None):
parts = perf_data_string.split()
@@ -250,14 +259,23 @@ def get_perfometers(translated_metrics):
# have more and more Perf-O-Meter definitions.
def perfometer_possible(perfometer, translated_metrics):
perf_type, perf_args = perfometer

if perf_type == "logarithmic":
required = [ perf_args[0] ]
elif perf_type == "stacked":

elif perf_type == "linear":
required = perf_args[0]
if perf_args[1]:
required = required + [perf_args[1]] # Reference value for 100%
if perf_args[2]:
required = required + [perf_args[2]] # Labelling value

elif perf_type in ("stacked", "dual"):
for sub_perf in perf_args:
if not perfometer_possible(sub_perf, translated_metrics):
return False
return True

else:
raise MKInternalError(_("Undefined Perf-O-Meter type '%s'") % perf_type)

@@ -300,6 +318,70 @@ def drop_dotzero(v):
else:
return t


def frexp10(x):
exp = int(math.log10(x))
mantissa = x / 10**exp
if mantissa < 1:
mantissa *= 10
exp -= 1
return mantissa, exp

# Render a physical value witha precision of p
# digits. Use K (kilo), M (mega), m (milli), µ (micro)
# p is the number of non-zero digits - not the number of
# decimal places.
# Examples for p = 3:
# a: 0.0002234 b: 4,500,000 c: 137.56
# Result:
# a: 223 µ b: 4.50 M c: 138

def physical_precision(v, precision, unit):
if v == 0:
return "%%.%df" % (precision - 1) % v
elif v < 0:
return "-" + physical_precision(-v, precision)

# Splitup in mantissa (digits) an exponent to the power of 10
# -> a: (2.23399998, -2) b: (4.5, 6) c: (1.3756, 2)
mantissa, exponent = frexp10(float(v))

# Round the mantissa to the required number of digits
# -> a: 2.23 b: 4.5 c: 1.38
mant_rounded = round(mantissa, precision-1) * 10**exponent

# Choose a power where no artifical zero (due to rounding) needs to be
# placed left of the decimal point.
scale_symbols = {
-4 : "p",
-3 : "n",
-2 : u"µ",
-1 : "m",
0 : "",
1 : "K",
2 : "M",
3 : "G",
4 : "T",
5 : "P",
}
scale = 0

while exponent < 0:
scale -= 1
exponent += 3

# scale, exponent = divmod(exponent, 3)
places_before_comma = exponent + 1
places_after_comma = precision - places_before_comma
while places_after_comma < 0:
scale += 1
exponent -= 3
places_before_comma = exponent + 1
places_after_comma = precision - places_before_comma
value = mantissa * 10**exponent
return u"%%.%df %%s%%s" % places_after_comma % (value, scale_symbols[scale], unit)


def metricometer_logarithmic(value, half_value, base, color):
# Negative values are printed like positive ones (e.g. time offset)
value = abs(float(value))
@@ -326,7 +408,7 @@ def build_perfometer(perfometer, translated_metrics):
label = metric_to_text(metric)
stack = [ metricometer_logarithmic(metric["value"], median, exponent, metric["color"]) ]

elif perfometer_type == "stacked":
elif perfometer_type == "linear":
entry = []
stack = [entry]

@@ -362,6 +444,45 @@ def build_perfometer(perfometer, translated_metrics):
unit = get_unit(metrics_expressions[0])
label = unit["render"](summed)

elif perfometer_type == "stacked":
stack = []
labels = []
for sub_perf in definition:
sub_label, sub_stack = build_perfometer(sub_perf, translated_metrics)
stack.append(sub_stack[0])
if sub_label:
labels.append(sub_label)
if labels:
label = " / ".join(labels)
else:
label = ""
return label, stack

elif perfometer_type == "dual":
labels = []
if len(definition) != 2:
raise MKInternalError(_("Perf-O-Meter of type 'dual' must contain exactly two definitions, not %d") % len(definition))

content = []
for nr, sub_perf in enumerate(definition):
sub_label, sub_stack = build_perfometer(sub_perf, translated_metrics)
if len(sub_stack) != 1:
raise MKInternalError(_("Perf-O-Meter of type 'dual' must only contain plain Perf-O-Meters"))

half_stack = [ (value/2, color) for (value, color) in sub_stack[0] ]
if nr == 0:
half_stack.reverse()
content += half_stack
if sub_label:
labels.append(sub_label)

if labels:
label = " / ".join(labels)
else:
label = ""
return label, [ content ]


else:
raise MKInternalError(_("Unsupported Perf-O-Meter type '%s'") % perfometer_type)

@@ -26,12 +26,6 @@

# Metric definitions for Check_MK's checks

KB = 1024
MB = 1024 * 1024
GB = 1024 * 1024 * 1024
TB = 1024 * 1024 * 1024 * 1024
PB = 1024 * 1024 * 1024 * 1024 * 1024

# .--Units---------------------------------------------------------------.
# | _ _ _ _ |
# | | | | |_ __ (_) |_ ___ |
@@ -63,8 +57,8 @@
}

# Similar as %, but value ranges from 0.0 ... 1.0
unit_info["100%"] = {
"title" : _("%"),
unit_info["ratio"] = {
"title" : _("Ratio"),
"symbol" : _("%"),
"render" : lambda v: "%s%%" % drop_dotzero(100.0 * v),
}
@@ -93,6 +87,18 @@
"render" : lambda v: "%s %s" % (drop_dotzero(v), _(u"°C")),
}

unit_info["a"] = {
"title" : _("Current (Amperage)"),
"symbol" : _("A"),
"render" : lambda v: physical_precision(v, 3, _("A")),
}

unit_info["dbm"] = {
"title" : _("Decibel-milliwatts"),
"symbol" : _("dBm"),
"render" : lambda v: "%s %s" % (drop_dotzero(v), _("dBm")),
}


#.
# .--Metrics-------------------------------------------------------------.
@@ -211,6 +217,25 @@
"color" : "#9a52bf",
}

metric_info["input_signal_power_dbm"] = {
"title" : _("Input Power"),
"unit" : "dbm",
"color" : "#20c080",
}

metric_info["output_signal_power_dbm"] = {
"title" : _("Output Power"),
"unit" : "dbm",
"color" : "#2080c0",
}

metric_info["current"] = {
"title" : _("Electrical Current"),
"unit" : "a",
"color" : "#ffb030",
}



#.
# .--Checks--------------------------------------------------------------.
@@ -298,6 +323,7 @@
check_metrics["check_mk-carel_sensors"] = {}
check_metrics["check_mk-netscaler_health.temp"] = {}
check_metrics["check_mk-kentix_temp"] = {}
check_metrics["check_mk-emc_datadomain_temps"] = {}

check_metrics["check_mk-kernel"] = { "processes" : { "name" : "proc_creat", } }

@@ -311,6 +337,11 @@
check_metrics["check_mk-mbg_lantime_nb_state"] = { "offset" : { "name" : "time_offset", "scale" : 0.000001 }} # convert us -> sec
check_metrics["check_mk-systemtime"] = { "offset" : { "name" : "time_offset" }}

check_metrics["check_mk-adva_fsp_if"] = { "output_power" : { "name" : "output_signal_power_dbm" },
"input_power" : { "name" : "input_signal_power_dbm" }}

check_metrics["check_mk-adva_fsp_current"] = {}

#.
# .--Perf-O-Meters-------------------------------------------------------.
# | ____ __ ___ __ __ _ |
@@ -323,21 +354,38 @@
# | Definition of Perf-O-Meters |
# '----------------------------------------------------------------------'

perfometer_info.append(("stacked", ( ["execution_time"], 90.0, None)))
# Types of Perf-O-Meters:
# linear -> multiple values added from left to right
# logarithmic -> one value in a logarithmic scale
# dual -> two Perf-O-Meters next to each other, the first one from right to left
# stacked -> two Perf-O-Meters of type linear, logarithmic or dual, stack vertically
# The label of dual and stacked is taken from the definition of the contained Perf-O-Meters

perfometer_info.append(("linear", ( ["execution_time"], 90.0, None)))
perfometer_info.append(("stacked", [
( "logarithmic", ( "load1", 4.0, 2.0)),
( "linear", ( [ "load1:max", ], 16, None)) ]))
perfometer_info.append(("logarithmic", ( "load1", 4.0, 2.0)))
perfometer_info.append(("logarithmic", ( "temp", 40.0, 1.2)))
perfometer_info.append(("logarithmic", ( "ctxt", 1000.0, 2.0)))
perfometer_info.append(("logarithmic", ( "pgmajfault", 1000.0, 2.0)))
perfometer_info.append(("logarithmic", ( "proc_creat", 1000.0, 2.0)))
perfometer_info.append(("logarithmic", ( "threads", 400.0, 2.0)))
perfometer_info.append(("stacked", ( [ "user", "system", "io_wait" ], 100.0, None)))
perfometer_info.append(("stacked", ( [ "fs_used(%)" ], 100.0, None)))
perfometer_info.append(("stacked", ( [ "mem_used", "swap_used", "caches", "mem_free", "swap_free" ], None,
("mem_total,mem_used,swap_used,+,/", "100%"))))
perfometer_info.append(("stacked", ( [ "mem_used" ], "mem_total", None)))
perfometer_info.append(("stacked", ( [ "mem_used(%)" ], 100.0, None)))
perfometer_info.append(("linear", ( [ "user", "system", "io_wait" ], 100.0, None)))
perfometer_info.append(("linear", ( [ "fs_used(%)" ], 100.0, None)))
perfometer_info.append(("linear", ( [ "mem_used", "swap_used", "caches", "mem_free", "swap_free" ], None,
("mem_total,mem_used,swap_used,+,/", "ratio"))))
perfometer_info.append(("linear", ( [ "mem_used" ], "mem_total", None)))
perfometer_info.append(("linear", ( [ "mem_used(%)" ], 100.0, None)))
perfometer_info.append(("logarithmic", ( "time_offset", 1.0, 10.0)))

perfometer_info.append(("dual", [
( "logarithmic", ( "input_signal_power_dbm", 4, 2)),
( "logarithmic", ( "output_signal_power_dbm", 4, 2)),
]))

perfometer_info.append(("logarithmic", ( "current", 10, 4)))


#.
# .--Graphs--------------------------------------------------------------.
@@ -153,7 +153,7 @@ def paint_perfometer(row):

title, h = perf_painter(row, check_command, perf_data)
# Test code for optically detecting old-style Perf-O-Meters
if config.debug:
if True or config.debug:
title = '{ ' + title + ' }'

except Exception, e:
@@ -190,11 +190,12 @@ def render_metricometer(stack):
if len(stack) not in (1, 2):
raise MKGeneralException(_("Invalid Perf-O-Meter definition %r: only one or two entries are allowed") % stack)

h = ""
if len(stack) == 2:
h = '<div class="stacked">'
h += '<div class="stacked">'

for entry in stack:
h = '<table><tr>'
h += '<table><tr>'
for percentage, color in entry:
h += perfometer_td(percentage, color)
h += "</tr></table>"

0 comments on commit 3fc5ac7

Please sign in to comment.
You can’t perform that action at this time.