#!/usr/bin/env ruby # # Fetch A&A line stats and return them to Prometheus # require "httparty" require "prometheus/client" require "prometheus/client/formats/text" require "sinatra" require "sinatra/config_file" require "yaml" # Metrics wrapper class for convenience class Metrics attr_reader :registry attr_reader :tx_bytes_to_date attr_reader :rx_bytes_to_date attr_reader :tx_pkts_to_date attr_reader :rx_pkts_to_date attr_reader :tx_drops_to_date attr_reader :min_latency_ns attr_reader :avg_latency_ns attr_reader :max_latency_ns attr_reader :avg_rx_bps attr_reader :avg_tx_bps attr_reader :score attr_reader :sent_polls attr_reader :lost_polls def initialize @registry = Prometheus::Client.registry # General metrics @tx_bytes_to_date = @registry.gauge(:aanet_tx_bytes_to_date, docstring: "Transmitted bytes to date") @rx_bytes_to_date = @registry.gauge(:aanet_rx_bytes_to_date, docstring: "Received bytes to date") @tx_pkts_to_date = @registry.gauge(:aanet_tx_pkts_to_date, docstring: "Transmitted packets to date") @rx_pkts_to_date = @registry.gauge(:aanet_rx_pkts_to_date, docstring: "Received packets to date") @tx_drops_to_date = @registry.gauge(:aanet_tx_drops_to_date, docstring: "Packet transmission failures to date") # Metrics from the most recent record returned @min_latency_ns = @registry.gauge(:aanet_min_latency_ns, docstring: "Minimum latency in nanoseconds from most recent record") @avg_latency_ns = @registry.gauge(:aanet_avg_latency_ns, docstring: "Average latency in nanoseconds from most recent record") @max_latency_ns = @registry.gauge(:aanet_max_latency_ns, docstring: "Maximum latency in nanoseconds from most recent record") @avg_rx_bps = @registry.gauge(:aanet_avg_rx_bps, docstring: "Average bytes per second received from most recent record") @avg_tx_bps = @registry.gauge(:aanet_avg_tx_bps, docstring: "Average bytes per second transmitted from most recent record") @score = @registry.gauge(:aanet_score, docstring: "Score from most recent record") @sent_polls = @registry.gauge(:aanet_sent_polls, docstring: "Number of pings sent from most recent record") @lost_polls = @registry.gauge(:aanet_lost_polls, docstring: "Number of pings failed from most recent record") end def render Prometheus::Client::Formats::Text.marshal(@registry) end end # Settings set :environment, :production set :bind, "0.0.0.0" set :port, 9729 set :stats_url, nil config_file "/etc/prometheus/aanet.yml" set :metrics, Metrics.new exit 0 if settings.stats_url.nil? # Routes get "/" do "Metrics" end get "/metrics" do stats_doc = HTTParty.get(settings.stats_url) metrics = settings.metrics if stats_doc.success? _, cqm = *stats_doc.first graph = cqm["graph"] metrics.tx_bytes_to_date.set(graph["tx_bytes_to_date"].to_i) metrics.rx_bytes_to_date.set(graph["rx_bytes_to_date"].to_i) metrics.tx_pkts_to_date.set(graph["tx_pkts_to_date"].to_i) metrics.rx_pkts_to_date.set(graph["rx_pkts_to_date"].to_i) metrics.tx_drops_to_date.set(graph["tx_drops_to_date"].to_i) graph["record"].last.tap do |record| metrics.min_latency_ns.set(record["min_latency_ns"].to_i) metrics.avg_latency_ns.set(record["ave_latency_ns"].to_i) metrics.max_latency_ns.set(record["max_latency_ns"].to_i) metrics.avg_rx_bps.set(record["ave_rx_bps"].to_i) metrics.avg_tx_bps.set(record["ave_tx_bps"].to_i) metrics.sent_polls.set(record["sent_polls"].to_i) metrics.lost_polls.set(record["lost_polls"].to_i) end end metrics.render end