Sampler - A Tool For Shell Commands Execution (How To Install)
Sampler is a tool for shell commands execution, visualization and
alerting. Configured with a simple YAML file.
Installation
macOS
brew cask install sampler
oR
curl -Lo /usr/local/bin/sampler https://github.com/sqshq/sampler/releases/download/v1.0.1/sampler-1.0.1-darwin-amd64chmod +x /usr/local/bin/sampler
Linux
wget https://github.com/sqshq/sampler/releases/download/v1.0.1/sampler-1.0.1-linux-amd64 -O /usr/local/bin/samplerchmod +x /usr/local/bin/sampler
Note:
libasound2-dev system library is required to be
installed for Sampler to play a trigger sound tone. Usually the library is in place, but if not - you can
do it with your favorite package manager, e.g apt install libasound2-dev
Windows (experimental)
Recommended to use with advanced console emulators, e.g. Cmder
Usage
You specify shell commands, Sampler executes them with a required rate.
The output is used for visualization.
One can sample any dynamic process right from the terminal - observe
changes in the database, monitor MQ in-flight messages, trigger deployment
process and get notification when it's done.
Using Sampler is basically a 3-step process:
- Define your configuration in a YAML file
-
Run
sampler -c config.yml - Adjust components size and location on UI
Components
The following is a list of configuration examples for each component
type, with macOS compatible sampling scripts.
Runchart
runcharts:- title: Search engine response timerate-ms: 500# sampling rate, default = 1000scale: 2# number of digits after sample decimal point, default = 1legend:enabled: true# enables item labels, default = truedetails: false# enables item statistics: cur/min/max/dlt values, default = trueitems:- label: GOOGLEsample: curl -o /dev/null -s -w '%{time_total}' https://www.google.comcolor: 178# 8-bit color number, default one is chosen from a pre-defined palette- label: YAHOOsample: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com- label: BINGsample: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com
Sparkline
sparklines:- title: CPU usagerate-ms: 200scale: 0sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'- title: Free memory pagesrate-ms: 200scale: 0sample: memory_pressure | grep 'Pages free' | awk '{print $3}'
Barchart
barcharts:- title: Local network activityrate-ms: 500# sampling rate, default = 1000scale: 0# number of digits after sample decimal point, default = 1items:- label: UDP bytes insample: nettop -J bytes_in -l 1 -m udp | awk '{sum += $4} END {print sum}'- label: UDP bytes outsample: nettop -J bytes_out -l 1 -m udp | awk '{sum += $4} END {print sum}'- label: TCP bytes insample: nettop -J bytes_in -l 1 -m tcp | awk '{sum += $4} END {print sum}'- label: TCP bytes outsample: nettop -J bytes_out -l 1 -m tcp | awk '{sum += $4} END {print sum}'
Gauge
gauges:- title: Minute progressrate-ms: 500 # sampling rate, default = 1000scale: 2 # number of digits after sample decimal point, default = 1percent-only: false # toggle display of the current value, default = falsecolor: 178 # 8-bit color number, default one is chosen from a pre-defined palettecur:sample: date +%S # sample script for current valuemax:sample: echo 60 # sample script for max valuemin:sample: echo 0 # sample script for min value- title: Year progresscur:sample: date +%jmax:sample: echo 365min:sample: echo 0
Textbox
textboxes:- title: Local weatherrate-ms: 10000# sampling rate, default = 1000sample: curl wttr.in?0ATQFborder: false# border around the item, default = truecolor: 178# 8-bit color number, default is white- title: Docker containers statsrate-ms: 500sample: docker stats --no-stream --format "table \t\t\t"
Asciibox
asciiboxes:- title: UTC timerate-ms: 500# sampling rate, default = 1000font: 3d# font type, default = 2dborder: false# border around the item, default = truecolor: 43# 8-bit color number, default is whitesample: env TZ=UTC date +%r
Bells and whistles
Triggers
Triggers allow to perform conditional actions, like visual/sound alerts
or an arbitrary shell command. The following examples illustrate the
concept.
Clock gauge, which shows minute progress and announces current time at
the beginning of each minute
gauges:- title: MINUTE PROGRESSposition: [[0, 18], [80, 0]]cur:sample: date +%Smax:sample: echo 60min:sample: echo 0triggers:- title: CLOCK BELL EVERY MINUTEcondition: '[ $label == "cur" ] && [ $cur -eq 0 ] && echo 1 || echo 0' # expects "1" as TRUE indicatoractions:terminal-bell: true# standard terminal bell, default = falsesound: true# NASA quindar tone, default = falsevisual: false# notification with current value on top of the component area, default = falsescript: say -v samantha `date +%I:%M%p` # an arbitrary script, which can use $cur, $prev and $label variables
Search engine latency chart, which alerts user when latency exceeds a
threshold
runcharts:- title: SEARCH ENGINE RESPONSE TIME (sec)rate-ms: 200items:- label: GOOGLEsample: curl -o /dev/null -s -w '%{time_total}' https://www.google.com- label: YAHOOsample: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.comtriggers:- title: Latency threshold exceededcondition: echo "$prev < 0.3 && $cur > 0.3" |bc -l # expects "1" as TRUE indicatoractions:terminal-bell: true # standard terminal bell, default = falsesound: true # NASA quindar tone, default = falsevisual: true # visual notification on top of the component area, default = falsescript: 'say alert: ${label} latency exceeded ${cur} second' # an arbitrary script, which can use $cur, $prev and $label variables
Interactive shell support
In addition to the
sample command, one can
specify init command (executed only once before
sampling) and transform command (to
post-process sample command output). That covers
interactive shell use case, e.g. to establish connection to a database
only once, and then perform polling within an interactive shell
session.
Basic mode
textboxes:- title: MongoDB pollingrate-ms: 500init: mongo --quiet --host=localhost test# executes only once to start the interactive sessionsample: Date.now();# executes with a required rate, in scope of the interactive sessiontransform: echo result = $sample# executes in scope of local session, $sample variable is available for transformation
PTY mode
In some cases interactive shell won't work, because its stdin is not a
terminal. We can fool it, using PTY mode:
textboxes:- title: Neo4j pollingpty: true# enables pseudo-terminal mode, default = falseinit: cypher-shell -u neo4j -p pwd --format plainsample: RETURN rand();transform: echo "$sample" | tail -n 1- title: Top on a remote serverpty: true# enables pseudo-terminal mode, default = falseinit: ssh -i ~/user.pem ec2-user@1.2.3.4sample: top
Multistep init
It is also possible to execute multiple init commands one after another,
before you start sampling.
textboxes:- title: Java application uptimemultistep-init:- java -jar jmxterm-1.0.0-uber.jar- open host:port# or local PID- bean java.lang:type=Runtimesample: get Uptime
Variables
If the configuration file contains repeated patterns, they can be
extracted into the
variables section. Also
variables can be specified
using -v/--variable flag on startup,
and any system environment variables will also be available in the
scripts.
variables:mongoconnection: mongo --quiet --host=localhost testbarcharts:- title: MongoDB documents by statusitems:- label: IN_PROGRESSinit: $mongoconnectionsample: db.getCollection('events').find({status:'IN_PROGRESS'}).count()- label: SUCCESSinit: $mongoconnectionsample: db.getCollection('events').find({status:'SUCCESS'}).count()- label: FAILinit: $mongoconnectionsample: db.getCollection('events').find({status:'FAIL'}).count()
Color theme
theme: light # default = darksparklines:- title: CPU usagesample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
Real-world recipes
Databases
The following are different database connection examples. Interactive
shell (init script) usage is recommended to establish connection only once
and then reuse it during sampling.
MySQL
# prerequisite: installed mysql shellvariables:mysql_connection: mysql -u root -s --database mysql --skip-column-namessparklines:- title: MySQL (random number example)pty: trueinit: $mysql_connectionsample: select rand();
PostgreSQL
# prerequisite: installed psql shellvariables:PGPASSWORD: pwdpostgres_connection: psql -h localhost -U postgres --no-align --tuples-onlysparklines:- title: PostgreSQL (random number example)init: $postgres_connectionsample: select random();
MongoDB
# prerequisite: installed mongo shellvariables:mongo_connection: mongo --quiet --host=localhost testsparklines:- title: MongoDB (random number example)init: $mongo_connectionsample: Math.random();
Neo4j
# prerequisite: installed cypher shellvariables:neo4j_connection: cypher-shell -u neo4j -p pwd --format plainsparklines:- title: Neo4j (random number example)pty: trueinit: $neo4j_connectionsample: RETURN rand();transform: echo "$sample" | tail -n 1
Kafka lag per consumer group
variables:
kafka_connection: $KAFKA_HOME/bin/kafka-consumer-groups --bootstrap-server localhost:9092
runcharts:
- title: Kafka lag per consumer group
rate-ms: 5000
scale: 0
items:
- label: A->B
sample: $kafka_connection --group group_a --describe | awk 'NR>1 {sum += $5} END {print sum}'
- label: B->C
sample: $kafka_connection --group group_b --describe | awk 'NR>1 {sum += $5} END {print sum}'
- label: C->D
sample: $kafka_connection --group group_c --describe | awk 'NR>1 {sum += $5} END {print sum}'
Docker containers stats (CPU, MEM, O/I)
textboxes:- title: Docker containers statssample: docker stats --no-stream --format "table \t\t\t\t\t\t"
SSH
TOP command on a remote server
variables:sshconnection: ssh -i ~/my-key-pair.pem ec2-user@1.2.3.4textboxes:- title: SSHpty: trueinit: $sshconnectionsample: top
JMX
Java application uptime example
# prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm)textboxes:- title: Java application uptimemultistep-init:- java -jar jmxterm-1.0.0-uber.jar- open host:port # or local PID- bean java.lang:type=Runtimesample: get Uptimetransform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}'







