#!/bin/bash # -*- sh -*- : << =cut =head1 NAME lxc-multigraph - Plugin to monitor LXC containers (v2.0) =head1 CONFIGURATION [lxc-multigraph] user root # The memory usage of containers are by default drawn as stacked area # charts. Alternatively a non-stacked graph with lines can be configured. # Default: true #env.ram_display_stacked 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, the "users" command is required in each container. Tested on Debian buster and Debian jessie. The double __ for values is for compatibility with the previous implementation. =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} # containers to be ignored exclude=${exclude:-} ram_display_stacked=${ram_display_stacked:-true} # try to guess the location, if empty cgrouppath=${cgrouppath:-} # --- FUNCTIONS function active_guests { local excludes="$1" local guest_name for guest_name in $(lxc-ls) do # handle optional exclude list in $1 if ! echo "$excludes" | grep -qwF "$guest_name"; then if lxc-info -n "$guest_name" --state 2>/dev/null | grep -qw RUNNING; then echo "$guest_name" fi fi done } 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 guest_name="$1" if [ -f "$lxcpath/$guest_name/config" ]; then # lxc 3 vs < 3 (grep -EF '^lxc.net.0.veth.pair' "$lxcpath/$guest_name/config" 2>/dev/null \ || grep -EF '^lxc.network.veth.pair' "$lxcpath/$guest_name/config" ) | awk '{print $NF;}' 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 guest_name="$1" local SYSFS [ -z "$guest_name" ] && return 0 if [ -n "$cgrouppath" ]; then SYSFS="$cgrouppath/$guest_name/tasks" if [ -e "$SYSFS" ]; then wc -l <"$SYSFS" return fi fi for SYSFS in \ "/sys/fs/cgroup/$guest_name/tasks" \ "/sys/fs/cgroup/lxc/$guest_name/tasks" \ "/sys/fs/cgroup/systemd/lxc/$guest_name/tasks" \ "/sys/fs/cgroup/cpuacct/lxc/$guest_name/tasks" \ "/sys/fs/cgroup/cpuacct/sysdefault/lxc/$guest_name/tasks" do if [ -e "$SYSFS" ]; then wc -l <"$SYSFS" return fi done if [ -e /usr/bin/cgm ]; then cgm getvalue cpu "lxc/$guest_name" tasks 2>/dev/null | wc -l else lxc_cgroup -n "$guest_name" tasks | wc -l fi } # --- BASIC DEFINES active_guests=$(active_guests $exclude) # --- AUTOCONF if [ "$1" = "autoconf" ]; then if [ ! -r /proc/net/dev ]; then echo "no (/proc/net/dev cannot be read)" elif [ ! -e "$lxcpath" ]; then echo "no ($lxcpath is not present)" else echo yes fi exit 0 fi # --- CONFIG OUTPUT if [ "$1" = "config" ]; then cat <