diff --git a/net/apinger/Makefile b/net/apinger/Makefile index c0b232d158..ea89ffdc6d 100644 --- a/net/apinger/Makefile +++ b/net/apinger/Makefile @@ -65,7 +65,27 @@ define Package/apinger/install $(INSTALL_DATA) ./files/user.hotplug $(1)/etc/hotplug.d/apinger/01-user $(INSTALL_DIR) $(1)/etc/hotplug.d/iface $(INSTALL_DATA) ./files/iface.hotplug $(1)/etc/hotplug.d/iface/25-apinger + $(INSTALL_DIR) $(1)/usr/libexec/rpcd + $(INSTALL_BIN) ./files/apinger.rpc $(1)/usr/libexec/rpcd/apinger +endef + +define Package/apinger-rrd + SECTION:=net + CATEGORY:=Network + DEPENDS:=+apinger +rrdtool1 +rrdcgi1 + TITLE:=Apinger RRD Graphs + URL:=https://github.com/Jajcus/apinger +endef + +define Package/apinger-rrd/description + Generate RRD Graphs from Apinger Data +endef + +define Package/apinger-rrd/install + $(INSTALL_DIR) $(1)/usr/libexec/apinger/rpc + $(INSTALL_DATA) ./files/graphs.sh $(1)/usr/libexec/apinger/rpc endef $(eval $(call BuildPackage,apinger)) +$(eval $(call BuildPackage,apinger-rrd)) diff --git a/net/apinger/files/apinger.init b/net/apinger/files/apinger.init index 51999880cc..7a287c03b5 100644 --- a/net/apinger/files/apinger.init +++ b/net/apinger/files/apinger.init @@ -3,6 +3,8 @@ START=80 USE_PROCD=1 +BIN=/usr/sbin/apinger +APINGER_RRD=/apinger/rrd . /lib/functions/network.sh @@ -36,7 +38,7 @@ append_target() { local target=$1 local interface address probe_interval srcip local avg_delay_samples avg_loss_samples avg_loss_delay_samples - local alarm_down alarm_delay alarm_loss alarms + local alarm_down alarm_delay alarm_loss alarms rrd config_get interface "$target" interface wan [ "$interface" != "$instance" ] && return 0 @@ -49,6 +51,7 @@ append_target() { config_get alarm_down "$target" alarm_down config_get alarm_delay "$target" alarm_delay config_get alarm_loss "$target" alarm_loss + config_get_bool rrd "$target" rrd 0 [ -z "$address" ] && return 0 @@ -69,6 +72,7 @@ append_target() { [ -n "$avg_loss_samples" ] && append_config_line "avg_loss_samples ${avg_loss_samples}" [ -n "$avg_loss_delay_samples" ] && append_config_line "avg_loss_delay_samples ${avg_loss_delay_samples}" [ -n "$alarms" ] && append_config_line "alarms override ${alarms}" + [ "$rrd" = "1" ] && append_config_line "rrd file \"$APINGER_RRD/apinger-target-$target.rrd\"" close_config_block write_config_block @@ -125,13 +129,14 @@ append_alarm_loss() { } init_apinger_config() { - local debug status_interval instance + local debug status_interval rrd_interval instance instance=$1 config_get_bool debug apinger debug 0 config_get status_interval apinger status_interval 1 + config_get rrd_interval apinger rrd_interval 30 - [ "$debug" == "1" ] && debug=on || debug=off + [ "$debug" = "1" ] && debug=on || debug=off set_config_file set_status_file @@ -141,6 +146,8 @@ user "root" group "root" debug ${debug} +rrd interval ${rrd_interval}s + status { scriptformat on file "$STATUS_FILE" @@ -185,9 +192,8 @@ start_instance() { config_foreach append_target target procd_open_instance "$instance" - procd_set_param command /usr/sbin/apinger -f -c $CONFIG_FILE + procd_set_param command $BIN -f -c $CONFIG_FILE procd_set_param stderr 1 - procd_set_param stdout 1 procd_close_instance } @@ -196,6 +202,8 @@ start_service() { config_load apinger + [ ! -d "$APINGER_RRD" ] && mkdir -p "$APINGER_RRD" + if [ -n "$instance" ]; then start_instance "$instance" else diff --git a/net/apinger/files/apinger.rpc b/net/apinger/files/apinger.rpc new file mode 100644 index 0000000000..0be6e16572 --- /dev/null +++ b/net/apinger/files/apinger.rpc @@ -0,0 +1,117 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh + +RPC_SCRIPTS=/usr/libexec/apinger/rpc + +[ -d $RPC_SCRIPTS ] && include $RPC_SCRIPTS + +__function__() { + type "$1" > /dev/null 2>&1 +} + +foreach_extra() { + local file obj + + [ ! -d $RPC_SCRIPTS ] && return + + for file in $RPC_SCRIPTS/*; do + obj="${file##*/}" + $1 "${obj%%.*}" + done +} + +apinger_status() { + interface_list() { + append iface_list $1 + } + config_load apinger + config_foreach interface_list interface + + json_init + json_add_array targets + + for iface in $iface_list; do + local status_file="/var/run/apinger-$iface.status" + + if [ -f "$status_file" ]; then + _IFS="$IFS" + IFS="|" + while read -r address srcip target received sent timestamp latency loss alarm; do + json_add_object targets + json_add_string interface "$iface" + json_add_string target "$target" + json_add_string address "$address" + json_add_string srcip "$srcip" + json_add_int sent "$sent" + json_add_int received "$received" + json_add_string latency "$latency" + json_add_string loss "$loss" + json_add_string alarm "$alarm" + json_add_int timestamp "$timestamp" + json_close_object + done < "$status_file" + IFS="$_IFS" + fi + done + + json_close_array + json_dump +} + +call_extra() { + if __function__ "$1"; then + $1 + else + json_init + json_add_string error "invalid call $1" + json_dump + fi +} + +call_method() { + case "$1" in + status) + apinger_status + ;; + *) + call_extra $1 + ;; + esac +} + +list_extra() { + if __function__ "${1}_help"; then + ${1}_help + else + json_add_object "$1" + json_close_object + fi +} + +list_methods() { + local file + + json_init + + json_add_object status + json_close_object + + foreach_extra list_extra ${1} + + json_dump +} + +main () { + case "$1" in + list) + list_methods + ;; + call) + call_method $2 + ;; + esac +} + +main "$@" diff --git a/net/apinger/files/graphs.sh b/net/apinger/files/graphs.sh new file mode 100644 index 0000000000..442dfbec76 --- /dev/null +++ b/net/apinger/files/graphs.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh + +APINGER="/usr/sbin/apinger" +RRDCGI="/www/cgi-bin/apinger" +GRAPH_DIR="/apinger/graphs" +WWW_LOCATION="/www${GRAPH_DIR}" + +update_interface_graphs() { + local iface cfg cmd + + iface=$1 + cfg=/var/run/apinger-$iface.conf + + [ ! -f $cfg ] && return + + cmd="$APINGER -c $cfg -g $WWW_LOCATION -l $GRAPH_DIR" + + if [ -x $RRDCGI ]; then + $cmd 2>/dev/null | sed -e '/\(HTML\|TITLE\|H1\|H2\|by\|^#\)/d' >> $RRDCGI + else + $cmd 2>/dev/null | sed -e '/\(HTML\|TITLE\|H1\|H2\|by\)/d' > $RRDCGI + chmod 755 $RRDCGI + fi +} + +update_graphs() { + [ ! -d $WWW_LOCATION ] && mkdir -p $WWW_LOCATION + [ -e $RRDCGI ] && rm -f $RRDCGI + + config_load apinger + config_foreach update_interface_graphs interface + + json_init + json_add_string rrdcgi "$RRDCGI" + json_dump +} + +graphs_help() { + json_add_object update_graphs + json_close_object +} diff --git a/net/apinger/files/iface.hotplug b/net/apinger/files/iface.hotplug index 6c1930f935..f97de0ae90 100644 --- a/net/apinger/files/iface.hotplug +++ b/net/apinger/files/iface.hotplug @@ -6,7 +6,7 @@ [ "$(uci_get apinger $INTERFACE)" == "interface" ] || exit 0 [ "$ACTION" = "ifup" ] && { - /etc/init.d/apinger $INTERFACE restart + /etc/init.d/apinger restart $INTERFACE } } diff --git a/net/apinger/patches/060-format-alarm-list.patch b/net/apinger/patches/060-format-alarm-list.patch new file mode 100644 index 0000000000..815202f3b6 --- /dev/null +++ b/net/apinger/patches/060-format-alarm-list.patch @@ -0,0 +1,12 @@ +--- a/src/apinger.c ++++ b/src/apinger.c +@@ -860,6 +860,9 @@ char *buf1,*buf2; + a=al->alarm; + if(config->status_format){ + fprintf(f,"%s",a->name); ++ if(al->next){ ++ fprintf(f,","); ++ } + } + else{ + fprintf(f," \"%s\"",a->name);