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
|
#!@@GOODSH@@
# -*- sh -*-
: << =cut
=head1 NAME
cpuspeed - Plugin to monitor CPU speed
=head1 APPLICABLE SYSTEMS
Linux systems with a working CPU speed governor/stats kernel module
that can be accessed through the /sys filesystem.
=head1 CONFIGURATION
None needed by default.
You can set one environment variable to modify the plugins behaviour:
[cpuspeed]
env.scaleto100 yes
Show the frequency as a percentage instead of absolute frequency.
If set the "yes" the plugin sets up a CDEF to change the speed in Hz
to percent.
If you set or unset this the whole time series will be shown in the
same way, either as Hz or percent (as the graphs are updated).
=head1 INTERPRETATION
The plugin supports two sources of information.
The optimal source of information is the "acpi-cpufreq" kernel module.
It provides access to the accumulated time a CPU spent in a specific
speed state (see /sys/devices/system/cpu/*/cpufreq/stats/time_in_state).
This value is fine-grained and represents the *average* CPU speed for
every data collection period.
This data is available only for non-Intel CPUs.
An alternative (sub-optimal) source of information is provided by the
"intel_pstate" driver (typically built into a kernel).
This driver delivers only *instant* information about the CPU speed
(at the time of the munin data collection). This is not necessarily
representative for the real CPU speed history.
The "pstate" driver conflicts with "acpi-cpufreq". Thus hosts with an
Intel CPU are usually stuck with "intel_pstate" as a less optimal
source of frequency information.
=head1 BUGS
Nah.
=head1 AUTHOR
Nicolai Langfeldt
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
. "$MUNIN_LIBDIR/plugins/plugin.sh"
scaleto100=${scaleto100:-no}
ACPI_CPUFREQ_INDICATOR_FILENAME=/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
INTEL_PSTATE_INDICATOR_FILENAME=/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
if [ "$1" = "autoconf" ]; then
if [ -r "$ACPI_CPUFREQ_INDICATOR_FILENAME" ]; then
# "acpi-cpufreq" is available
echo yes
elif [ -r "$INTEL_PSTATE_INDICATOR_FILENAME" ]; then
# the "intel_pstate" driver is available (no averaging, but at least snapshot values)
echo yes
else
echo "no (neither $ACPI_CPUFREQ_INDICATOR_FILENAME nor $INTEL_PSTATE_INDICATOR_FILENAME is readable)"
fi
exit 0
fi
if [ "$1" = "config" ]; then
echo "graph_title CPU frequency scaling"
echo "graph_args --base 1000"
echo "graph_category system"
if [ "$scaleto100" = "yes" ]; then
echo "graph_vlabel %"
echo "graph_scale no"
else
echo "graph_vlabel Hz"
fi
# the visualized data depends on the available data source
if [ -r "$ACPI_CPUFREQ_INDICATOR_FILENAME" ]; then
graph_info="This graph shows the average running speed of each CPU."
field_type="DERIVE"
elif [ -r "$INTEL_PSTATE_INDICATOR_FILENAME" ]; then
graph_info="This graph shows the current speed of the CPU at the time of the data retrieval (not its average). This is a limitiation of the 'intel_pstate' driver."
field_type="GAUGE"
else
graph_info="The properties of this data source are not documented."
field_type="DERIVE"
fi
echo "graph_info $graph_info"
for c in /sys/devices/system/cpu/cpu[0-9]*; do
if [ ! -r "$c/cpufreq/stats/time_in_state" ] && [ ! -r "$c/cpufreq/scaling_cur_freq" ]; then
continue
fi
N=${c##*/cpu}
echo "cpu$N.label CPU $N"
echo "cpu$N.type $field_type"
if [ -r "$c/cpufreq/cpuinfo_max_freq" ]; then
MAXHZ=$(cat "$c/cpufreq/cpuinfo_max_freq")
# Adding 10% to $MAXHZ, to cope with polling jitters
# See bug D#615957
MAXHZ=$(( MAXHZ + MAXHZ / 10 ))
echo "cpu$N.max $MAXHZ"
if [ "$scaleto100" = "yes" ]; then
echo "cpu$N.cdef cpu$N,1000,*,$MAXHZ,/"
else
echo "cpu$N.cdef cpu$N,1000,*"
fi
fi
if [ -r "$c/cpufreq/cpuinfo_min_freq" ]; then
MINHZ=$(cat "$c/cpufreq/cpuinfo_min_freq")
echo "cpu$N.min $MINHZ"
fi
print_warning "cpu$N"
print_critical "cpu$N"
done | sort -V
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" != 1 ]; then exit 0; fi
fi
for c in /sys/devices/system/cpu/cpu[0-9]*; do
N=${c##*/cpu}
if [ -r "$c/cpufreq/stats/time_in_state" ]; then
value=$(awk '{ cycles += $1 * $2 } END { printf("%.0f", cycles / 100); }' "$c/cpufreq/stats/time_in_state")
elif [ -r "$c/cpufreq/scaling_cur_freq" ]; then
value=$(cat "$c/cpufreq/scaling_cur_freq")
else
continue
fi
printf 'cpu%d.value %s\n' "$N" "$value"
done
|