Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / lxc / lxc-multigraph @ 33b2f3ed

Historique | Voir | Annoter | Télécharger (10,2 ko)

1 4e321bbc Marc SCHAEFER
#!/bin/bash
2
# -*- sh -*-
3
4
: << =cut
5
6
=head1 NAME
7
8
lxc-multigraph - Plugin to monitor LXC containers (v2.0)
9
10
=head1 CONFIGURATION
11
12
  [lxc-multigraph]
13
    user root
14
15 9af96d2c Lars Kruse
    # The memory usage of containers are by default drawn as stacked area
16
    # charts.  Alternatively a non-stacked graph with lines can be configured.
17
    # Default: true
18
    #env.ram_display_stacked true
19 4e321bbc Marc SCHAEFER
20
    # lxc container path, default below
21
    #env.lxcpath /var/lib/lxc
22
23
    # exclude the following containers
24
    # (default none excluded)
25
    #env.exclude container1 container2
26
27
    # path where tasks sysfs files are stored,
28
    # set this if the various attempts in the
29
    # code don't work
30
    # (default none)
31
    #env.cgrouppath /sys/fs/cgroup/cpuacct/lxc/
32
33
=head1 INTERPRETATION
34
35
This plugin needs root privilege.
36
37
This plugin has been tested with lxc 3 and
38
lx2 (on Debian buster and Debian jessie,
39
respectively).
40
41
For the network graphs to work, you need
42
to have in every container's config file
43
a line defining the virtual network interface
44
path (else lxc will use a random name at
45
each container's start); see the lxc_netdev()
46
function below.
47
48
If using lxc 2, make sure you do not have cruft
49
in your container config files, you can test
50
it with:
51
   lxc-cgroup -o /dev/stdout -l INFO -n 104 cpuacct.usage
52
-- with 104 a valid lxc instance), if you
53
get a warning, fix the config file.
54
55 e91f7ecb Lars Kruse
For the logins graph, the "users" command is required in each
56
container.
57 4e321bbc Marc SCHAEFER
58
Tested on Debian buster and Debian jessie.
59
60 c0fe6dc3 Marc SCHAEFER
The double __ for values is for compatibility
61
with the previous implementation.
62
63 4e321bbc Marc SCHAEFER
=head1 AUTHOR
64
65
vajtsz vajtsz@gmail.com
66
mitty  mitty@mitty.jp
67
alphanet schaefer@alphanet.ch (many changes and multigraph)
68
69
See https://framagit.org/alphanet/various-stuff
70
(plugins/lcx)
71
72
=head1 LICENSE
73
74
2-clause BSD License
75
or GPLv3 license or later, at your option
76
77
=head1 MAGIC MARKERS
78
79
 #%# family=auto
80
 #%# capabilities=autoconf
