Class PrometheusMetrics

java.lang.Object
org.acemq.rabbitmq.admin.metrics.PrometheusMetrics

public final class PrometheusMetrics extends Object
Reads RabbitMQ's Prometheus endpoint.

 PrometheusMetrics metrics = PrometheusMetrics.at("http://localhost:15692");

 long waiting = metrics.scrapeDetailed()
         .forQueue("orders.new")
         .metric("rabbitmq_detailed_queue_messages_ready")
         .map(MetricSample::asLong)
         .orElse(0L);
 

Two endpoints, and the difference matters

/metrics is aggregate. rabbitmq_queue_messages_ready with no labels: the total across the whole broker. It cannot tell you which queue is deep, and a dashboard built on it will show a backlog without saying where.

/metrics/detailed is per-object, and only for the metric families you ask for. The names gain a rabbitmq_detailed_ prefix and the labels appear: rabbitmq_detailed_queue_messages_ready{vhost="/",queue="orders.new"}. This is what "messages per queue" needs, and it is not the default because it costs the broker real work on an estate with many thousands of queues.

scrape() reads the first; scrapeDetailed() reads the second with the families this library's alerts need.

A different port, and no credentials

15692, not 15672, and a different plugin — rabbitmq_prometheus rather than rabbitmq_management. It is unauthenticated by default, which is deliberate on RabbitMQ's part and worth knowing: anything that can reach the port can read every queue name on the broker.

  • Field Details

    • DEFAULT_PORT

      public static final int DEFAULT_PORT
      What RabbitMQ's Prometheus plugin listens on.
      See Also:
  • Method Details

    • at

      public static PrometheusMetrics at(String url)
      Parameters:
      url - where the Prometheus plugin listens, for example http://localhost:15692
      Returns:
      a scraper
    • at

      public static PrometheusMetrics at(String url, Duration timeout)
      Parameters:
      url - where the Prometheus plugin listens
      timeout - how long a scrape may take
      Returns:
      a scraper
    • scrape

      public MetricsSnapshot scrape()
      Returns:
      the aggregate scrape: broker-wide totals, no per-queue labels
    • scrapeDetailed

      public MetricsSnapshot scrapeDetailed()
      Returns:
      the per-object scrape, limited to the families this library's alerts use. Metric names carry the rabbitmq_detailed_ prefix
    • scrapeDetailed

      public MetricsSnapshot scrapeDetailed(String... families)
      Parameters:
      families - the metric families to ask for, without the family= prefix. Note that scrapeDetailed() written with empty parentheses calls scrapeDetailed() above, not this method with an empty array — Java prefers the more specific overload. This guard therefore catches the case that actually happens in practice: a caller passing a list of families that turned out to be empty
      Returns:
      a per-object scrape of exactly those
    • parse

      public static MetricsSnapshot parse(String body)
      Parses the Prometheus text exposition format.

      Small on purpose. The format is a line per sample, and the only genuinely fiddly parts are that a label value may contain an escaped quote or a comma, and that a line may carry a trailing timestamp that is not the value.

      Public because a scrape does not have to come from here. Prometheus itself, a sidecar, a file captured during an incident or a federated scrape endpoint all produce this format, and an alert should be evaluable against any of them — the rules in org.acemq.rabbitmq.admin.alerts care about the samples, not about who fetched them.

      Parameters:
      body - a scrape in the Prometheus text exposition format
      Returns:
      the samples in it
    • toString

      public String toString()
      Overrides:
      toString in class Object