mirror of
https://github.com/pstadler/metrics.sh.git
synced 2025-11-29 21:33:29 -05:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f28c79906 | ||
|
|
3fccd9615d | ||
|
|
2cca88ed8d | ||
|
|
bc23216756 | ||
|
|
8c5131c6ef | ||
|
|
0533eb0ac8 | ||
|
|
9023954f3f | ||
|
|
4f5ed15b98 | ||
|
|
2ed7792a20 | ||
|
|
3a2fff387d | ||
|
|
be4039d647 | ||
|
|
636feccd7c | ||
|
|
697b978d95 | ||
|
|
d8cd496543 | ||
|
|
215e50ecea | ||
|
|
5c0962e12b | ||
|
|
85ee93aec3 | ||
|
|
3a9c155b7e | ||
|
|
81ca6e0e57 | ||
|
|
b21a7c1269 | ||
|
|
129ece3e0b | ||
|
|
817a19d4d8 | ||
|
|
d5fbece5ae | ||
|
|
8882f19ab3 | ||
|
|
a0f29e6106 | ||
|
|
8623398d7d | ||
|
|
6544ba03a0 | ||
|
|
c956283fbe | ||
|
|
f2f3decd78 | ||
|
|
1f573df67e | ||
|
|
ae5f2a66ed | ||
|
|
72c2be5554 | ||
|
|
ff9ed8ac10 | ||
|
|
77629720aa |
63
README.md
63
README.md
@@ -1,12 +1,22 @@
|
||||
# metrics.sh
|
||||