81
82
=cut
83
84 89003f01 Lars Kruse
. "$MUNIN_LIBDIR/plugins/plugin.sh"
85
86 4e321bbc Marc SCHAEFER
87
lxcpath=${lxcpath:-/var/lib/lxc}
88 d415877c Lars Kruse
# containers to be ignored
89
exclude=${exclude:-}
90 9af96d2c Lars Kruse
ram_display_stacked=${ram_display_stacked:-true}
91 d415877c Lars Kruse
# try to guess the location, if empty
92
cgrouppath=${cgrouppath:-}
93 ab6f4e3c Lars Kruse
94 4e321bbc Marc SCHAEFER
95 784b06fe Marc SCHAEFER
# --- FUNCTIONS
96
97 4e321bbc Marc SCHAEFER
function active_guests {
98 46626b99 Lars Kruse
   local excludes="$1"
99
   local guest_name
100 276e96c0 Lars Kruse
   for guest_name in $(lxc-ls)
101 4e321bbc Marc SCHAEFER
   do
102
      # handle optional exclude list in $1
103 46626b99 Lars Kruse
      if ! echo "$excludes" | grep -qwF "$guest_name"; then
104
         if lxc-info -n "$guest_name" --state 2>/dev/null | grep -qw RUNNING; then
105 6413375c Lars Kruse
            echo "$guest_name"
106 4e321bbc Marc SCHAEFER
         fi
107
      fi
108
   done
109
}
110
111 6696a4d8 Lars Kruse
112 4e321bbc Marc SCHAEFER
function lxc_cgroup {
113
   # lxc3 (lxc < 3: may output some warnings if there is cruft in your config dir)
114
   lxc-cgroup -o /dev/stdout -l INFO $* | sed 's/^.*lxc_cgroup.c:main:[0-9][0-9]* - //'
115
}
116
117 6696a4d8 Lars Kruse
118 4e321bbc Marc SCHAEFER
function lxc_netdev {
119 9cdea3c3 Lars Kruse
   local guest_name="$1"
120 4e321bbc Marc SCHAEFER
121 9cdea3c3 Lars Kruse
   if [ -f "$lxcpath/$guest_name/config" ]; then
122 4e321bbc Marc SCHAEFER
      # lxc 3 vs < 3
123 199b4517 Lars Kruse
      (grep -EF '^lxc.net.0.veth.pair' "$lxcpath/$guest_name/config" 2>/dev/null \
124
         || grep -EF '^lxc.network.veth.pair' "$lxcpath/$guest_name/config"
125 4e321bbc Marc SCHAEFER
      ) | awk '{print $NF;}'
126
   fi
127
}
128
129 6696a4d8 Lars Kruse
130 4e321bbc Marc SCHAEFER
# find proper sysfs and count it
131
# Debian 6.0: /sys/fs/cgroup/<container>/tasks
132
# Ubuntu 12.04 with fstab: /sys/fs/cgroup/lxc/<container>/tasks
133
# Ubuntu 12.04 with cgroup-lite: /sys/fs/cgroup/cpuacct/lxc/<container>/tasks
134
# Ubuntu 12.04 with cgroup-bin: /sys/fs/cgroup/cpuacct/sysdefault/lxc/<container>/tasks
135
# Ubuntu 14.04 /sys/fs/cgroup/systemd/lxc/<container>/tasks
136
# and with cgmanager on jessie
137
lxc_count_processes () {
138 ec3a7f40 Lars Kruse
   local guest_name="$1"
139 4e321bbc Marc SCHAEFER
   local SYSFS
140
141 ec3a7f40 Lars Kruse
   [ -z "$guest_name" ] && return 0
142 4e321bbc Marc SCHAEFER
143
   if [ -n "$cgrouppath" ]; then
144 ec3a7f40 Lars Kruse
      SYSFS="$cgrouppath/$guest_name/tasks"
145 89003f01 Lars Kruse
      if [ -e "$SYSFS" ]; then
146 ec3a7f40 Lars Kruse
         wc -l <"$SYSFS"
147
         return
148 4e321bbc Marc SCHAEFER
      fi
149
   fi
150
151
   for SYSFS in \
152 89003f01 Lars Kruse
      "/sys/fs/cgroup/$guest_name/tasks" \
153
      "/sys/fs/cgroup/lxc/$guest_name/tasks" \
154
      "/sys/fs/cgroup/systemd/lxc/$guest_name/tasks" \
155
      "/sys/fs/cgroup/cpuacct/lxc/$guest_name/tasks" \
156
      "/sys/fs/cgroup/cpuacct/sysdefault/lxc/$guest_name/tasks"
157 4e321bbc Marc SCHAEFER
   do
158 89003f01 Lars Kruse
      if [ -e "$SYSFS" ]; then
159 ec3a7f40 Lars Kruse
         wc -l <"$SYSFS"
160
         return
161 4e321bbc Marc SCHAEFER
      fi
162
   done
163
164
   if [ -e /usr/bin/cgm ]; then
165 ec3a7f40 Lars Kruse
      cgm getvalue cpu "lxc/$guest_name" tasks 2>/dev/null | wc -l
166
   else
167
      lxc_cgroup -n "$guest_name" tasks | wc -l
168 4e321bbc Marc SCHAEFER
   fi
169
}
170
171 6696a4d8 Lars Kruse
172 784b06fe Marc SCHAEFER
# --- BASIC DEFINES
173
174 8b955667 Lars Kruse
active_guests=$(active_guests "$exclude")
175 4e321bbc Marc SCHAEFER
176 784b06fe Marc SCHAEFER
# --- AUTOCONF
177
178 4e321bbc Marc SCHAEFER
if [ "$1" = "autoconf" ]; then
179
   if [ ! -r /proc/net/dev ]; then
