Compare commits

..

No commits in common. "master" and "0.2.3" have entirely different histories.

9 changed files with 32 additions and 104 deletions

View File

@ -16,7 +16,7 @@ metrics.sh is a lightweight metrics collection and forwarding daemon implemented
``` ```
$ ./metrics.sh --help $ ./metrics.sh --help
Usage: ./metrics.sh [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u] Usage: ./metrics.sh [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u]
Options: Options:
@ -39,7 +39,6 @@ $ 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. 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 ### Requirements
@ -60,17 +59,16 @@ Metric | Description
## Reporters ## Reporters
Reporter | Description Reporter | Description
---------------- | ------------- --------------- | -------------
`stdout` | Write to standard out (default) `stdout` | Write to standard out (default)
`file` | Write to a file or named pipe `file` | Write to a file or named pipe
`udp` | Send data to any service via UDP `udp` | Send data to any service via UDP
`statsd` | Send data to [StatsD](https://github.com/etsy/statsd) `statsd` | Send data to [StatsD](https://github.com/etsy/statsd)
`influxdb` | Send data to [InfluxDB](http://influxdb.com/) `influxdb` | Send data to [InfluxDB](http://influxdb.com/)
`prometheus` | Provide HTTP endpoint for [Prometheus](http://prometheus.io/) `prometheus` | Provide HTTP endpoint for [Prometheus](http://prometheus.io/)
`keen_io` | Send data to [Keen IO](https://keen.io) `keen_io` | Send data to [Keen IO](https://keen.io)
`stathat` | Send data to [StatHat](https://www.stathat.com) `stathat` | Send data to [StatHat](https://www.stathat.com)
`logentries_com` | Send data to [Logentries](https://logentries.com/)
## Configuration ## Configuration
@ -96,7 +94,7 @@ $ DISK_USAGE_MOUNTPOINT=/dev/vdb ./metrics.sh -m disk_usage
### Configuration files ### Configuration files
Maintaining all these options can become a cumbersome job, but metrics.sh provides functionality for creating and reading configuration files. Maintaing all these options can become a cumbersome job, but metrics.sh provides functionality for creating and reading configuration files.
```sh ```sh
$ ./metrics.sh -C > metrics.ini # write configuration to metrics.ini $ ./metrics.sh -C > metrics.ini # write configuration to metrics.ini
@ -153,7 +151,7 @@ defaults () {} # setting default variables
start () {} # called at the beginning start () {} # called at the beginning
collect () {} # collect the actual metric collect () {} # collect the actual metric
stop () {} # called before exiting stop () {} # called before exiting
docs () {} # used for printing docs and creating output for configuration docs () {} # used for priting docs and creating output for configuration
``` ```
Metrics run within an isolated scope. It's generally safe to create variables and helper functions within metrics. Metrics run within an isolated scope. It's generally safe to create variables and helper functions within metrics.
@ -191,7 +189,7 @@ collect () {
report $(du $DU_ARGS | awk '{ print $1 }') report $(du $DU_ARGS | awk '{ print $1 }')
# If report is called with two arguments, the first one will be appended # 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 # 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". # values like `network_io`, which reports "network_io.in" / "network_io.out".
} }
@ -216,7 +214,7 @@ defaults () {} # setting default variables
start () {} # called at the beginning start () {} # called at the beginning
report () {} # report the actual metric report () {} # report the actual metric
stop () {} # called before exiting stop () {} # called before exiting
docs () {} # used for printing docs and creating output for configuration docs () {} # used for priting 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`. 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`.
@ -232,7 +230,7 @@ defaults () {
} }
# Prepare the reporter. Create helper functions to be used during collection # Prepare the reporter. Create helper functions to be used during collection
# if needed. Returning 1 will result in an error and execution will be stopped. # if needed. Returning 1 will result in an error and exection will be stopped.
start () { start () {
if [ -z $JSON_API_ENDPOINT ]; then if [ -z $JSON_API_ENDPOINT ]; then
echo "Error: json_api requires \$JSON_API_ENDPOINT to be specified" echo "Error: json_api requires \$JSON_API_ENDPOINT to be specified"
@ -242,7 +240,7 @@ start () {
# Report metric. This function is called whenever there's a new value # 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 # 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. # that arguments passed to this function are sanitized and valid.
report () { report () {
local metric=$1 # the name of the metric, e.g. "cpu", "cpu_alias", "cpu.foo" local metric=$1 # the name of the metric, e.g. "cpu", "cpu_alias", "cpu.foo"

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# load utils # load utils
for util in ${DIR}/lib/utils/*.sh; do for util in ./lib/utils/*.sh; do
. $util . $util
done done
@ -16,10 +16,10 @@ main_defaults () {
DEFAULT_REPORTER=stdout DEFAULT_REPORTER=stdout
fi fi
if [ -z $CUSTOM_REPORTERS_PATH ]; then if [ -z $CUSTOM_REPORTERS_PATH ]; then
CUSTOM_REPORTERS_PATH=${DIR}/reporters/custom CUSTOM_REPORTERS_PATH=./reporters/custom
fi fi
if [ -z $CUSTOM_METRICS_PATH ]; then if [ -z $CUSTOM_METRICS_PATH ]; then
CUSTOM_METRICS_PATH=${DIR}/metrics/custom CUSTOM_METRICS_PATH=./metrics/custom
fi fi
} }

View File

@ -2,7 +2,7 @@
get_available_reporters () { get_available_reporters () {
local result local result
for file in `ls ${DIR}/reporters/*.sh $CUSTOM_REPORTERS_PATH/*.sh 2> /dev/null`; do for file in `ls ./reporters/*.sh $CUSTOM_REPORTERS_PATH/*.sh 2> /dev/null`; do
local filename=$(basename $file) local filename=$(basename $file)
local reporter=${filename%.*} local reporter=${filename%.*}
result=$(echo "$result $reporter") result=$(echo "$result $reporter")
@ -12,7 +12,7 @@ get_available_reporters () {
get_available_metrics () { get_available_metrics () {
local result local result
for file in `ls ${DIR}/metrics/*.sh $CUSTOM_METRICS_PATH/*.sh 2> /dev/null`; do for file in `ls ./metrics/*.sh $CUSTOM_METRICS_PATH/*.sh 2> /dev/null`; do
local filename=$(basename $file) local filename=$(basename $file)
local metric=${filename%.*} local metric=${filename%.*}
# register metric # register metric
@ -26,7 +26,7 @@ load_reporter_with_prefix () {
local name=$2 local name=$2
local file local file
for dir in $CUSTOM_REPORTERS_PATH ${DIR}/reporters; do for dir in $CUSTOM_REPORTERS_PATH ./reporters; do
if [ -f $dir/$name.sh ]; then if [ -f $dir/$name.sh ]; then
file=$dir/$name.sh file=$dir/$name.sh
break break
@ -53,7 +53,7 @@ load_metric_with_prefix () {
local name=$2 local name=$2
local file local file
for dir in $CUSTOM_METRICS_PATH ${DIR}/metrics; do for dir in $CUSTOM_METRICS_PATH ./metrics; do
if [ -f $dir/$name.sh ]; then if [ -f $dir/$name.sh ]; then
file=$dir/$name.sh file=$dir/$name.sh
break break

View File

@ -4,7 +4,6 @@
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
DIR=$(dirname "$0")
usage () { usage () {
echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u]" echo " Usage: $0 [-d] [-h] [-v] [-c] [-m] [-r] [-i] [-C] [-u]"
@ -91,11 +90,11 @@ while [ $# -gt 0 ]; do
done done
# run # run
. ${DIR}/lib/main.sh . ./lib/main.sh
if [ $opt_do_update = true ]; then if [ $opt_do_update = true ]; then
if ! command_exists git; 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 exit 1
fi fi
echo "Fetching latest version..." echo "Fetching latest version..."
@ -126,7 +125,7 @@ fi
if [ -n "$opt_config_file" ]; then if [ -n "$opt_config_file" ]; then
verbose "Loading configuration file: $opt_config_file" verbose "Loading configuration file: $opt_config_file"
parse_config "$opt_config_file" parse_config $opt_config_file
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
exit 1 exit 1
fi fi
@ -163,4 +162,4 @@ verbose "Using reporter: $__REPORTER"
echo "metrics.sh started with PID: $$" echo "metrics.sh started with PID: $$"
verbose "Collecting metrics every $INTERVAL second(s)" verbose "Collecting metrics every $INTERVAL second(s)"
main_collect main_collect

View File

@ -13,11 +13,11 @@ if is_osx; then
} }
else else
collect () { collect () {
report $(free | awk '/Mem:/ { report $(free | awk '/buffers\/cache/ {
printf "%.1f", 100 - $4 / ($3 + $4) * 100}') printf "%.1f", 100 - $4 / ($3 + $4) * 100.0 }')
} }
fi fi
docs () { docs () {
echo "Percentage of used memory." echo "Percentage of used memory."
} }

View File

@ -20,6 +20,7 @@ start () {
report () { report () {
local metric=$1 local metric=$1
local value=$2 local value=$2
local points
local data="$metric,$__influxdb_hostname value=$value" local data="$metric,$__influxdb_hostname value=$value"
curl -s -X POST $INFLUXDB_API_ENDPOINT --data-binary "$data" curl -s -X POST $INFLUXDB_API_ENDPOINT --data-binary "$data"
} }

View File

@ -1,19 +0,0 @@
#!/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"
}

View File

@ -1,40 +0,0 @@
# 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
```

View File

@ -1,11 +0,0 @@
[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