mirror of
https://github.com/pstadler/metrics.sh.git
synced 2025-02-28 13:59:12 -05:00
fully working config handling. support for multiple metrics of the same type. implement signal trapping
This commit is contained in:
parent
f06e238b85
commit
e0a528859f
@ -7,7 +7,7 @@ metrics.sh is a lightweight metrics collection and fowarding utility implemented
|
|||||||
```
|
```
|
||||||
$ ./metrics.sh --help
|
$ ./metrics.sh --help
|
||||||
|
|
||||||
Usage: ./metrics.sh [-d] [-h] [-v] [-m metrics] [-r reporter] [-i interval]
|
Usage: ./metrics.sh [-d] [-h] [-v] [-c] [-m] [-r] [-i]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
@ -54,8 +54,7 @@ TODO: how to write custom reporters
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- README
|
- README
|
||||||
- config file support
|
- config file docs
|
||||||
- config file auto-generation
|
- config file auto-generation
|
||||||
- load custom/contrib metrics and reporters
|
- load custom/contrib metrics and reporters
|
||||||
- same metric multiple times? (e.g. disk_usage for multiple devices)
|
|
||||||
- allow multiple reporters?
|
- allow multiple reporters?
|
123
lib/main.sh
123
lib/main.sh
@ -28,9 +28,6 @@ main_load () {
|
|||||||
# register metric
|
# register metric
|
||||||
__AVAILABLE_METRICS=$(trim "$__AVAILABLE_METRICS $metric")
|
__AVAILABLE_METRICS=$(trim "$__AVAILABLE_METRICS $metric")
|
||||||
done
|
done
|
||||||
|
|
||||||
load_metric_with_prefix __m_${metric}_ $file
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main_init () {
|
main_init () {
|
||||||
@ -41,12 +38,6 @@ main_init () {
|
|||||||
# create temp dir
|
# create temp dir
|
||||||
TEMP_DIR=$(make_temp_dir)
|
TEMP_DIR=$(make_temp_dir)
|
||||||
|
|
||||||
# register trap
|
|
||||||
trap '
|
|
||||||
main_terminate
|
|
||||||
trap - TERM && kill -- -$$ INT TERM EXIT
|
|
||||||
' INT TERM EXIT
|
|
||||||
|
|
||||||
# check if reporter exists
|
# check if reporter exists
|
||||||
if ! in_array $__REPORTER "$__AVAILABLE_REPORTERS"; then
|
if ! in_array $__REPORTER "$__AVAILABLE_REPORTERS"; then
|
||||||
echo "Error: reporter '$__REPORTER' is not available"
|
echo "Error: reporter '$__REPORTER' is not available"
|
||||||
@ -63,78 +54,96 @@ main_init () {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# init reporter
|
# init reporter
|
||||||
|
if is_function __r_${__REPORTER}_config; then
|
||||||
|
__r_${__REPORTER}_config
|
||||||
|
fi
|
||||||
if is_function __r_${__REPORTER}_init; then
|
if is_function __r_${__REPORTER}_init; then
|
||||||
__r_${__REPORTER}_init
|
__r_${__REPORTER}_init
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# init metrics
|
|
||||||
for metric in $__METRICS; do
|
|
||||||
local metric_name=$(get_name $metric)
|
|
||||||
local metric_alias=$(get_alias $metric)
|
|
||||||
|
|
||||||
load_metric_with_prefix __m_${metric_alias}_ ./metrics/${metric_name}.sh
|
|
||||||
|
|
||||||
if ! is_function __m_${metric_alias}_init; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
__m_${metric_alias}_init
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main_collect () {
|
main_collect () {
|
||||||
# used by metrics to return results
|
# register trap
|
||||||
report () {
|
trap '
|
||||||
local _r_label _r_result
|
trap "" 13
|
||||||
if [ -z $2 ]; then
|
trap - INT TERM EXIT
|
||||||
_r_label=$metric
|
echo Exit signal received.
|
||||||
_r_result="$1"
|
kill -13 -$$
|
||||||
else
|
' 13 INT TERM EXIT
|
||||||
_r_label="$metric.$1"
|
|
||||||
_r_result="$2"
|
|
||||||
fi
|
|
||||||
if is_number $_r_result; then
|
|
||||||
__r_${__REPORTER}_report $_r_label $_r_result
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# collect metrics
|
# collect metrics
|
||||||
for metric in $__METRICS; do
|
for metric in $__METRICS; do
|
||||||
metric=$(get_alias $metric)
|
# run in subshell to isolate scope
|
||||||
if ! is_function __m_${metric}_collect; then
|
(
|
||||||
continue
|
local metric_name=$(get_name $metric)
|
||||||
fi
|
local metric_alias=$(get_alias $metric)
|
||||||
|
# used by metrics to return results
|
||||||
|
report () {
|
||||||
|
local _r_label _r_result
|
||||||
|
if [ -z $2 ]; then
|
||||||
|
_r_label=$metric_alias
|
||||||
|
_r_result="$1"
|
||||||
|
else
|
||||||
|
_r_label="$metric_alias.$1"
|
||||||
|
_r_result="$2"
|
||||||
|
fi
|
||||||
|
if is_number $_r_result; then
|
||||||
|
__r_${__REPORTER}_report $_r_label $_r_result
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# fork
|
# init metric
|
||||||
(while true; do
|
if is_function __m_${metric_alias}_config; then
|
||||||
__m_${metric}_collect
|
__m_${metric_alias}_config
|
||||||
sleep $INTERVAL
|
fi
|
||||||
done) &
|
|
||||||
|
load_metric_with_prefix __m_${metric_alias}_ ./metrics/${metric_name}.sh
|
||||||
|
|
||||||
|
if is_function __m_${metric_alias}_init; then
|
||||||
|
__m_${metric_alias}_init
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! is_function __m_${metric_alias}_collect; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# collect metrics
|
||||||
|
trap "
|
||||||
|
if is_function __m_${metric_alias}_terminate; then
|
||||||
|
verbose 'Stopping metric ${metric_alias}'
|
||||||
|
__m_${metric_alias}_terminate
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
" 13
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
__m_${metric_alias}_collect
|
||||||
|
sleep $INTERVAL
|
||||||
|
done
|
||||||
|
) &
|
||||||
done
|
done
|
||||||
|
|
||||||
# run forever
|
# wait until interrupted
|
||||||
sleep 2147483647 # `sleep infinity` is not portable
|
wait
|
||||||
|
# then wait again for processes to end
|
||||||
|
wait
|
||||||
|
|
||||||
|
main_terminate
|
||||||
}
|
}
|
||||||
|
|
||||||
main_terminate () {
|
main_terminate () {
|
||||||
# terminate metrics
|
|
||||||
for metric in $__METRICS; do
|
|
||||||
metric=$(get_alias $metric)
|
|
||||||
if ! is_function __m_${metric}_terminate; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
__m_${metric}_terminate
|
|
||||||
done
|
|
||||||
|
|
||||||
# terminate reporter
|
# terminate reporter
|
||||||
if is_function __r_${__REPORTER}_terminate; then
|
if is_function __r_${__REPORTER}_terminate; then
|
||||||
|
verbose "Stopping reporter ${__REPORTER}"
|
||||||
__r_${__REPORTER}_terminate
|
__r_${__REPORTER}_terminate
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
verbose -n "Cleaning up..."
|
||||||
# delete temporary directory
|
# delete temporary directory
|
||||||
if [ -d $TEMP_DIR ]; then
|
if [ -d $TEMP_DIR ]; then
|
||||||
rmdir $TEMP_DIR
|
rmdir $TEMP_DIR
|
||||||
fi
|
fi
|
||||||
|
verbose "done"
|
||||||
}
|
}
|
||||||
|
|
||||||
main_docs () {
|
main_docs () {
|
||||||
|
@ -24,7 +24,6 @@ parse_config () {
|
|||||||
|
|
||||||
local _group
|
local _group
|
||||||
local _name
|
local _name
|
||||||
local _alias
|
|
||||||
local _body
|
local _body
|
||||||
|
|
||||||
end_section () {
|
end_section () {
|
||||||
@ -34,20 +33,16 @@ parse_config () {
|
|||||||
|
|
||||||
local fn_name
|
local fn_name
|
||||||
if [ "$_group" = "reporter" ]; then
|
if [ "$_group" = "reporter" ]; then
|
||||||
__CFG_REPORTERS=$(trim "${__CFG_REPORTERS} ${_name}:${_alias}")
|
__CFG_REPORTERS=$(trim "${__CFG_REPORTERS} ${_name}")
|
||||||
fn_name="__r_"
|
fn_name="__r_"
|
||||||
elif [ "$_group" = "metric" ]; then
|
elif [ "$_group" = "metric" ]; then
|
||||||
__CFG_METRICS=$(trim "${__CFG_METRICS} ${_name}:${_alias}")
|
__CFG_METRICS=$(trim "${__CFG_METRICS} ${_name}")
|
||||||
fn_name="__m_"
|
fn_name="__m_"
|
||||||
else
|
else
|
||||||
fn_name="global"
|
fn_name="main"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$_alias" ]; then
|
fn_name=${fn_name}$(get_alias $_name)
|
||||||
fn_name="${fn_name}${_alias}"
|
|
||||||
elif [ -n "$_name" ]; then
|
|
||||||
fn_name="${fn_name}${_name}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$_body" ]; then
|
if [ -z "$_body" ]; then
|
||||||
return
|
return
|
||||||
@ -68,7 +63,7 @@ parse_config () {
|
|||||||
local _section=$(echo $line | grep '^\[.*' | sed 's/\[\(.*\)\]/\1/')
|
local _section=$(echo $line | grep '^\[.*' | sed 's/\[\(.*\)\]/\1/')
|
||||||
if [ -n "$_section" ]; then
|
if [ -n "$_section" ]; then
|
||||||
end_section
|
end_section
|
||||||
unset _group _name _alias _body
|
unset _group _name _body
|
||||||
|
|
||||||
_group=$(echo $_section | awk '{ print $1 }')
|
_group=$(echo $_section | awk '{ print $1 }')
|
||||||
|
|
||||||
@ -78,13 +73,11 @@ parse_config () {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$_group" = "metrics.sh" ]; then
|
if [ "$_group" = "metrics.sh" ]; then
|
||||||
_group="global"
|
_group="main"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_section=$(echo $_section | awk '{ print $2 }')
|
_name=$(echo $_section | awk '{ print $2 }')
|
||||||
_name=$(echo $_section | awk 'BEGIN { FS=":" } { print $1 }')
|
|
||||||
_alias=$(echo $_section | awk 'BEGIN { FS=":" } { print $2 }')
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -16,4 +16,11 @@ in_array () {
|
|||||||
|
|
||||||
trim () {
|
trim () {
|
||||||
echo $1 | sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'
|
echo $1 | sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_id () {
|
||||||
|
RESTORE_LC_ALL=$LC_ALL
|
||||||
|
LC_ALL=C
|
||||||
|
echo __u_$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 10)
|
||||||
|
LC_ALL=$RESTORE_LC_ALL
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ LANG=en_US.UTF-8
|
|||||||
LANGUAGE=en_US.UTF-8
|
LANGUAGE=en_US.UTF-8
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
echo " Usage: $0 [-d] [-h] [-v] [-m metrics] [-r reporter] [-i interval]"
|
echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i]"
|
||||||
}
|
}
|
||||||
|
|
||||||
help () {
|
help () {
|
||||||
@ -82,10 +82,11 @@ done
|
|||||||
# run
|
# run
|
||||||
. ./lib/main.sh
|
. ./lib/main.sh
|
||||||
|
|
||||||
if [ $opt_verbose = "true" ]; then
|
if [ $opt_verbose = true ]; then
|
||||||
verbose_on
|
verbose_on
|
||||||
verbose "Started in verbose mode"
|
verbose "Started in verbose mode"
|
||||||
fi
|
fi
|
||||||
|
verbose "PID: $$"
|
||||||
verbose "OS detected: $OS_TYPE"
|
verbose "OS detected: $OS_TYPE"
|
||||||
|
|
||||||
main_load
|
main_load
|
||||||
@ -105,8 +106,8 @@ if [ -n "$CONFIG_FILE" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if is_function global_config; then
|
if is_function main_config; then
|
||||||
global_config
|
main_config
|
||||||
fi
|
fi
|
||||||
|
|
||||||
configured_reporters=$(get_configured_reporters)
|
configured_reporters=$(get_configured_reporters)
|
||||||
|
@ -8,7 +8,7 @@ init () {
|
|||||||
DISK_IO_MOUNTPOINT="/dev/vda"
|
DISK_IO_MOUNTPOINT="/dev/vda"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
readonly __disk_io_fifo=$TEMP_DIR/disk_io
|
readonly __disk_io_fifo=$TEMP_DIR/$(unique_id)
|
||||||
mkfifo $__disk_io_fifo
|
mkfifo $__disk_io_fifo
|
||||||
__disk_io_bgproc &
|
__disk_io_bgproc &
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user