structured main routines. implement file reporter
This commit is contained in:
parent
c54c9d73b7
commit
9858beb329
22
README.md
22
README.md
|
@ -1,14 +1,12 @@
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [] README
|
- README
|
||||||
- [] option parsing
|
- option parsing
|
||||||
- [] allow multiple reporters
|
- allow multiple reporters
|
||||||
- [] implement log reporter
|
- better docs, including reporters (--docs)
|
||||||
- [] better docs, including reporters (--docs)
|
- config file support
|
||||||
- [] config file support
|
- config file auto-generation
|
||||||
- [] config file auto-generation
|
- load custom metrics
|
||||||
- [] disk_io metric
|
- async metrics
|
||||||
- [] load custom metrics
|
- extended metric labels?
|
||||||
- [] async metrics
|
- same metric multiple times (e.g. disk_usage for multiple devices)
|
||||||
- [] extended metric labels?
|
|
||||||
- [] same metric multiple times (e.g. disk_usage for multiple devices)
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
# load utils
|
||||||
|
for util in ./lib/utils/*.sh; do source $util; done
|
||||||
|
|
||||||
|
# init
|
||||||
|
__METRICS=()
|
||||||
|
__TEMP_DIR=$(make_temp_dir)
|
||||||
|
|
||||||
|
# load reporter
|
||||||
|
|
||||||
|
main_load () {
|
||||||
|
source ./reporters/${REPORTER}.sh
|
||||||
|
copy_function init __r_${REPORTER}_init
|
||||||
|
copy_function report __r_${REPORTER}_report
|
||||||
|
copy_function terminate __r_${REPORTER}_terminate
|
||||||
|
copy_function docs __r_${REPORTER}_docs
|
||||||
|
unset -f init report terminate docs
|
||||||
|
|
||||||
|
# load metrics
|
||||||
|
for file in ./metrics/*.sh; do
|
||||||
|
filename=$(basename $file)
|
||||||
|
metric=${filename%.*}
|
||||||
|
|
||||||
|
# soruce file and copy functions
|
||||||
|
source $file
|
||||||
|
copy_function init __m_${metric}_init
|
||||||
|
copy_function collect __m_${metric}_collect
|
||||||
|
copy_function terminate __m_${metric}_terminate
|
||||||
|
copy_function docs __m_${metric}_docs
|
||||||
|
unset -f init collect terminate docs
|
||||||
|
|
||||||
|
# register metric
|
||||||
|
__METRICS+=($metric)
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_init () {
|
||||||
|
# init reporter
|
||||||
|
if is_function __r_${REPORTER}_init; then
|
||||||
|
__r_${REPORTER}_init
|
||||||
|
fi
|
||||||
|
|
||||||
|
# init metrics
|
||||||
|
for metric in ${__METRICS[@]}; do
|
||||||
|
if ! is_function __m_${metric}_init; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
__m_${metric}_init
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_docs () {
|
||||||
|
echo "Available metrics:"
|
||||||
|
for metric in ${__METRICS[@]}; do
|
||||||
|
if ! is_function __m_${metric}_docs; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[$metric]"
|
||||||
|
__m_${metric}_docs
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_collect () {
|
||||||
|
# used by metrics to return results
|
||||||
|
report () {
|
||||||
|
local _r_result
|
||||||
|
if [ -z $2 ]; then
|
||||||
|
_r_label=$metric
|
||||||
|
_r_result="$1"
|
||||||
|
else
|
||||||
|
_r_label="$metric.$1"
|
||||||
|
_r_result="$2"
|
||||||
|
fi
|
||||||
|
if is_number $_r_result; then
|
||||||
|
__r_${REPORTER}_report $_r_label $_r_result
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# collect metrics
|
||||||
|
while true; do
|
||||||
|
for metric in ${__METRICS[@]}; do
|
||||||
|
if ! is_function __m_${metric}_collect; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
__m_${metric}_collect
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep $INTERVAL
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_terminate () {
|
||||||
|
# terminate metrics
|
||||||
|
for metric in ${__METRICS[@]}; do
|
||||||
|
if ! is_function __m_${metric}_terminate; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
__m_${metric}_terminate
|
||||||
|
done
|
||||||
|
|
||||||
|
# terminate reporter
|
||||||
|
if is_function __r_${REPORTER}_terminate; then
|
||||||
|
__r_${REPORTER}_terminate
|
||||||
|
fi
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
is_number () {
|
||||||
|
[ ! -z "$1" ] && printf '%f' "$1" &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
iso_date () {
|
||||||
|
date -u +"%Y-%m-%dT%H:%M:%SZ"
|
||||||
|
}
|
|
@ -14,11 +14,13 @@ is_linux () { [ $OS_TYPE == 'solaris' ]; }
|
||||||
is_bsd () { [ $OS_TYPE == 'bsd']; }
|
is_bsd () { [ $OS_TYPE == 'bsd']; }
|
||||||
is_unknown () { [ $OS_TYPE == 'unknown' ]; }
|
is_unknown () { [ $OS_TYPE == 'unknown' ]; }
|
||||||
|
|
||||||
|
# http://unix.stackexchange.com/a/84980/50905
|
||||||
make_temp_dir () {
|
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
|
make_temp_dir () {
|
||||||
mktemp -d -t 'sysmetrics'
|
mktemp -d -t 'sysmetrics'
|
||||||
else
|
|
||||||
mktemp -d
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
make_temp_dir () {
|
||||||
|
mktemp -d
|
||||||
|
}
|
||||||
|
fi
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
init () {
|
||||||
if [ -z $DISK_IO_MOUNTPOINT ]; then
|
if [ -z $DISK_IO_MOUNTPOINT ]; then
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
DISK_IO_MOUNTPOINT="disk0"
|
DISK_IO_MOUNTPOINT="disk0"
|
||||||
|
@ -7,6 +8,10 @@ if [ -z $DISK_IO_MOUNTPOINT ]; then
|
||||||
DISK_IO_MOUNTPOINT="/dev/vda"
|
DISK_IO_MOUNTPOINT="/dev/vda"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
readonly __disk_io_fifo=$__TEMP_DIR/disk_io
|
||||||
|
mkfifo $__disk_io_fifo
|
||||||
|
__disk_io_bgproc &
|
||||||
|
}
|
||||||
|
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
__disk_io_bgproc () {
|
__disk_io_bgproc () {
|
||||||
|
@ -20,19 +25,14 @@ else
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__disk_io_fifo=$__TEMP_DIR/disk_io
|
|
||||||
|
|
||||||
init () {
|
|
||||||
__disk_io_bgproc &
|
|
||||||
mkfifo $__disk_io_fifo
|
|
||||||
}
|
|
||||||
|
|
||||||
collect () {
|
collect () {
|
||||||
report $(cat $__disk_io_fifo)
|
report $(cat $__disk_io_fifo)
|
||||||
}
|
}
|
||||||
|
|
||||||
terminate () {
|
terminate () {
|
||||||
|
if [ ! -z $__disk_io_fifo ] && [ -f $__disk_io_fifo ]; then
|
||||||
rm $__disk_io_fifo
|
rm $__disk_io_fifo
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
docs () {
|
docs () {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
init () {
|
||||||
if [ -z $DISK_USAGE_MOUNTPOINT ]; then
|
if [ -z $DISK_USAGE_MOUNTPOINT ]; then
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
DISK_USAGE_MOUNTPOINT="/dev/disk1"
|
DISK_USAGE_MOUNTPOINT="/dev/disk1"
|
||||||
|
@ -7,6 +8,7 @@ if [ -z $DISK_USAGE_MOUNTPOINT ]; then
|
||||||
DISK_USAGE_MOUNTPOINT="/dev/vda"
|
DISK_USAGE_MOUNTPOINT="/dev/vda"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
collect () {
|
collect () {
|
||||||
report $(df | awk -v disk_regexp="^$DISK_USAGE_MOUNTPOINT" \
|
report $(df | awk -v disk_regexp="^$DISK_USAGE_MOUNTPOINT" \
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
declare -r __memory_os_memsize=$(sysctl -n hw.memsize)
|
init () {
|
||||||
|
readonly __memory_os_memsize=$(sysctl -n hw.memsize)
|
||||||
|
}
|
||||||
|
|
||||||
collect () {
|
collect () {
|
||||||
report $(vm_stat | awk -v total_memory=$__memory_os_memsize \
|
report $(vm_stat | awk -v total_memory=$__memory_os_memsize \
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
init () {
|
||||||
if [ -z $NETWORK_IO_INTERFACE ]; then
|
if [ -z $NETWORK_IO_INTERFACE ]; then
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
NETWORK_IO_INTERFACE="en0"
|
NETWORK_IO_INTERFACE="en0"
|
||||||
|
@ -7,13 +8,7 @@ if [ -z $NETWORK_IO_INTERFACE ]; then
|
||||||
NETWORK_IO_INTERFACE="eth0"
|
NETWORK_IO_INTERFACE="eth0"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
readonly __network_io_divisor=$[$INTERVAL * 1024]
|
||||||
declare -r __network_io_divisor=$[$INTERVAL * 1024]
|
|
||||||
__network_io_sample=(0 0)
|
|
||||||
|
|
||||||
__network_io_calc_kBps() {
|
|
||||||
echo $1 $2 | awk -v divisor=$__network_io_divisor \
|
|
||||||
'{printf "%.2f", ($1 - $2) / divisor}'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_osx; then
|
if is_osx; then
|
||||||
|
@ -28,9 +23,14 @@ else
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
__network_io_calc_kBps() {
|
||||||
|
echo $1 $2 | awk -v divisor=$__network_io_divisor \
|
||||||
|
'{printf "%.2f", ($1 - $2) / divisor}'
|
||||||
|
}
|
||||||
|
|
||||||
collect () {
|
collect () {
|
||||||
local sample=( $(__network_io_collect) )
|
local sample=( $(__network_io_collect) )
|
||||||
if [ ${__network_io_sample[0]} -ne 0 ]; then
|
if [ ! -z $__network_io_sample ]; then
|
||||||
report "in" $(__network_io_calc_kBps ${sample[0]} ${__network_io_sample[0]})
|
report "in" $(__network_io_calc_kBps ${sample[0]} ${__network_io_sample[0]})
|
||||||
report "out" $(__network_io_calc_kBps ${sample[1]} ${__network_io_sample[1]})
|
report "out" $(__network_io_calc_kBps ${sample[1]} ${__network_io_sample[1]})
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
collect () {
|
||||||
|
report 1
|
||||||
|
}
|
||||||
|
|
||||||
|
docs () {
|
||||||
|
echo "Send a simple ping in form of an integer '1'."
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
report () {
|
||||||
|
local METRIC=$1
|
||||||
|
local VALUE=$2
|
||||||
|
local DATE=$(iso_date)
|
||||||
|
echo $DATE $METRIC: $VALUE >> $FILE_LOCATION
|
||||||
|
}
|
||||||
|
|
||||||
|
init () {
|
||||||
|
if [ -z $FILE_LOCATION ]; then
|
||||||
|
echo "Missing configuration: \$FILE_LOCATION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f $FILE_LOCATION ]; then
|
||||||
|
touch $FILE_LOCATION
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
docs () {
|
||||||
|
echo "Write to a file or named pipe."
|
||||||
|
echo "\$FILE_LOCATION=$FILE_LOCATION"
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
report () {
|
report () {
|
||||||
METRIC=$1
|
METRIC=$1
|
||||||
VALUE=$2
|
VALUE=$2
|
||||||
curl -d "stat=$METRIC&ezkey=$API_KEY&value=$VALUE" http://api.stathat.com/ez
|
curl -d "stat=$METRIC&ezkey=$STATHAT_API_KEY&value=$VALUE" http://api.stathat.com/ez
|
||||||
}
|
}
|
||||||
|
|
||||||
docs () {
|
docs () {
|
||||||
|
|
|
@ -2,93 +2,16 @@
|
||||||
|
|
||||||
# config
|
# config
|
||||||
INTERVAL=1
|
INTERVAL=1
|
||||||
REPORTER=stdout
|
REPORTER=file
|
||||||
|
|
||||||
# load utils
|
|
||||||
for util in ./lib/utils/*.sh; do source $util; done
|
|
||||||
|
|
||||||
# init
|
|
||||||
__METRICS=()
|
|
||||||
__TEMP_DIR=$(make_temp_dir)
|
|
||||||
|
|
||||||
# register trap
|
# register trap
|
||||||
trap '
|
trap '
|
||||||
for metric in ${__METRICS[@]}; do
|
main_terminate
|
||||||
if ! is_function __m_${metric}_terminate; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
__m_${metric}_terminate
|
|
||||||
done
|
|
||||||
trap - SIGTERM && kill -- -$$ SIGINT SIGTERM EXIT
|
trap - SIGTERM && kill -- -$$ SIGINT SIGTERM EXIT
|
||||||
' SIGINT SIGTERM EXIT
|
' SIGINT SIGTERM EXIT
|
||||||
|
|
||||||
# load reporter
|
# load and start main routine
|
||||||
source ./reporters/${REPORTER}.sh
|
source ./lib/main.sh
|
||||||
copy_function init __r_${REPORTER}_init
|
main_load
|
||||||
copy_function report __r_${REPORTER}_report
|
main_init
|
||||||
copy_function terminate __r_${REPORTER}_terminate
|
main_collect
|
||||||
copy_function docs __r_${REPORTER}_docs
|
|
||||||
unset -f init report terminate docs
|
|
||||||
|
|
||||||
# load metrics
|
|
||||||
for file in ./metrics/*.sh; do
|
|
||||||
filename=$(basename $file)
|
|
||||||
metric=${filename%.*}
|
|
||||||
|
|
||||||
# soruce file and copy functions
|
|
||||||
source $file
|
|
||||||
copy_function init __m_${metric}_init
|
|
||||||
copy_function collect __m_${metric}_collect
|
|
||||||
copy_function terminate __m_${metric}_terminate
|
|
||||||
copy_function docs __m_${metric}_docs
|
|
||||||
unset -f init collect terminate docs
|
|
||||||
|
|
||||||
# register metric
|
|
||||||
__METRICS+=($metric)
|
|
||||||
done
|
|
||||||
|
|
||||||
# init metrics
|
|
||||||
for metric in ${__METRICS[@]}; do
|
|
||||||
if ! is_function __m_${metric}_init; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
__m_${metric}_init
|
|
||||||
done
|
|
||||||
|
|
||||||
# print docs for metrics
|
|
||||||
echo "Available metrics:"
|
|
||||||
for metric in ${__METRICS[@]}; do
|
|
||||||
if ! is_function __m_${metric}_docs; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[$metric]"
|
|
||||||
__m_${metric}_docs
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
|
|
||||||
report () {
|
|
||||||
local result
|
|
||||||
if [ -z $2 ]; then
|
|
||||||
label=$metric
|
|
||||||
result="$1"
|
|
||||||
else
|
|
||||||
label="$metric.$1"
|
|
||||||
result="$2"
|
|
||||||
fi
|
|
||||||
__r_${REPORTER}_report $label $result
|
|
||||||
}
|
|
||||||
|
|
||||||
# collect metrics
|
|
||||||
while true; do
|
|
||||||
for metric in ${__METRICS[@]}; do
|
|
||||||
if ! is_function __m_${metric}_collect; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
__m_${metric}_collect
|
|
||||||
done
|
|
||||||
|
|
||||||
sleep $INTERVAL
|
|
||||||
done
|
|
Loading…
Reference in New Issue