From b20446507c9c45aee2c0e69aa532a5317ac7b1bb Mon Sep 17 00:00:00 2001 From: Patrick Stadler Date: Thu, 19 Mar 2015 21:14:14 +0100 Subject: [PATCH] started working on config loader --- README.md | 7 ++-- lib/utils/config.sh | 97 +++++++++++++++++++++++++++++++++++++++++++++ metrics.sh | 30 ++++++++++++++ 3 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 lib/utils/config.sh diff --git a/README.md b/README.md index 11594b6..4e63554 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # metrics.sh -metrics.sh is a lightweight metrics collection and fowarding utility implemented in portable POSIX compliant shell scripts. A transparent interface based on hooks enables writing custom metric collectors and forwarders in an elegant way. - -Besides having a low impact on system resources, which makes metric.sh a suitable solution for running in virtual environments and servers with limited capacities, simplicty is the main goal of this project, hence its documentation shall fit in a single README. +metrics.sh is a lightweight metrics collection and fowarding utility implemented in portable POSIX compliant shell scripts. A transparent interface based on hooks enables writing custom metric collectors and reporters in an elegant way. ## Usage @@ -13,6 +11,7 @@ $ ./metrics.sh --help Options: + -c, --config path to config file -m, --metrics comma-separated list of metrics to collect -r, --reporter use specified reporter (default: stdout) -i, --interval collect metrics every n seconds (default: 2) @@ -31,7 +30,7 @@ TODO: /etc/init.d ### Requirements -metrics.sh has been tested on Ubuntu and Mac OS X but is supposed to run on most *NIX-line operating systems. Some of the provided metrics require [procfs](http://en.wikipedia.org/wiki/Procfs) to be available. +metrics.sh has been tested on Ubuntu and Mac OS X but is supposed to run on most *NIX-like operating systems. Some of the provided metrics require [procfs](http://en.wikipedia.org/wiki/Procfs) to be available. ## Metrics diff --git a/lib/utils/config.sh b/lib/utils/config.sh new file mode 100644 index 0000000..5d9f916 --- /dev/null +++ b/lib/utils/config.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +__CFG_REPORTERS= +__CFG_METRICS= + +get_configured_reporters () { + echo $__CFG_REPORTERS +} + +get_configured_metrics () { + echo $__CFG_METRICS +} + +parse_config () { + if [ ! -f "$1" ]; then + echo "Error: unable to load config file: ${1}" + return 1 + fi + + RESTORE_IFS=$IFS + # dash compatibility :-( + IFS=$' +' + + local _group + local _name + local _alias + local _body + + end_section () { + if [ -z "$_group" ]; then + return + fi + + local fn_name + if [ "$_group" = "reporter" ]; then + __CFG_REPORTERS=$(trim "${__CFG_REPORTERS} ${_name}:${_alias}") + fn_name="__r_" + elif [ "$_group" = "metric" ]; then + __CFG_METRICS=$(trim "${__CFG_METRICS} ${_name}:${_alias}") + fn_name="__m_" + else + fn_name="global" + fi + + if [ -n "$_alias" ]; then + fn_name="${fn_name}${_alias}" + elif [ -n "$_name" ]; then + fn_name="${fn_name}${_name}" + fi + + if [ -z "$_body" ]; then + return + fi + + #echo "${fn_name}_config () { ${_body}; }" + eval "${fn_name}_config () { ${_body}; }" + } + + for line in $(cat $1); do + # handle comments / empty lines + line=$(echo $line | grep -v '^\(#\|;\)') + + if [ -z "$line" ]; then + continue + fi + + local _section=$(echo $line | grep '^\[.*' | sed 's/\[\(.*\)\]/\1/') + if [ -n "$_section" ]; then + end_section + unset _group _name _alias _body + + _group=$(echo $_section | awk '{ print $1 }') + + if echo " metrics.sh metric reporter " | grep -q -v " $_group "; then + echo "Warning: unknown section in configuration file: $_section" + continue + fi + + if [ "$_group" = "metrics.sh" ]; then + _group="global" + continue + fi + + _section=$(echo $_section | awk '{ print $2 }') + _name=$(echo $_section | awk 'BEGIN { FS=":" } { print $1 } ') + _alias=$(echo $_section | awk 'BEGIN { FS=":" } { print $2 } ') + continue + fi + + _body=$(echo "${_body};${line}" | sed 's/^;//g') + done + + end_section + + IFS=$RESTORE_IFS +} \ No newline at end of file diff --git a/metrics.sh b/metrics.sh index a2483bb..fdce0b2 100755 --- a/metrics.sh +++ b/metrics.sh @@ -4,6 +4,7 @@ INTERVAL=2 REPORTER=stdout METRICS=cpu,disk_io,disk_usage,heartbeat,memory,network_io,swap +CONFIG_FILE= # env LC_ALL=en_US.UTF-8 @@ -20,6 +21,7 @@ help () { echo echo " Options: " echo + echo " -c, --config path to config file" echo " -m, --metrics comma-separated list of metrics to collect" echo " -r, --reporter use specified reporter (default: stdout)" echo " -i, --interval collect metrics every n seconds (default: 2)" @@ -35,6 +37,11 @@ opt_verbose=false while [ $# -gt 0 ]; do case $1 in + -c|--config) + shift + CONFIG_FILE=$1 + ;; + -m|--metrics) shift METRICS=$1 @@ -90,6 +97,29 @@ if [ $opt_docs = true ]; then exit fi +if [ -n "$CONFIG_FILE" ]; then + verbose "Loading configuration file: $CONFIG_FILE" + + parse_config $CONFIG_FILE + if [ $? -ne 0 ]; then + exit 1 + fi + + if is_function global_config; then + global_config + fi + + configured_reporters=$(get_configured_reporters) + if [ -n "$configured_reporters" ]; then + REPORTER=$configured_reporters + fi + + configured_metrics=$(get_configured_metrics) + if [ -n "$configured_metrics" ]; then + METRICS=$configured_metrics + fi +fi + main_init $METRICS $REPORTER verbose "Using metrics: $__METRICS" verbose "Using reporter: $__REPORTER"