180
      echo "no (/proc/net/dev cannot be read)"
181 d004990b Lars Kruse
   elif [ ! -e "$lxcpath" ]; then
182 4e321bbc Marc SCHAEFER
      echo "no ($lxcpath is not present)"
183 d004990b Lars Kruse
   else
184
      echo yes
185 4e321bbc Marc SCHAEFER
   fi
186 d004990b Lars Kruse
   exit 0
187 4e321bbc Marc SCHAEFER
fi
188
189
# --- CONFIG OUTPUT
190
191
if [ "$1" = "config" ]; then
192
   cat <<EOF
193
multigraph lxc_cpu
194
graph_title CPU Usage
195
graph_args -l 0 --base 1000
196
graph_vlabel USER_HZ
197
graph_category lxc
198
EOF
199
200 33b2f3ed Lars Kruse
   for guest_name in $active_guests
201 4e321bbc Marc SCHAEFER
   do
202 33b2f3ed Lars Kruse
      for cpu_usage in user system
203 4e321bbc Marc SCHAEFER
      do
204
         cat <<EOF
205 33b2f3ed Lars Kruse
$(clean_fieldname "cpu_${cpu_usage}__${guest_name}").label $guest_name: $(echo "${cpu_usage:0:1}" | tr "[:lower:]" "[:upper:]")${cpu_usage:1}
206
$(clean_fieldname "cpu_${cpu_usage}__${guest_name}").type DERIVE
207
$(clean_fieldname "cpu_${cpu_usage}__${guest_name}").min 0
208 4e321bbc Marc SCHAEFER
EOF
209
      done
210
   done
211
212
   cat <<EOF
213
214
multigraph lxc_cpu_time
215
graph_title CPU time
216
graph_args -l 0 --base 1000
217
graph_vlabel nanosec
218
graph_category lxc
219
EOF
220
221 33b2f3ed Lars Kruse
   for guest_name in $active_guests
222 6696a4d8 Lars Kruse
   do
223 4e321bbc Marc SCHAEFER
      cat <<EOF
224 33b2f3ed Lars Kruse
$(clean_fieldname "cpu_time__${guest_name}").label $guest_name: CPU time
225
$(clean_fieldname "cpu_time__${guest_name}").type DERIVE
226
$(clean_fieldname "cpu_time__${guest_name}").min 0
227 4e321bbc Marc SCHAEFER
EOF
228
   done
229
230
   cat <<EOF
231
232
multigraph lxc_logins
233
graph_title Logins
234
graph_category lxc
235
EOF
236
237 33b2f3ed Lars Kruse
   for guest_name in $active_guests
238 4e321bbc Marc SCHAEFER
   do
239
      cat <<EOF
240 33b2f3ed Lars Kruse
$(clean_fieldname "logins__${guest_name}").label $guest_name: logins
241
$(clean_fieldname "logins__${guest_name}").type GAUGE
242 4e321bbc Marc SCHAEFER
EOF
243
   done
244
245
   cat <<EOF
246
247
multigraph lxc_net
248
graph_title Network traffic
249
graph_args --base 1000
250 0d593014 Lars Kruse
graph_vlabel bits in (-) / out (+) per \${graph_period}
251 4e321bbc Marc SCHAEFER
graph_category lxc
252
graph_info This graph shows the traffic of active LXC containers.
253
EOF
254
255 33b2f3ed Lars Kruse
   for guest_name in $active_guests
256 4e321bbc Marc SCHAEFER
   do
257 33b2f3ed Lars Kruse
      device=$(lxc_netdev "$guest_name")
