add defaults() fn. add --print-config. config loader now fails on error

This commit is contained in:
Patrick Stadler 2015-03-21 21:19:08 +01:00
parent e0a528859f
commit b518c807d1
16 changed files with 232 additions and 125 deletions

View File

@ -55,6 +55,6 @@ TODO: how to write custom reporters
- README - README
- config file docs - config file docs
- config file auto-generation
- load custom/contrib metrics and reporters - load custom/contrib metrics and reporters
- enable -m <alias> / -r <alias>
- allow multiple reporters? - allow multiple reporters?

View File

@ -9,7 +9,22 @@ done
__AVAILABLE_METRICS= __AVAILABLE_METRICS=
__AVAILABLE_REPORTERS= __AVAILABLE_REPORTERS=
main_defaults () {
if [ -z $INTERVAL ]; then
INTERVAL=2
fi
if [ -z $METRICS ]; then
METRICS=cpu,disk_io,disk_usage,heartbeat,memory,network_io,swap
fi
if [ -z $REPORTER ]; then
REPORTER=stdout
fi
}
main_load () { main_load () {
# set defaults
main_defaults
# load reporter # load reporter
for file in ./reporters/*.sh; do for file in ./reporters/*.sh; do
local filename=$(basename $file) local filename=$(basename $file)
@ -54,11 +69,14 @@ main_init () {
done done
# init reporter # init reporter
if is_function __r_${__REPORTER}_defaults; then
__r_${__REPORTER}_defaults
fi
if is_function __r_${__REPORTER}_config; then if is_function __r_${__REPORTER}_config; then
__r_${__REPORTER}_config __r_${__REPORTER}_config
fi fi
if is_function __r_${__REPORTER}_init; then if is_function __r_${__REPORTER}_start; then
__r_${__REPORTER}_init __r_${__REPORTER}_start
fi fi
} }
@ -77,6 +95,35 @@ main_collect () {
( (
local metric_name=$(get_name $metric) local metric_name=$(get_name $metric)
local metric_alias=$(get_alias $metric) local metric_alias=$(get_alias $metric)
# init metric
load_metric_with_prefix __m_${metric_alias}_ ./metrics/${metric_name}.sh
if is_function __m_${metric_alias}_defaults; then
__m_${metric_alias}_defaults
fi
if is_function __m_${metric_alias}_config; then
__m_${metric_alias}_config
fi
if is_function __m_${metric_alias}_start; then
__m_${metric_alias}_start
fi
if ! is_function __m_${metric_alias}_collect; then
continue
fi
# collect metrics
trap "
verbose \"Stopping metric '${metric_alias}'\"
if is_function __m_${metric_alias}_stop; then
__m_${metric_alias}_stop
fi
exit 0
" 13
# used by metrics to return results # used by metrics to return results
report () { report () {
local _r_label _r_result local _r_label _r_result
@ -92,30 +139,6 @@ main_collect () {
fi fi
} }
# init metric
if is_function __m_${metric_alias}_config; then
__m_${metric_alias}_config
fi
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 while true; do
__m_${metric_alias}_collect __m_${metric_alias}_collect
sleep $INTERVAL sleep $INTERVAL
@ -132,13 +155,13 @@ main_collect () {
} }
main_terminate () { main_terminate () {
# terminate reporter # stop reporter
if is_function __r_${__REPORTER}_terminate; then verbose "Stopping reporter '${__REPORTER}'"
verbose "Stopping reporter ${__REPORTER}" if is_function __r_${__REPORTER}_stop; then
__r_${__REPORTER}_terminate __r_${__REPORTER}_stop
fi fi
verbose -n "Cleaning up..." verbose "Cleaning up..."
# delete temporary directory # delete temporary directory
if [ -d $TEMP_DIR ]; then if [ -d $TEMP_DIR ]; then
rmdir $TEMP_DIR rmdir $TEMP_DIR
@ -146,8 +169,8 @@ main_terminate () {
verbose "done" verbose "done"
} }
main_docs () { main_print_docs () {
echo "# Metrics" echo "# METRICS"
for metric in $__AVAILABLE_METRICS; do for metric in $__AVAILABLE_METRICS; do
load_metric_with_prefix __m_${metric}_ ./metrics/${metric}.sh load_metric_with_prefix __m_${metric}_ ./metrics/${metric}.sh
@ -156,6 +179,10 @@ main_docs () {
continue continue
fi fi
if is_function __m_${metric}_defaults; then
__m_${metric}_defaults
fi
echo echo
echo "[$metric]" echo "[$metric]"
__m_${metric}_docs __m_${metric}_docs
@ -168,8 +195,48 @@ main_docs () {
continue continue
fi fi
if is_function __r_${reporter}_defaults; then
__r_${reporter}_defaults
fi
echo echo
echo "[$reporter]" echo "[$reporter]"
__r_${reporter}_docs __r_${reporter}_docs
done done
} }
main_print_config () {
echo "[metrics.sh]"
echo ";INTERVAL=$INTERVAL"
echo ";METRICS=$METRICS"
echo ";REPORTER=$REPORTER"
for metric in $__AVAILABLE_METRICS; do
load_metric_with_prefix __m_${metric}_ ./metrics/${metric}.sh
if is_function __m_${metric}_defaults; then
__m_${metric}_defaults
fi
echo
echo ";[metric $metric]"
if ! is_function __m_${metric}_docs; then
continue
fi
print_prefixed ";" "$(__m_${metric}_docs)"
done
for reporter in $__AVAILABLE_REPORTERS; do
if ! is_function __r_${reporter}_docs; then
continue
fi
if is_function __r_${reporter}_defaults; then
__r_${reporter}_defaults
fi
echo
echo ";[reporter $reporter]"
print_prefixed ";" "$(__r_${reporter}_docs)"
done
}

View File

@ -48,8 +48,13 @@ parse_config () {
return return
fi fi
#echo "${fn_name}_config () { ${_body}; }" if ! eval "$_body" > /dev/null 2>&1; then
eval "${fn_name}_config () { ${_body}; }" echo "Error parsing config section: $_name: $_body"
exit 1
fi
#echo "${fn_name}_config () { $_body; }"
eval "${fn_name}_config () { $_body; }"
} }
for line in $(cat $1); do for line in $(cat $1); do

View File

@ -9,8 +9,6 @@ iso_date () {
} }
in_array () { in_array () {
local item=$1
local arr=$2
echo " $2 " | grep -q " $1 " echo " $2 " | grep -q " $1 "
} }
@ -24,3 +22,7 @@ unique_id () {
echo __u_$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 10) echo __u_$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 10)
LC_ALL=$RESTORE_LC_ALL LC_ALL=$RESTORE_LC_ALL
} }
print_prefixed () {
printf "$2" | sed -e "s/^/$1/g"
}

View File

@ -6,9 +6,10 @@ load_reporter_with_prefix () {
local content local content
content=$(sed \ content=$(sed \
-e 's/^[[:space:]]*\(init[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(defaults[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(start[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(report[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(report[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(terminate[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(stop[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(docs[ ]*()[ ]*{\)/'"$prefix"'\1/' $file) -e 's/^[[:space:]]*\(docs[ ]*()[ ]*{\)/'"$prefix"'\1/' $file)
eval "$content" eval "$content"
@ -21,9 +22,10 @@ load_metric_with_prefix () {
# dash will error if this variable is defined as `local` # dash will error if this variable is defined as `local`
content=$(sed \ content=$(sed \
-e 's/^[[:space:]]*\(init[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(defaults[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(start[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(collect[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(collect[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(terminate[ ]*()[ ]*{\)/'"$prefix"'\1/' \ -e 's/^[[:space:]]*\(stop[ ]*()[ ]*{\)/'"$prefix"'\1/' \
-e 's/^[[:space:]]*\(docs[ ]*()[ ]*{\)/'"$prefix"'\1/' $file) -e 's/^[[:space:]]*\(docs[ ]*()[ ]*{\)/'"$prefix"'\1/' $file)
eval "$content" eval "$content"

View File

@ -1,18 +1,12 @@
#!/bin/sh #!/bin/sh
# config
INTERVAL=2
REPORTER=stdout
METRICS=cpu,disk_io,disk_usage,heartbeat,memory,network_io,swap
CONFIG_FILE=
# env # env
LC_ALL=en_US.UTF-8 LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8 LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8 LANGUAGE=en_US.UTF-8
usage () { usage () {
echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i]" echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C]"
} }
help () { help () {
@ -27,34 +21,40 @@ help () {
echo " -i, --interval <seconds> collect metrics every n seconds (default: 2)" echo " -i, --interval <seconds> collect metrics every n seconds (default: 2)"
echo " -v, --verbose enable verbose mode" echo " -v, --verbose enable verbose mode"
echo " -d, --docs show documentation" echo " -d, --docs show documentation"
echo " -C, --print-config print output to be used in a config file"
echo " -h, --help show this text" echo " -h, --help show this text"
echo echo
} }
# handle opts # handle opts
opt_config_file=
opt_metrics=
opt_reporter=
opt_interval=
opt_docs=false opt_docs=false
opt_verbose=false opt_verbose=false
opt_print_config=false
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
-c|--config) -c|--config)
shift shift
CONFIG_FILE=$1 opt_config_file=$1
;; ;;
-m|--metrics) -m|--metrics)
shift shift
METRICS=$1 opt_metrics=$1
;; ;;
-r|--reporter) -r|--reporter)
shift shift
REPORTER=$1 opt_reporter=$1
;; ;;
-i|--interval) -i|--interval)
shift shift
INTERVAL=$1 opt_interval=$1
;; ;;
-v|-verbose) -v|-verbose)
@ -65,6 +65,10 @@ while [ $# -gt 0 ]; do
opt_docs=true opt_docs=true
;; ;;
-C|--print-config)
opt_print_config=true
;;
-h|--help) -h|--help)
help help
exit exit
@ -85,29 +89,30 @@ done
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
verbose "PID: $$" verbose "PID: $$"
verbose "OS detected: $OS_TYPE" verbose "OS detected: $OS_TYPE"
fi
main_load main_load
verbose "Available metrics: $__AVAILABLE_METRICS" verbose "Available metrics: $__AVAILABLE_METRICS"
verbose "Available reporters: $__AVAILABLE_REPORTERS" verbose "Available reporters: $__AVAILABLE_REPORTERS"
if [ $opt_docs = true ]; then if [ $opt_docs = true ]; then
main_docs main_print_docs
exit exit
fi fi
if [ -n "$CONFIG_FILE" ]; then if [ $opt_print_config = true ]; then
verbose "Loading configuration file: $CONFIG_FILE" main_print_config
exit
parse_config $CONFIG_FILE
if [ $? -ne 0 ]; then
exit 1
fi fi
if is_function main_config; then if [ -n "$opt_config_file" ]; then
main_config verbose "Loading configuration file: $opt_config_file"
parse_config $opt_config_file
if [ $? -ne 0 ]; then
exit 1
fi fi
configured_reporters=$(get_configured_reporters) configured_reporters=$(get_configured_reporters)
@ -121,6 +126,21 @@ if [ -n "$CONFIG_FILE" ]; then
fi fi
fi fi
# --reporter always wins
if [ -n "$opt_reporter" ]; then
REPORTER=$opt_reporter
fi
# --metrics always wins
if [ -n "$opt_metrics" ]; then
METRICS=$opt_metrics
fi
# --interval always wins
if [ -n "$opt_interval" ]; then
INTERVAL=$opt_interval
fi
main_init "$METRICS" "$REPORTER" main_init "$METRICS" "$REPORTER"
verbose "Using metrics: $__METRICS" verbose "Using metrics: $__METRICS"
verbose "Using reporter: $__REPORTER" verbose "Using reporter: $__REPORTER"

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { defaults () {
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"
@ -8,10 +8,11 @@ init () {
DISK_IO_MOUNTPOINT="/dev/vda" DISK_IO_MOUNTPOINT="/dev/vda"
fi fi
fi fi
}
start () {
readonly __disk_io_fifo=$TEMP_DIR/$(unique_id) readonly __disk_io_fifo=$TEMP_DIR/$(unique_id)
mkfifo $__disk_io_fifo mkfifo $__disk_io_fifo
__disk_io_bgproc &
}
if is_osx; then if is_osx; then
__disk_io_bgproc () { __disk_io_bgproc () {
@ -27,11 +28,14 @@ else
} }
fi fi
__disk_io_bgproc &
}
collect () { collect () {
report $(cat $__disk_io_fifo) report $(cat $__disk_io_fifo)
} }
terminate () { stop () {
if [ ! -z $__disk_io_fifo ] && [ -p $__disk_io_fifo ]; then if [ ! -z $__disk_io_fifo ] && [ -p $__disk_io_fifo ]; then
rm $__disk_io_fifo rm $__disk_io_fifo
fi fi
@ -39,5 +43,5 @@ terminate () {
docs () { docs () {
echo "Disk I/O in MB/s." echo "Disk I/O in MB/s."
echo "\$DISK_IO_MOUNTPOINT=" echo "DISK_IO_MOUNTPOINT=$DISK_IO_MOUNTPOINT"
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { defaults () {
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"
@ -17,5 +17,5 @@ collect () {
docs () { docs () {
echo "Disk usage percentage for a file system at a given mount point." echo "Disk usage percentage for a file system at a given mount point."
echo "\$DISK_USAGE_MOUNTPOINT=" echo "DISK_USAGE_MOUNTPOINT=$DISK_USAGE_MOUNTPOINT"
} }

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
if is_osx; then if is_osx; then
init () { start () {
readonly __memory_os_memsize=$(sysctl -n hw.memsize) readonly __memory_os_memsize=$(sysctl -n hw.memsize)
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { defaults () {
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"
@ -8,32 +8,35 @@ init () {
NETWORK_IO_INTERFACE="eth0" NETWORK_IO_INTERFACE="eth0"
fi fi
fi fi
readonly __network_io_divisor=$(($INTERVAL * 1024))
} }
start () {
readonly __network_io_divisor=$(($INTERVAL * 1024))
if is_osx; then if is_osx; then
__network_io_collect () { get_netstat () {
netstat -b -I $NETWORK_IO_INTERFACE | awk '{ print $7" "$10 }' | tail -n 1 netstat -b -I $NETWORK_IO_INTERFACE | awk '{ print $7" "$10 }' | tail -n 1
} }
else else
__network_io_collect () { get_netstat () {
cat /proc/net/dev | awk -v iface_regex="$NETWORK_IO_INTERFACE:" \ cat /proc/net/dev | awk -v iface_regex="$NETWORK_IO_INTERFACE:" \
'$0 ~ iface_regex { print $2" "$10 }' '$0 ~ iface_regex { print $2" "$10 }'
} }
fi fi
__network_io_calc_kBps() { calc_kBps() {
echo $1 $2 | awk -v divisor=$__network_io_divisor \ echo $1 $2 | awk -v divisor=$__network_io_divisor \
'{ printf "%.2f", ($1 - $2) / divisor }' '{ printf "%.2f", ($1 - $2) / divisor }'
} }
}
collect () { collect () {
local sample local sample
sample=$(__network_io_collect) sample=$(get_netstat)
if [ ! -z "$__network_io_sample" ]; then if [ ! -z "$__network_io_sample" ]; then
report "in" $(__network_io_calc_kBps $(echo $sample | awk '{print $1}') \ report "in" $(calc_kBps $(echo $sample | awk '{print $1}') \
$(echo $__network_io_sample | awk '{print $1}')) $(echo $__network_io_sample | awk '{print $1}'))
report "out" $(__network_io_calc_kBps $(echo $sample | awk '{print $2}') \ report "out" $(calc_kBps $(echo $sample | awk '{print $2}') \
$(echo $__network_io_sample | awk '{print $2}')) $(echo $__network_io_sample | awk '{print $2}'))
fi fi
__network_io_sample="$sample" __network_io_sample="$sample"
@ -41,5 +44,5 @@ collect () {
docs () { docs () {
echo "Network traffic in kB/s." echo "Network traffic in kB/s."
echo "\$NETWORK_IO_INTERFACE=" echo "NETWORK_IO_INTERFACE=$NETWORK_IO_INTERFACE"
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { start () {
if [ -z $PING_REMOTE_HOST ]; then if [ -z $PING_REMOTE_HOST ]; then
echo "Error: ping metric requires \$PING_REMOTE_HOST to be specified" echo "Error: ping metric requires \$PING_REMOTE_HOST to be specified"
exit 1 exit 1
@ -19,5 +19,5 @@ collect () {
docs () { docs () {
echo "Check if remote host is reachable by sending a single ping." echo "Check if remote host is reachable by sending a single ping."
echo "Reports '1' if ping was successful, '0' if not." echo "Reports '1' if ping was successful, '0' if not."
echo "\$PING_REMOTE_HOST=" echo "PING_REMOTE_HOST=$PING_REMOTE_HOST"
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { start () {
if [ -z $FILE_LOCATION ]; then if [ -z $FILE_LOCATION ]; then
echo "Error: file reporter requires \$FILE_LOCATION to be specified" echo "Error: file reporter requires \$FILE_LOCATION to be specified"
exit 1 exit 1
@ -20,5 +20,5 @@ report () {
docs () { docs () {
echo "Write to a file or named pipe." echo "Write to a file or named pipe."
echo "\$FILE_LOCATION=" echo "FILE_LOCATION=$FILE_LOCATION"
} }

View File

@ -1,15 +1,17 @@
#!/bin/sh #!/bin/sh
init () { defaults () {
if [ -z $INFLUXDB_SEND_HOSTNAME ]; then
INFLUXDB_SEND_HOSTNAME=true
fi
}
start () {
if [ -z $INFLUXDB_API_ENDPOINT ]; then if [ -z $INFLUXDB_API_ENDPOINT ]; then
echo "Error: influxdb requires \$INFLUXDB_API_ENDPOINT to be specified" echo "Error: influxdb requires \$INFLUXDB_API_ENDPOINT to be specified"
exit 1 exit 1
fi fi
if [ -z $INFLUXDB_SEND_HOSTNAME ]; then
INFLUXDB_SEND_HOSTNAME=true
fi
if [ "$INFLUXDB_SEND_HOSTNAME" = true ]; then if [ "$INFLUXDB_SEND_HOSTNAME" = true ]; then
__influxdb_columns="[\"value\",\"host\"]" __influxdb_columns="[\"value\",\"host\"]"
__influxdb_hostname=$(hostname) __influxdb_hostname=$(hostname)
@ -34,6 +36,6 @@ report () {
docs () { docs () {
echo "Send data to InfluxDB." echo "Send data to InfluxDB."
echo "\$INFLUXDB_API_ENDPOINT=" echo "INFLUXDB_API_ENDPOINT=$INFLUXDB_API_ENDPOINT"
echo "\$INFLUXDB_SEND_HOSTNAME=true" echo "INFLUXDB_SEND_HOSTNAME=$INFLUXDB_SEND_HOSTNAME"
} }

View File

@ -1,6 +1,12 @@
#!/bin/sh #!/bin/sh
init() { defaults () {
if [ -z $KEEN_IO_EVENT_COLLECTION ]; then
KEEN_IO_EVENT_COLLECTION=$(hostname)
fi
}
start() {
if [ -z $KEEN_IO_PROJECT_ID ]; then if [ -z $KEEN_IO_PROJECT_ID ]; then
echo "Error: keen_io requires \$KEEN_IO_PROJECT_ID to be specified" echo "Error: keen_io requires \$KEEN_IO_PROJECT_ID to be specified"
exit 1 exit 1
@ -11,10 +17,6 @@ init() {
exit 1 exit 1
fi fi
if [ -z $KEEN_IO_EVENT_COLLECTION ]; then
KEEN_IO_EVENT_COLLECTION=$(hostname)
fi
__keen_io_api_url="https://api.keen.io/3.0" __keen_io_api_url="https://api.keen.io/3.0"
__keen_io_api_url="$__keen_io_api_url/projects/$KEEN_IO_PROJECT_ID" __keen_io_api_url="$__keen_io_api_url/projects/$KEEN_IO_PROJECT_ID"
__keen_io_api_url="$__keen_io_api_url/events/$KEEN_IO_EVENT_COLLECTION" __keen_io_api_url="$__keen_io_api_url/events/$KEEN_IO_EVENT_COLLECTION"
@ -31,7 +33,7 @@ report () {
docs () { docs () {
echo "Send data to Keen IO (https://keen.io)." echo "Send data to Keen IO (https://keen.io)."
echo "\$KEEN_IO_WRITE_KEY=<write_key>" echo "KEEN_IO_WRITE_KEY=$KEEN_IO_WRITE_KEY"
echo "\$KEEN_IO_PROJECT_ID=<project_id>" echo "KEEN_IO_PROJECT_ID=$KEEN_IO_PROJECT_ID"
echo "\$KEEN_IO_EVENT_COLLECTION=$(hostname)" echo "KEEN_IO_EVENT_COLLECTION=$KEEN_IO_EVENT_COLLECTION"
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
init () { start () {
if [ -z $STATHAT_API_KEY ]; then if [ -z $STATHAT_API_KEY ]; then
echo "Error: stathat requires \$STATHAT_API_KEY to be specified" echo "Error: stathat requires \$STATHAT_API_KEY to be specified"
exit 1 exit 1
@ -17,5 +17,5 @@ report () {
docs () { docs () {
echo "Send data to StatHat (https://www.stathat.com)." echo "Send data to StatHat (https://www.stathat.com)."
echo "\$STATHAT_API_KEY=<ez_key>" echo "STATHAT_API_KEY=$STATHAT_API_KEY"
} }

View File

@ -8,5 +8,5 @@ report () {
} }
docs () { docs () {
echo "Print to standard output (e.g. the TTY you're running the script in)" echo "Print to standard output, e.g. the TTY you're running the script in."
} }