prometheus-aanet-exporter 3.58 KB
Newer Older
Robert May's avatar
Robert May committed
1 2 3 4 5 6 7 8 9 10 11 12
#!/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"

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
# 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

Robert May's avatar
Robert May committed
56 57 58 59 60 61 62 63
# Settings
set :environment, :production
set :bind, "0.0.0.0"
set :port, 9729
set :stats_url, nil

config_file "/etc/prometheus/aanet.yml"

64 65
set :metrics, Metrics.new

Robert May's avatar
Robert May committed
66 67 68 69 70 71 72 73 74
exit 0 if settings.stats_url.nil?

# Routes
get "/" do
  "<a href='/metrics'>Metrics</a>"
end

get "/metrics" do
  stats_doc = HTTParty.get(settings.stats_url)
75
  metrics = settings.metrics
Robert May's avatar
Robert May committed
76 77 78 79 80

  if stats_doc.success?
    _, cqm = *stats_doc.first
    graph = cqm["graph"]

81 82 83 84 85
    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)
Robert May's avatar
Robert May committed
86 87

    graph["record"].last.tap do |record|
88 89 90 91 92 93 94
      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)
Robert May's avatar
Robert May committed
95 96 97
    end
  end

98
  metrics.render
Robert May's avatar
Robert May committed
99
end