diff --git a/plugins/lxc/lxc-multigraph b/plugins/lxc/lxc-multigraph new file mode 100755 index 00000000..ee920004 --- /dev/null +++ b/plugins/lxc/lxc-multigraph @@ -0,0 +1,377 @@ +#!/bin/bash +# -*- sh -*- + +: << =cut + +=head1 NAME + +lxc-multigraph - Plugin to monitor LXC containers (v2.0) + +=head1 CONFIGURATION + + [lxc-multigraph] + user root + + # memory usage of containers drawn as + # stacked area charts (changes graph + # order) -- defaults to false + # env.ram_areastack true + + # lxc container path, default below + #env.lxcpath /var/lib/lxc + + # exclude the following containers + # (default none excluded) + #env.exclude container1 container2 + + # path where tasks sysfs files are stored, + # set this if the various attempts in the + # code don't work + # (default none) + #env.cgrouppath /sys/fs/cgroup/cpuacct/lxc/ + +=head1 INTERPRETATION + +This plugin needs root privilege. + +This plugin has been tested with lxc 3 and +lx2 (on Debian buster and Debian jessie, +respectively). + +For the network graphs to work, you need +to have in every container's config file +a line defining the virtual network interface +path (else lxc will use a random name at +each container's start); see the lxc_netdev() +function below. + +If using lxc 2, make sure you do not have cruft +in your container config files, you can test +it with: + lxc-cgroup -o /dev/stdout -l INFO -n 104 cpuacct.usage +-- with 104 a valid lxc instance), if you +get a warning, fix the config file. + +For the logins graph, you need the bc command, and, +in each container, the users command. + +Tested on Debian buster and Debian jessie. + +=head1 AUTHOR + +vajtsz vajtsz@gmail.com +mitty mitty@mitty.jp +alphanet schaefer@alphanet.ch (many changes and multigraph) + +See https://framagit.org/alphanet/various-stuff +(plugins/lcx) + +=head1 LICENSE + +2-clause BSD License +or GPLv3 license or later, at your option + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + +. $MUNIN_LIBDIR/plugins/plugin.sh + +lxcpath=${lxcpath:-/var/lib/lxc} + +function active_guests { + local g active i ok + for g in $(lxc-ls | sort -u) + do + # handle optional exclude list in $1 + ok=1 + for i in $1 + do + if [ "$i" = "$g" ]; then + ok=0 + fi + done + + if [ $ok = 1 ]; then + if lxc-info -n $g 2>&1 | grep -qs RUNNING; then + active="$active $g" + fi + fi + done + + echo $active +} + +function lxc_cgroup { + # lxc3 (lxc < 3: may output some warnings if there is cruft in your config dir) + lxc-cgroup -o /dev/stdout -l INFO $* | sed 's/^.*lxc_cgroup.c:main:[0-9][0-9]* - //' +} + +function lxc_netdev { + local g=$1 dev + + if [ -f $lxcpath/$g/config ]; then + # lxc 3 vs < 3 + (egrep '^lxc.net.0.veth.pair' $lxcpath/$g/config 2>/dev/null \ + || egrep '^lxc.network.veth.pair' $lxcpath/$g/config + ) | awk '{print $NF;}' + else + echo unknown + fi +} + +# find proper sysfs and count it +# Debian 6.0: /sys/fs/cgroup//tasks +# Ubuntu 12.04 with fstab: /sys/fs/cgroup/lxc//tasks +# Ubuntu 12.04 with cgroup-lite: /sys/fs/cgroup/cpuacct/lxc//tasks +# Ubuntu 12.04 with cgroup-bin: /sys/fs/cgroup/cpuacct/sysdefault/lxc//tasks +# Ubuntu 14.04 /sys/fs/cgroup/systemd/lxc//tasks +# and with cgmanager on jessie +lxc_count_processes () { + local SYSFS + + [ -z "$1" ] && return 0 + + if [ -n "$cgrouppath" ]; then + SYSFS="$cgrouppath/$1/tasks" + if [ -e $SYSFS ]; then + return $(wc -l < $SYSFS) + fi + fi + + for SYSFS in \ + /sys/fs/cgroup/"$1"/tasks \ + /sys/fs/cgroup/lxc/"$1"/tasks \ + /sys/fs/cgroup/systemd/lxc/"$1"/tasks \ + /sys/fs/cgroup/cpuacct/lxc/"$1"/tasks \ + /sys/fs/cgroup/cpuacct/sysdefault/lxc/"$1"/tasks + do + if [ -e $SYSFS ]; then + return $(wc -l < $SYSFS) + fi + done + + if [ -e /usr/bin/cgm ]; then + return $(cgm getvalue cpu "lxc/$1" tasks 2>/dev/null | wc -l) + fi + + return 0 +} + +active_guests=$(active_guests $exclude) + +if [ "$1" = "autoconf" ]; then + if [ ! -r /proc/net/dev ]; then + echo "no (/proc/net/dev cannot be read)" + exit 0 + fi + if [ ! -e "$lxcpath" ]; then + echo "no ($lxcpath is not present)" + exit 0 + fi + + echo yes +fi + +# --- CONFIG OUTPUT + +if [ "$1" = "config" ]; then + cat <