#!/bin/bash
#
# Plugin to parse packetship (http://www.packetship.com/) streaming server statistics.
#
# Author:
#    Dave Fennell <dave@microtux.co.uk>
#
# Created:
#    2nd January 2013
#
# License:
#    GPLv2
#
# Usage:
#    Link in /etc/munin/plugins/ as packetship_streams or packetship_bandwidth (or both)
#

# change those to reflect your bind configuration (use plugin configuration)
# hostname file
if [ "$hostname" = "" ]; then
	hostname="localhost"
fi

# url path
if [ "$url" = "" ]; then
	url="packetship/status.php"
fi

# Get the mode from the plugin symlink name.
mode=${0#*_}

# Check for valid mode.
if [[ "$mode" != "streams" && "$mode" != "bandwidth" ]]; then
	echo "Link name must be packetship_streams or packetship_bandwidth."
	exit 1
fi

# Fetch the XML formatted stats from packetship.
xml=$(wget -q -O - http://${hostname}/${url})

# Function to do simple string parsing of XML data.
read_dom () {
	local IFS=\>
	read -d \< ENTITY CONTENT
	TAG_NAME=${ENTITY%% *}
	ATTRIBUTES=${ENTITY#* }

	# Remove / characters from ATTRIBUTES if present.
	ATTRIBUTES=${ATTRIBUTES//\//}

	if [[ $ENTITY = "" ]]; then
		return 1
	fi

	return 0
}

# Get the number of pumps from the xml feed.
pumps_line=$(echo "$xml" | grep "<ps:pumps")

while read_dom; do
	if [ "$TAG_NAME" != "" ]; then
		break
	fi
done <<< "$pumps_line"

eval $ATTRIBUTES
actual_pumps=$total
fake_pumps=$total

# If there are no pumps then pretend there is one
# (so we get something on the graph).
if [ "$actual_pumps" == 0 ]; then
	fake_pumps=1
fi

# Config mode.
if [ "$1" = "config" ]; then
	echo 'graph_args --lower-limit 0'
	echo 'graph_category streaming'
	echo 'graph_info '${mode}' statistics for packetship server'
	echo 'graph_scale no'
	echo 'graph_title Packetship '${mode}

	if [ "$mode" = "streams" ]; then
		echo 'graph_vlabel streams'
	else
		echo 'graph_vlabel bandwidth (Mbit/sec)'
	fi

	for pump in $(seq $fake_pumps); do
		echo "pump"${pump}"_disk_value.label Pump" ${pump} "Disk current"
		echo "pump"${pump}"_disk_value.info Current Pump" ${pump} "disk" ${mode}
		echo "pump"${pump}"_disk_value.type GAUGE"

		echo "pump"${pump}"_disk_max.label Pump" ${pump} "Disk max"
		echo "pump"${pump}"_disk_max.info Limit of Pump" ${pump} "disk" ${mode}
		echo "pump"${pump}"_disk_max.type GAUGE"

		echo "pump"${pump}"_network_value.label Pump" ${pump} "Network current"
		echo "pump"${pump}"_network_value.info Current Pump" ${pump} "network" ${mode}
		echo "pump"${pump}"_network_value.type GAUGE"

		echo "pump"${pump}"_network_max.label Pump" ${pump} "Network max"
		echo "pump"${pump}"_network_max.info Limit of Pump" ${pump} "network" ${mode}
		echo "pump"${pump}"_network_max.type GAUGE"
	done

	# If dirty config capability is enabled then fall through
	# to output the data with the config information.
	if [ "$MUNIN_CAP_DIRTYCONFIG" = "" ]; then
		exit 0
	fi
fi

# If there are no pumps then output fake pump1 data and end.
if [ "$actual_pumps" == 0 ]; then
	echo "pump1_disk_value.value" 0
	echo "pump1_disk_max.value" 0
	echo "pump1_network_value.value" 0
	echo "pump1_network_max.value" 0
	exit
fi

pumps_section=$(echo "$xml" | sed "0,/<ps:pumps/d" | sed -e "/<\/ps:pumps/,\$d")

for pump in $(seq $actual_pumps); do
	pump_section=$(echo "$pumps_section" | sed "0,/<ps:pump id=.pump"${pump}"./d" | sed -e "/<\/ps:pump/,\$d")

	# Disk stats are from '<ps:disk>' to '</ps:disk>'
	disk_stats=$(echo "$pump_section" | sed "0,/<ps:disk>/d" | sed -e "/<\/ps:disk>/,\$d" | grep $mode)
	network_stats=$(echo "$pump_section" | sed "0,/<ps:network>/d" | sed -e "/<\/ps:network>/,\$d" | grep $mode)

	# Output disk values for this pump.
	while read_dom; do
		# Ignore empty tags (First loop)
		if [ "$TAG_NAME" = "" ]; then
			continue
		fi

		eval $ATTRIBUTES

		echo "pump"${pump}"_disk_value.value" $used
		echo "pump"${pump}"_disk_max.value" $max
	done <<< "$disk_stats"

	# Output network values for this pump
	while read_dom; do
		# Ignore empty tags (First loop)
		if [ "$TAG_NAME" = "" ]; then
			continue
		fi

		eval $ATTRIBUTES

		echo "pump"${pump}"_network_value.value" $used
		echo "pump"${pump}"_network_max.value" $max
	done <<< "$network_stats"
done