258 313d195f Lars Kruse
      if [ -z "$device" ]; then
259 4e321bbc Marc SCHAEFER
         continue
260
      fi
261
      cat <<EOF
262 33b2f3ed Lars Kruse
$(clean_fieldname "net__${guest_name}_down").label $guest_name
263
$(clean_fieldname "net__${guest_name}_down").type DERIVE
264
$(clean_fieldname "net__${guest_name}_down").graph no
265
$(clean_fieldname "net__${guest_name}_down").cdef $(clean_fieldname "net__${guest_name}_down"),8,*
266
$(clean_fieldname "net__${guest_name}_down").min 0
267
$(clean_fieldname "net__${guest_name}_up").label $guest_name
268
$(clean_fieldname "net__${guest_name}_up").type DERIVE
269
$(clean_fieldname "net__${guest_name}_up").negative $(clean_fieldname "net__${guest_name}_down")
270
$(clean_fieldname "net__${guest_name}_up").cdef $(clean_fieldname "net__${guest_name}_up"),8,*
271
$(clean_fieldname "net__${guest_name}_up").min 0
272 da8a74fd Lars Kruse
EOF
273
      if [ -r "/sys/class/net/$device/speed" ]; then
274
         megabit_per_second=$(cat "/sys/class/net/$device/speed")
275
         bps=$((megabit_per_second * 1000 * 1000))
276
         cat <<EOF
277 33b2f3ed Lars Kruse
$(clean_fieldname "net__${guest_name}_down").max $bps
278
$(clean_fieldname "net__${guest_name}_up").max $bps
279 4e321bbc Marc SCHAEFER
EOF
280 da8a74fd Lars Kruse
      fi
281 6696a4d8 Lars Kruse
   done
282 4e321bbc Marc SCHAEFER
283
   cat <<EOF
284
285
multigraph lxc_proc
286
graph_title Processes
287
graph_args -l 0 --base 1000
288
graph_vlabel Number of processes
289
graph_category lxc
290
EOF
291 33b2f3ed Lars Kruse
   for guest_name in $active_guests
292 6696a4d8 Lars Kruse
   do
293 4e321bbc Marc SCHAEFER
      cat <<EOF
294 33b2f3ed Lars Kruse
$(clean_fieldname "lxc_proc__${guest_name}").label $guest_name: processes
295
$(clean_fieldname "lxc_proc__${guest_name}").type GAUGE
296
$(clean_fieldname "lxc_proc__${guest_name}").min 0
297 4e321bbc Marc SCHAEFER
EOF
298
   done
299
300
   cat <<EOF
301
302
multigraph lxc_ram
303
graph_title Memory
304
graph_args -l 0 --base 1024
305
graph_vlabel byte
306
graph_category lxc
307
EOF
308
309 33b2f3ed Lars Kruse
   for guest_name in $active_guests
310 4e321bbc Marc SCHAEFER
   do
311 9af96d2c Lars Kruse
      if [ "$ram_display_stacked" != "true" ]; then
312 ab6f4e3c Lars Kruse
         draw_style="LINE1"
313 9af96d2c Lars Kruse
      else
314
         draw_style="AREASTACK"
315 4e321bbc Marc SCHAEFER
      fi
316
317
      cat <<EOF
318 33b2f3ed Lars Kruse
$(clean_fieldname "mem_usage__${guest_name}").label ${guest_name}: Mem usage
319
$(clean_fieldname "mem_usage__${guest_name}").type GAUGE
320
$(clean_fieldname "mem_usage__${guest_name}").draw $draw_style
321
$(clean_fieldname "mem_cache__${guest_name}").label ${guest_name}: Cache
322
$(clean_fieldname "mem_cache__${guest_name}").type GAUGE
323
$(clean_fieldname "mem_active__${guest_name}").label ${guest_name}: Active
324
$(clean_fieldname "mem_active__${guest_name}").type GAUGE
325
$(clean_fieldname "mem_inactive__${guest_name}").label ${guest_name}: Inactive
326
$(clean_fieldname "mem_inactive__${guest_name}").type GAUGE
327 4e321bbc Marc SCHAEFER
EOF
328
   done
