#!@@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 1

Show the frequency as a percentage instead of absolute frequency.  If
set 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 shows the average CPU speed in the measurement period as
represented by /sys/devices/system/cpu/*/cpufreq/stats/time_in_state.

This is a counter plugin and represents the average.  Many cpuspeed
plugins reports the "instant" CPU speed at the time the plugin runs.
This is not representative for this metric.

=head1 BUGS

Nah.

=head1 AUTHOR

Nicolai Langfeldt

=head1 LICENSE

GPLv2

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf

=cut

. $MUNIN_LIBDIR/plugins/plugin.sh

if [ "$1" = "autoconf" ]; then
    if [ -r /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state ] ; then
        echo yes
        exit 0
    else
        echo "no (missing /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state)"
        exit 0
    fi
fi


if [ "$1" = "config" ]; then
    echo graph_title CPU frequency scaling
    echo graph_args --base 1000
    echo graph_info This graph shows the average speeds at which the CPUs are running
    echo graph_category system

    if [ "$scaleto100" = "yes" ]; then
        echo "graph_vlabel %"
        echo "graph_scale no"
    else
        echo "graph_vlabel Hz"
    fi

    for c in /sys/devices/system/cpu/cpu[0-9]*; do
        N=${c##*/cpu}

        echo "cpu$N.label CPU $N"
        echo "cpu$N.type DERIVE"

	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
    exit 0;
fi

for c in /sys/devices/system/cpu/cpu[0-9]*; do
    N=${c##*/cpu}
    awk -v cpu=$N '{ cycles += $1 * $2 } 
               END { printf "cpu%d.value %.0f\n", cpu, cycles / 100; }' \
        $c/cpufreq/stats/time_in_state
done
