File: cpuspeed.in

package info (click to toggle)
munin 2.0.76-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 7,064 kB
  • sloc: perl: 11,684; java: 1,924; sh: 1,632; makefile: 636; javascript: 365; python: 267
file content (162 lines) | stat: -rw-r--r-- 4,837 bytes parent folder | download | duplicates (2)
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