329
330
   exit 0
331
fi
332
333
# --- DATA OUTPUT
334
335
echo "multigraph lxc_cpu"
336 33b2f3ed Lars Kruse
for guest_name in $active_guests
337 6696a4d8 Lars Kruse
do
338 33b2f3ed Lars Kruse
   for cpu_usage in user system
339 6696a4d8 Lars Kruse
   do
340 33b2f3ed Lars Kruse
      echo "$(clean_fieldname "cpu_${cpu_usage}__${guest_name}").value $(lxc_cgroup -n "$guest_name" cpuacct.stat | grep "$cpu_usage" | awk '{ print $2; }')"
341 4e321bbc Marc SCHAEFER
   done
342
done
343
344
echo "multigraph lxc_cpu_time"
345 33b2f3ed Lars Kruse
for guest_name in $active_guests
346 4e321bbc Marc SCHAEFER
do
347 33b2f3ed Lars Kruse
   echo "$(clean_fieldname "cpu_time__${guest_name}").value $(lxc_cgroup -n "$guest_name" cpuacct.usage)"
348 4e321bbc Marc SCHAEFER
done
349
350
echo "multigraph lxc_logins"
351 33b2f3ed Lars Kruse
for guest_name in $active_guests
352 6696a4d8 Lars Kruse
do
353 33b2f3ed Lars Kruse
   echo "$(clean_fieldname "logins__${guest_name}").value $(lxc-attach -n "$guest_name" users | wc -w)"
354 4e321bbc Marc SCHAEFER
done
355
356
echo "multigraph lxc_net"
357 33b2f3ed Lars Kruse
for guest_name in $active_guests
358 4e321bbc Marc SCHAEFER
do
359 33b2f3ed Lars Kruse
   device=$(lxc_netdev "$guest_name")
360 313d195f Lars Kruse
   if [ -z "$device" ]; then
361 ec3a7f40 Lars Kruse
      value_up="U"
362
      value_down="U"
363
   else
364 199b4517 Lars Kruse
      value_up=$(grep -E "^ *${device}:" /proc/net/dev | awk '{print $10;}')
365
      value_down=$(grep -E "^ *${device}:" /proc/net/dev | awk '{print $2;}')
366 4e321bbc Marc SCHAEFER
   fi
367
368
   cat <<EOF
369 33b2f3ed Lars Kruse
$(clean_fieldname "net__${guest_name}_up").value $value_up
370
$(clean_fieldname "net__${guest_name}_down").value $value_down
371 4e321bbc Marc SCHAEFER
EOF
372
done
373
374
echo "multigraph lxc_proc"
375 33b2f3ed Lars Kruse
for guest_name in $active_guests
376 4e321bbc Marc SCHAEFER
do
377 33b2f3ed Lars Kruse
   echo "$(clean_fieldname "lxc_proc__${guest_name}").value $(lxc_count_processes "$guest_name")"
378 4e321bbc Marc SCHAEFER
done
379
380
echo "multigraph lxc_ram"
381 33b2f3ed Lars Kruse
for guest_name in $active_guests
382 4e321bbc Marc SCHAEFER
do
383
   cat <<EOF
384 33b2f3ed Lars Kruse
$(clean_fieldname "mem_usage__${guest_name}").value $(lxc_cgroup -n "$guest_name" memory.usage_in_bytes)
385
$(clean_fieldname "mem_cache__${guest_name}").value $(lxc_cgroup -n "$guest_name" memory.stat | grep total_cache | awk '{print $2;}')
386
$(clean_fieldname "mem_active__${guest_name}").value $(lxc_cgroup -n "$guest_name" memory.stat | grep total_active_anon | awk '{print $2;}')
387
$(clean_fieldname "mem_inactive__${guest_name}").value $(lxc_cgroup -n "$guest_name" memory.stat | grep total_inactive_anon | awk '{print $2;}')
388 4e321bbc Marc SCHAEFER
EOF
389
done