Longboat
Longboat is a metric collection system. Intended for Viking, but theoretically generic.
It aggregates metrics collected by raiders, which are individual Ruby classes intended to gather and munge data from any source. It then present the data in Prometheus Exposition Format at a HTTP endpoint.
Dependencies
Longboat depends on the optimist
and sinatra
gems (and optionally thin
). You can install with gem or bundler in the usual ways.
$ bundle install
Usage
Defaults
Longboat has some sensible defaults, so to get started pop your raiders in lib/raiders
and run:
$ ./longboat
== Sinatra (v2.1.0) has taken the stage on 8564 for production with backup from Thin
Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on 127.0.0.1:8564, CTRL+C to stop
Test
When testing new raiders, use the --test
flag. Rather than starting a web server and entering the raid loop, this will only run the raiders once then spit out the metrics on stdout:
$ ./longboat --test
#HELP longboat_a_value A value specified at runtime
#TYPE longboat_a_value gauge
longboat_a_value{} 4 1604490345980
Raider paths
Use --raider-path
to append a directory to the raider path. You can call this multiple times:
$ ./longboat -a /some/global/raiders -a /some/more/raiders -a even_more_raiders
Raiders
Raiders go out, raid things, and return to the longboat with metrics for the collector.
Longboat will pick up all raiders in the lib/raiders
directory by default.
There are some example raiders in examples
.
Raider structure
Each raider consists of:
- a file with a snake_case name, such as
my_raider.rb
- containing a single class with a CamelCase name matching the file name, such as
MyRaider
- with two methods:
initialize
, which takes two arguments of:- the collector to
report!
the metrics to, and - a hash containing config relevant to raiders
- the collector to
raid
, no arguments, which triggers a raid and metric report
Longboat::Collector#report!
takes as arguments:
- The name of the metric
- The value of the metric
- Optionally, as a final hash:
help
: The help string for the metrictype
: The Prometheus type of the metriclabels
: A hash containing the metric labelstimestamp
: The timestamp when the metric was collected, defaults to the timereport!
was called.
For gauges and counters, the value is simply the vale of the metric.
For histograms, the value is a hash containing:
buckets
: A hash mapping the upper bound to the number of observations in the bucketcount
: The total number of observationssum
: The sum of all observations
For summaries, the value is a hash containing:
quantiles
: A hash mapping the quantile to the valuecount
: The total number of observationssum
: The sum of all observations
Raider config
Longboat offers the Longboat::Config.for_raider
primitive to allow raiders to get command line arguments at runtime. It takes a block which is passed wholesale to Optimist::Parser.new
, and returns a hash of parsed arguments. For more information see the documentation for Optimist.
Consider the following raider:
class MyRaider
def initialize(collector, config)
@my_config = Longboat::Config.for_raider do
opt :myraider_an_argument, "An argument for myraider"
end
end
...
After calling longboat thusly:
$ ./longboat --myraider-an-argument
The @my_config
hash will look like:
{:myraider_an_argument => true, :myraider_an_argument_given => true}
Be aware that there’s no namespacing between raider arguments, so it’s recommended that you prefix your argument with the raider’s name, such as --myraider-an-argument
. Also be aware that the automatic short-options are very likely to clash horribly, so try to avoid using these. Finally, there is presently no way to get help about raider arguments.