|
||||
|
||||
metrics.sh is a lightweight metrics collection and fowarding daemon implemented in portable POSIX compliant shell scripts. A transparent interface based on hooks enables writing custom collectors and reporters in an elegant way.
|
||||
metrics.sh is a lightweight metrics collection and forwarding daemon implemented in portable POSIX compliant shell scripts. A transparent interface based on hooks enables writing custom collectors and reporters in an elegant way.
|
||||
|
||||
**Project philosophy**
|
||||
|
||||
- Flat learning curve
|
||||
- Easily extensible
|
||||
- Low impact on system resources
|
||||
- No compilation, custom interpreters and runtimes required
|
||||
- Freedom to choose any service for storage, charting and alerting
|
||||
- Open source, no proprietary parts
|
||||
- Community-driven development, growing number of included metrics over time
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
$ ./metrics.sh --help
|
||||
|
||||
|
||||
Usage: ./metrics.sh [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u]
|
||||
|
||||
Options:
|
||||
@@ -25,12 +35,15 @@ $ ./metrics.sh --help
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ git clone git@github.com:pstadler/metrics.sh.git
|
||||
$ git clone https://github.com/pstadler/metrics.sh.git
|
||||
```
|
||||
|
||||
See this [guide](init.d/README.md) how to run metrics.sh as a service on Linux.
|
||||
Or [here](systemd/README.md) for instructions to set metrics.sh up for systemd.
|
||||
|
||||
### Requirements
|
||||
|
||||
metrics.sh has been tested on Ubuntu 14.04 and Mac OS X but is supposed to run on most Unix-like operating systems. Some of the provided metrics require [procfs](http://en.wikipedia.org/wiki/Procfs) to be available when running on *nix. POSIX compliancy means that metrics.sh works with minimalistic command interpreters such as [dash](http://manpages.ubuntu.com/manpages/trusty/en/man1/dash.1.html). Built-in metrics do __not__ require root privileges.
|
||||
metrics.sh has been tested on Ubuntu 14.04 and Mac OS X but is supposed to run on most Unix-like operating systems. Some of the provided metrics require [procfs](http://en.wikipedia.org/wiki/Procfs) to be available when running on *nix. POSIX compliancy means that metrics.sh works with minimalistic command interpreters such as [dash](http://manpages.ubuntu.com/manpages/en/man1/dash.1.html). Built-in metrics do __not__ require root privileges.
|
||||
|
||||
## Metrics
|
||||
|
||||
@@ -47,14 +60,17 @@ Metric | Description
|
||||
|
||||
## Reporters
|
||||
|
||||
Reporter | Description
|
||||
--------------- | -------------
|
||||
`stdout` | Write to standard out (default)
|
||||
`file` | Write to a file or named pipe
|
||||
`statsd` | Send data to [StatsD](https://github.com/etsy/statsd)
|
||||
`influxdb` | Send data to [InfluxDB](http://influxdb.com/)
|
||||
`keen_io` | Send data to [Keen IO](https://keen.io)
|
||||
`stathat` | Send data to [StatHat](https://www.stathat.com)
|
||||
Reporter | Description
|
||||
---------------- | -------------
|
||||
`stdout` | Write to standard out (default)
|
||||
`file` | Write to a file or named pipe
|
||||
`udp` | Send data to any service via UDP
|
||||
`statsd` | Send data to [StatsD](https://github.com/etsy/statsd)
|
||||
`influxdb` | Send data to [InfluxDB](http://influxdb.com/)
|
||||
`prometheus` | Provide HTTP endpoint for [Prometheus](http://prometheus.io/)
|
||||
`keen_io` | Send data to [Keen IO](https://keen.io)
|
||||
`stathat` | Send data to [StatHat](https://www.stathat.com)
|
||||
`logentries_com` | Send data to [Logentries](https://logentries.com/)
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -80,7 +96,7 @@ $ DISK_USAGE_MOUNTPOINT=/dev/vdb ./metrics.sh -m disk_usage
|
||||
|
||||
### Configuration files
|
||||
|
||||
Maintaing all these options can become a cumbersome job, but metrics.sh provides functionality for creating and reading configuration files.
|
||||
Maintaining all these options can become a cumbersome job, but metrics.sh provides functionality for creating and reading configuration files.
|
||||
|
||||
```sh
|
||||
$ ./metrics.sh -C > metrics.ini # write configuration to metrics.ini
|
||||
@@ -137,7 +153,7 @@ defaults () {} # setting default variables
|
||||
start () {} # called at the beginning
|
||||
collect () {} # collect the actual metric
|
||||
stop () {} # called before exiting
|
||||
docs () {} # used for priting docs and creating output for configuration
|
||||
docs () {} # used for printing docs and creating output for configuration
|
||||
```
|
||||
|
||||
Metrics run within an isolated scope. It's generally safe to create variables and helper functions within metrics.
|
||||
@@ -161,9 +177,9 @@ defaults () {
|
||||
# if needed. Returning 1 will disable this metric and report a warning.
|
||||
start () {
|
||||
if [ $DIR_SIZE_IN_MB = false ]; then
|
||||
DU_ARGS="-s -m $DIR_SIZE_PATH"
|
||||
else
|
||||
DU_ARGS="-s -k $DIR_SIZE_PATH"
|
||||
else
|
||||
DU_ARGS="-s -m $DIR_SIZE_PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -175,7 +191,7 @@ collect () {
|
||||
report $(du $DU_ARGS | awk '{ print $1 }')
|
||||
# If report is called with two arguments, the first one will be appended
|
||||
# to the metric name, for example `report "foo" $val` would be reported as
|
||||
# "dir_size.foo: $val". This is helpful when a metric is collecting multiple
|
||||
# "dir_size.foo: $val". This is helpful when a metric is collecting multiple
|
||||
# values like `network_io`, which reports "network_io.in" / "network_io.out".
|
||||
}
|
||||
|
||||
@@ -200,7 +216,7 @@ defaults () {} # setting default variables
|
||||
start () {} # called at the beginning
|
||||
report () {} # report the actual metric
|
||||
stop () {} # called before exiting
|
||||
docs () {} # used for priting docs and creating output for configuration
|
||||
docs () {} # used for printing docs and creating output for configuration
|
||||
```
|
||||
|
||||
Below is an example script for sending metrics as JSON data to an API endpoint. Assuming this script is located at `./reporters/custom/json_api.sh`, it can be invoked by calling `./metrics.sh -r json_api`.
|
||||
@@ -216,7 +232,7 @@ defaults () {
|
||||
}
|
||||
|
||||
# Prepare the reporter. Create helper functions to be used during collection
|
||||
# if needed. Returning 1 will result in an error and exection will be stopped.
|
||||
# if needed. Returning 1 will result in an error and execution will be stopped.
|
||||
start () {
|
||||
if [ -z $JSON_API_ENDPOINT ]; then
|
||||
echo "Error: json_api requires \$JSON_API_ENDPOINT to be specified"
|
||||
@@ -226,7 +242,7 @@ start () {
|
||||
|
||||
# Report metric. This function is called whenever there's a new value
|
||||
# to report. It's important to know that metrics don't call this function
|
||||
# directly, as there's some more work to be done before. You can safely assume
|
||||
# directly, as there's some more work to be done before. You can safely assume
|
||||
# that arguments passed to this function are sanitized and valid.
|
||||
report () {
|
||||
local metric=$1 # the name of the metric, e.g. "cpu", "cpu_alias", "cpu.foo"
|
||||
@@ -247,8 +263,3 @@ docs () {
|
||||
echo "JSON_API_METHOD=$JSON_API_METHOD"
|
||||
}
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
|
||||
- Test and improve init.d script and write docs for it
|
||||
- Tests
|
||||
37
init.d/README.md
Normal file
37
init.d/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Running metrics.sh as a service on Linux
|
||||
|
||||
Run the following commands as root:
|
||||
|
||||
```sh
|
||||
# Install metrics.sh at /opt/metrics.sh
|
||||
$ mkdir /opt; cd /opt
|
||||
$ git clone https://github.com/pstadler/metrics.sh.git
|
||||
$ cd metrics.sh
|
||||
# Install the service
|
||||
$ ln -s $PWD/init.d/metrics.sh /etc/init.d/metrics.sh
|
||||
# Create a config file
|
||||
$ mkdir /etc/metrics.sh && chmod 600 /etc/metrics.sh
|
||||
$ ./metrics.sh -C > /etc/metrics.sh/metrics.ini
|
||||
# At this point you should edit your config file at
|
||||
# /etc/metrics.sh/metrics.ini
|
||||
|
||||
# Start service
|
||||
$ service metrics.sh start
|
||||
|
||||
# If run with the default configuration where reporter is 'stdout', metrics
|
||||
# will be written to /var/log/metrics.sh.log. Be aware that this file will
|
||||
# grow fast.
|
||||
$ tail -f /var/log/metrics.sh.log
|
||||
|
||||
# Stop service
|
||||
$ service metrics.sh stop
|
||||
|
||||
# Check service status
|
||||
$ service metrics.sh status
|
||||
|
||||
# Automatically start service when booting and stop when shutting down
|
||||
$ update-rc.d metrics.sh defaults
|
||||
|
||||
# Disable automatic starting/stopping
|
||||
$ update-rc.d -f metrics.sh remove
|
||||
```
|
||||
49
init.d/metrics.sh
Normal file → Executable file
49
init.d/metrics.sh
Normal file → Executable file
@@ -9,9 +9,10 @@
|
||||
# Description: Controls the metrics daemon "metrics.sh"
|
||||
### END INIT INFO
|
||||
|
||||
SCRIPT=<SCRIPT>
|
||||
RUNAS=<USER>
|
||||
CONFIG_FILE=<CONFIG_FILE>
|
||||
SCRIPT_DIR=/opt/metrics.sh
|
||||
CONFIG_FILE=/etc/metrics.sh/metrics.ini
|
||||
RUNAS=root
|
||||
SCRIPT=$SCRIPT_DIR/metrics.sh
|
||||
ARGS="-c $CONFIG_FILE"
|
||||
NAME=metrics.sh
|
||||
|
||||
@@ -19,16 +20,19 @@ PIDFILE=/var/run/$NAME.pid
|
||||
LOGFILE=/var/log/$NAME.log
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
[ -x "$SCRIPT" ] || exit 0
|
||||
|
||||
cd $SCRIPT_DIR
|
||||
|
||||
start() {
|
||||
if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE); then
|
||||
PID=$([ -f $PIDFILE ] && cat $PIDFILE)
|
||||
if [ -n "$PID" ] && kill -0 $PID; then
|
||||
echo 'Service already running' >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Starting service...' >&2
|
||||
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
|
||||
su -c "$CMD $ARGS" $RUNAS > "$PIDFILE"
|
||||
local CMD="$SCRIPT $ARGS &> \"$LOGFILE\" & echo \$!"
|
||||
su -c "$CMD" $RUNAS > "$PIDFILE"
|
||||
echo 'Service started' >&2
|
||||
}
|
||||
|
||||
@@ -43,29 +47,15 @@ stop() {
|
||||
}
|
||||
|
||||
status() {
|
||||
printf "%-50s" "Checking $NAME..."
|
||||
if [ -f $PIDFILE ]; then
|
||||
PID=$(cat $PIDFILE)
|
||||
if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
|
||||
printf "%s\n" "The process appears to be dead but pidfile still exists"
|
||||
if [ -z "$(ps axf | grep $PID | grep -v grep)" ]; then
|
||||
echo "The process appears to be dead but pidfile still exists"
|
||||
else
|
||||
echo "Running, the PID is $PID"
|
||||
echo "Service is running"
|
||||
fi
|
||||
else
|
||||
printf "%s\n" "Service not running"
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo -n 'Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] '
|
||||
local SURE
|
||||
read SURE
|
||||
if [ "$SURE" = "yes" ]; then
|
||||
stop
|
||||
rm -f "$PIDFILE"
|
||||
echo "Notice: log file was not removed: '$LOGFILE'" >&2
|
||||
update-rc.d -f <NAME> remove
|
||||
rm -fv "$0"
|
||||
echo "Service not running"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -79,13 +69,6 @@ case "$1" in
|
||||
status)
|
||||
status
|
||||
;;
|
||||
uninstall)
|
||||
uninstall
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|uninstall}"
|
||||
echo "Usage: $0 {start|stop|status}"
|
||||
esac
|
||||
|
||||
13
lib/main.sh
13
lib/main.sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# load utils
|
||||
for util in ./lib/utils/*.sh; do
|
||||
for util in ${DIR}/lib/utils/*.sh; do
|
||||
. $util
|
||||
done
|
||||
|
||||
@@ -16,10 +16,10 @@ main_defaults () {
|
||||
DEFAULT_REPORTER=stdout
|
||||
fi
|
||||
if [ -z $CUSTOM_REPORTERS_PATH ]; then
|
||||
CUSTOM_REPORTERS_PATH=./reporters/custom
|
||||
CUSTOM_REPORTERS_PATH=${DIR}/reporters/custom
|
||||
fi
|
||||
if [ -z $CUSTOM_METRICS_PATH ]; then
|
||||
CUSTOM_METRICS_PATH=./metrics/custom
|
||||
CUSTOM_METRICS_PATH=${DIR}/metrics/custom
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ main_collect () {
|
||||
trap "" 13
|
||||
trap - INT TERM EXIT
|
||||
echo Exit signal received, stopping...
|
||||
kill -13 -$$
|
||||
kill -13 0
|
||||
' 13 INT TERM EXIT
|
||||
|
||||
# init reporter
|
||||
@@ -116,7 +116,7 @@ main_collect () {
|
||||
if is_function __m_${metric_alias}_start; then
|
||||
__m_${metric_alias}_start
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Warning: metric '${metric_alias}' is disabled after failing to start"
|
||||
echo "Warning: metric '${metric_alias}' is disabled after it failed to start"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
@@ -178,7 +178,8 @@ main_terminate () {
|
||||
if [ -d $TEMP_DIR ]; then
|
||||
rmdir $TEMP_DIR
|
||||
fi
|
||||
verbose "done"
|
||||
|
||||
echo "done"
|
||||
}
|
||||
|
||||
main_print_docs () {
|
||||
|
||||
@@ -8,6 +8,10 @@ iso_date () {
|
||||
date -u +"%Y-%m-%dT%H:%M:%SZ"
|
||||
}
|
||||
|
||||
unix_timestamp () {
|
||||
date "+%s"
|
||||
}
|
||||
|
||||
in_array () {
|
||||
echo " $2 " | grep -q " $1 "
|
||||
}
|
||||
@@ -24,5 +28,5 @@ unique_id () {
|
||||
}
|
||||
|
||||
print_prefixed () {
|
||||
printf "$2" | sed -e "s/^/$1/g"
|
||||
printf "$2\n" | sed -e "s/^/$1/g"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
get_available_reporters () {
|
||||
local result
|
||||
for file in `ls ./reporters/*.sh $CUSTOM_REPORTERS_PATH/*.sh 2> /dev/null`; do
|
||||
for file in `ls ${DIR}/reporters/*.sh $CUSTOM_REPORTERS_PATH/*.sh 2> /dev/null`; do
|
||||
local filename=$(basename $file)
|
||||
local reporter=${filename%.*}
|
||||
result=$(echo "$result $reporter")
|
||||
@@ -12,7 +12,7 @@ get_available_reporters () {
|
||||
|
||||
get_available_metrics () {
|
||||
local result
|
||||
for file in `ls ./metrics/*.sh $CUSTOM_METRICS_PATH/*.sh 2> /dev/null`; do
|
||||
for file in `ls ${DIR}/metrics/*.sh $CUSTOM_METRICS_PATH/*.sh 2> /dev/null`; do
|
||||
local filename=$(basename $file)
|
||||
local metric=${filename%.*}
|
||||
# register metric
|
||||
@@ -26,7 +26,7 @@ load_reporter_with_prefix () {
|
||||
local name=$2
|
||||
|
||||
local file
|
||||
for dir in $CUSTOM_REPORTERS_PATH ./reporters; do
|
||||
for dir in $CUSTOM_REPORTERS_PATH ${DIR}/reporters; do
|
||||
if [ -f $dir/$name.sh ]; then
|
||||
file=$dir/$name.sh
|
||||
break
|
||||
@@ -53,7 +53,7 @@ load_metric_with_prefix () {
|
||||
local name=$2
|
||||
|
||||
local file
|
||||
for dir in $CUSTOM_METRICS_PATH ./metrics; do
|
||||
for dir in $CUSTOM_METRICS_PATH ${DIR}/metrics; do
|
||||
if [ -f $dir/$name.sh ]; then
|
||||
file=$dir/$name.sh
|
||||
break
|
||||
|
||||
@@ -15,7 +15,7 @@ esac)
|
||||
|
||||
is_solaris () { [ $OS_TYPE = 'solaris' ]; }
|
||||
is_osx () { [ $OS_TYPE = 'osx' ]; }
|
||||
is_linux () { [ $OS_TYPE = 'solaris' ]; }
|
||||
is_linux () { [ $OS_TYPE = 'linux' ]; }
|
||||
is_bsd () { [ $OS_TYPE = 'bsd']; }
|
||||
is_unknown () { [ $OS_TYPE = 'unknown' ]; }
|
||||
|
||||
@@ -28,4 +28,4 @@ else
|
||||
make_temp_dir () {
|
||||
mktemp -d
|
||||
}
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
LC_ALL=en_US.UTF-8
|
||||
LANG=en_US.UTF-8
|
||||
LANGUAGE=en_US.UTF-8
|
||||
DIR=$(dirname "$0")
|
||||
|
||||
usage () {
|
||||
echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u]"
|
||||
@@ -90,11 +91,11 @@ while [ $# -gt 0 ]; do
|
||||
done
|
||||
|
||||
# run
|
||||
. ./lib/main.sh
|
||||
. ${DIR}/lib/main.sh
|
||||
|
||||
if [ $opt_do_update = true ]; then
|
||||
if ! command_exists git; then
|
||||
echo "Error: --update requires `git` to be in the PATH"
|
||||
echo "Error: --update requires 'git' to be in the PATH"
|
||||
exit 1
|
||||
fi
|
||||
echo "Fetching latest version..."
|
||||
@@ -125,7 +126,7 @@ fi
|
||||
if [ -n "$opt_config_file" ]; then
|
||||
verbose "Loading configuration file: $opt_config_file"
|
||||
|
||||
parse_config $opt_config_file
|
||||
parse_config "$opt_config_file"
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
@@ -162,4 +163,4 @@ verbose "Using reporter: $__REPORTER"
|
||||
|
||||
echo "metrics.sh started with PID: $$"
|
||||
verbose "Collecting metrics every $INTERVAL second(s)"
|
||||
main_collect
|
||||
main_collect
|
||||
|
||||
@@ -11,7 +11,12 @@ defaults () {
|
||||
}
|
||||
|
||||
start () {
|
||||
readonly fifo=$TEMP_DIR/$(unique_id)
|
||||
if ! command_exists iostat; then
|
||||
echo "Warning: disk_io requires the command 'iostat' to be available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
readonly fifo=$TEMP_DIR/$(unique_id)_disk_io
|
||||
mkfifo $fifo
|
||||
|
||||
if is_osx; then
|
||||
|
||||
@@ -13,11 +13,11 @@ if is_osx; then
|
||||
}
|
||||
else
|
||||
collect () {
|
||||
report $(free | awk '/buffers\/cache/ {
|
||||
printf "%.1f", 100 - $4 / ($3 + $4) * 100.0 }')
|
||||
report $(free | awk '/Mem:/ {
|
||||
printf "%.1f", 100 - $4 / ($3 + $4) * 100}')
|
||||
}
|
||||
fi
|
||||
|
||||
docs () {
|
||||
echo "Percentage of used memory."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,28 +13,19 @@ start () {
|
||||
fi
|
||||
|
||||
if [ "$INFLUXDB_SEND_HOSTNAME" = true ]; then
|
||||
__influxdb_columns="[\"value\",\"host\"]"
|
||||
__influxdb_hostname=$(hostname)
|
||||
else
|
||||
__influxdb_columns="[\"value\"]"
|
||||
__influxdb_hostname="host=$(hostname)"
|
||||
fi
|
||||
}
|
||||
|
||||
report () {
|
||||
local metric=$1
|
||||
local value=$2
|
||||
local points
|
||||
if [ "$INFLUXDB_SEND_HOSTNAME" = true ]; then
|
||||
points="[$value,\"$__influxdb_hostname\"]"
|
||||
else
|
||||
points="[$value]"
|
||||
fi
|
||||
local data="[{\"name\":\"$metric\",\"columns\":$__influxdb_columns,\"points\":[$points]}]"
|
||||
curl -s -X POST $INFLUXDB_API_ENDPOINT -d $data
|
||||
local data="$metric,$__influxdb_hostname value=$value"
|
||||
curl -s -X POST $INFLUXDB_API_ENDPOINT --data-binary "$data"
|
||||
}
|
||||
|
||||
docs () {
|
||||
echo "Send data to InfluxDB."
|
||||
echo "INFLUXDB_API_ENDPOINT=$INFLUXDB_API_ENDPOINT"
|
||||
echo "INFLUXDB_SEND_HOSTNAME=$INFLUXDB_SEND_HOSTNAME"
|
||||
}
|
||||
}
|
||||
|
||||
19
reporters/logentries_com.sh
Normal file
19
reporters/logentries_com.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
start () {
|
||||
if [ -z $LOGENTRIES_TOKEN ]; then
|
||||
echo "Error: logentries.com requires \$LOGENTRIES_TOKEN to be specified"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
report () {
|
||||
local metric=$1 # the name of the metric, e.g. "cpu", "cpu_alias", "cpu.foo"
|
||||
local value=$2 # int or float
|
||||
echo "$LOGENTRIES_TOKEN $metric=$value" | nc data.logentries.com 10000
|
||||
}
|
||||
|
||||
docs () {
|
||||
echo "Send data to Logentries.com using token TCP (https://docs.logentries.com/docs/input-token)"
|
||||
echo "LOGENTRIES_TOKEN=$LOGENTRIES_TOKEN"
|
||||
}
|
||||
83
reporters/prometheus.sh
Normal file
83
reporters/prometheus.sh
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/bin/sh
|
||||
|
||||
defaults () {
|
||||
if [ -z $PROMETHEUS_PORT ]; then
|
||||
PROMETHEUS_PORT=9100
|
||||
fi
|
||||
if [ -z $PROMETHEUS_METRIC_NAME ]; then
|
||||
PROMETHEUS_METRIC_NAME="metrics_sh"
|
||||
fi
|
||||
}
|
||||
|
||||
start () {
|
||||
readonly prometheus_report_header="# TYPE metrics_sh gauge"
|
||||
readonly prometheus_stats_file=$TEMP_DIR/$(unique_id)_prometheus
|
||||
readonly prometheus_httpd_fifo=$TEMP_DIR/$(unique_id)_prometheus_fifo
|
||||
touch $prometheus_stats_file
|
||||
mkfifo $prometheus_httpd_fifo
|
||||
|
||||
prometheus_httpd &
|
||||
prometheus_stats_file_monitor &
|
||||
}
|
||||
|
||||
report () {
|
||||
local metric=$1
|
||||
local value=$2
|
||||
|
||||
printf "%s{metric=\"%s\"} %s %s\n" "$PROMETHEUS_METRIC_NAME" "$metric" \
|
||||
"$value" "$(unix_timestamp)000" >> $prometheus_stats_file
|
||||
}
|
||||
|
||||
stop () {
|
||||
if [ ! -z $prometheus_stats_file ] && [ -f $prometheus_stats_file ]; then
|
||||
rm $prometheus_stats_file
|
||||
fi
|
||||
if [ ! -z $prometheus_httpd_fifo ] && [ -p $prometheus_httpd_fifo ]; then
|
||||
rm $prometheus_httpd_fifo
|
||||
fi
|
||||
}
|
||||
|
||||
prometheus_httpd () {
|
||||
echo "Serving prometheus HTTP endpoint at http://localhost:$PROMETHEUS_PORT/metrics"
|
||||
while true; do
|
||||
local REQUEST RESPONSE
|
||||
cat $prometheus_httpd_fifo | nc -l $PROMETHEUS_PORT | while read line; do
|
||||
line=$(echo "$line" | tr -d '[\r\n]')
|
||||
# extract the request
|
||||
if echo "$line" | grep -qE '^GET /'; then
|
||||
REQUEST=$(echo "$line" | cut -d ' ' -f2)
|
||||
# end of request
|
||||
elif [ "x$line" = x ]; then
|
||||
if echo $REQUEST | grep -qE '^/metrics'; then
|
||||
RESPONSE=$(cat $prometheus_stats_file)
|
||||
# clear
|
||||
printf "" > $prometheus_stats_file
|
||||
printf "HTTP/1.1 200 OK\nContent-Type: text/plain\n\n%s\n%s\n" \
|
||||
"$prometheus_report_header" "$RESPONSE" > $prometheus_httpd_fifo
|
||||
else
|
||||
printf "HTTP/1.1 404 Not Found\nLocation: %s\n\n%s\n" \
|
||||
"$REQUEST" "404 Not Found" > $prometheus_httpd_fifo
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
prometheus_stats_file_monitor () {
|
||||
while true; do
|
||||
local bytes=$(ls -l $prometheus_stats_file | awk '{ print $5 }')
|
||||
# clear file if bigger than 5MB
|
||||
if [ $bytes -gt 5000000 ]; then
|
||||
printf "" > $prometheus_stats_file
|
||||
fi
|
||||
sleep 120
|
||||
done
|
||||
}
|
||||
|
||||
docs () {
|
||||
echo "Provide HTTP endpoint for Prometheus (http://prometheus.io)."
|
||||
echo "Exposes metrics of type gauges in the following format:"
|
||||
echo "$PROMETHEUS_METRIC_NAME{metric=\"<metric>\"} <value> <timestamp>"
|
||||
echo "PROMETHEUS_PORT=$PROMETHEUS_PORT"
|
||||
echo "PROMETHEUS_METRIC_NAME=$PROMETHEUS_METRIC_NAME"
|
||||
}
|
||||
38
reporters/udp.sh
Normal file
38
reporters/udp.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
defaults () {
|
||||
if [ -z $UDP_HOST ]; then
|
||||
UDP_HOST="127.0.0.1"
|
||||
fi
|
||||
if [ -z $UDP_DELIMITER ]; then
|
||||
UDP_DELIMITER="="
|
||||
fi
|
||||
}
|
||||
|
||||
start () {
|
||||
if [ -z $UDP_PORT ]; then
|
||||
echo "Error: udp requires \$UDP_PORT to be specified"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$UDP_PREFIX" ]; then
|
||||
prefix="$UDP_PREFIX."
|
||||
fi
|
||||
if [ -n "$UDP_DELIMITER" ]; then
|
||||
delimiter="$UDP_DELIMITER"
|
||||
fi
|
||||
}
|
||||
|
||||
report () {
|
||||
local metric=$1
|
||||
local value=$2
|
||||
echo "$prefix$metric$delimiter$value" | nc -u -w0 $UDP_HOST $UDP_PORT
|
||||
}
|
||||
|
||||
docs () {
|
||||
echo "Send data to any service using UDP."
|
||||
echo "UDP_HOST=$UDP_HOST"
|
||||
echo "UDP_PORT=$UDP_PORT"
|
||||
echo "UDP_PREFIX=$UDP_PREFIX"
|
||||
echo "UDP_DELIMITER=\"$UDP_DELIMITER\""
|
||||
}
|
||||
40
systemd/README.md
Normal file
40
systemd/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Running metrics.sh as a systemd service on Linux
|
||||
|
||||
Run the following commands as root:
|
||||
|
||||
```sh
|
||||
# Install metrics.sh at /opt/metrics.sh
|
||||
$ mkdir /opt; cd /opt
|
||||
$ git clone https://github.com/pstadler/metrics.sh.git
|
||||
$ cd metrics.sh
|
||||
# Install the service
|
||||
$ cp -p $PWD/systemd/metrics.sh.service /etc/systemd/system/metrics.sh.service
|
||||
# Create a config file
|
||||
$ mkdir /etc/metrics.sh && chmod 600 /etc/metrics.sh
|
||||
$ ./metrics.sh -C > /etc/metrics.sh/metrics.ini
|
||||
# At this point you should edit your config file at
|
||||
# /etc/metrics.sh/metrics.ini
|
||||
|
||||
# Reload systemd daemon
|
||||
$ systemctl daemon-reload
|
||||
|
||||
# Start service
|
||||
$ systemctl start metrics.sh.service
|
||||
|
||||
# If run with the default configuration where reporter is 'stdout', metrics
|
||||
# will be written to the journal. See the log using `journalctl -u metrics.sh`
|
||||
# or follow it with:
|
||||
$ journalctl -f -u metrics.sh
|
||||
|
||||
# Stop service
|
||||
$ systemctl stop metrics.sh.service
|
||||
|
||||
# Check service status
|
||||
$ systemctl status metrics.sh.service
|
||||
|
||||
# Automatically start service when booting and stop when shutting down
|
||||
$ systemctl enable metrics.sh.service
|
||||
|
||||
# Disable automatic starting/stopping
|
||||
$ systemctl disable metrics.sh.service
|
||||
```
|
||||
11
systemd/metrics.sh.service
Normal file
11
systemd/metrics.sh.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Controls the metrics daemon "metrics.sh"
|
||||
Documentation=https://github.com/pstadler/metrics.sh
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/opt/metrics.sh/metrics.sh -c /etc/metrics.sh/metrics.ini
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user