From 0cc4dcb122e88db33b1a8eb02bffe6fd3dad891e Mon Sep 17 00:00:00 2001
From: Diana Corbacho <diana@rabbitmq.com>
Date: Tue, 2 Oct 2018 11:46:33 +0100
Subject: [PATCH] Add policy and overflow, mode and type arguments as labels on
 queues

Labels should not have values with high cardinalities, as each label
generates a new time series, so keys such as exclusive_consumer_tag
should not be stored in prometheus. We could possibly argue that policy
is one of those, but it might be worth to try it out as it could be a
very useful metric.
---
 .../prometheus_rabbitmq_queues_collector.erl  | 31 +++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/collectors/prometheus_rabbitmq_queues_collector.erl b/src/collectors/prometheus_rabbitmq_queues_collector.erl
index 021d010..f245dfd 100644
--- a/src/collectors/prometheus_rabbitmq_queues_collector.erl
+++ b/src/collectors/prometheus_rabbitmq_queues_collector.erl
@@ -122,8 +122,26 @@ metric(boolean, Labels, Value0) ->
 %%====================================================================
 
 labels(Queue) ->
-  [{vhost, queue_vhost(Queue)},
-   {queue, queue_name(Queue)}].
+    %% exclusive_consumer_tag should not be used as a label. Prometheus documentation
+    %% states that labels should not be used to store dimensions with high cardinality,
+    %% as every unique combination of key-value label pairs represents a new time
+    %% series, which can dramatically increase the amount of data stored.
+    %% As such, from the arguments only x-overflow, x-queue-mode and x-queue-type
+    %% should be represented as arguments.
+    add_if_not_empty(
+      {queue_mode, queue_argument(<<"x-queue-mode">>, Queue)},
+      add_if_not_empty(
+        {type, queue_argument(<<"x-queue-type">>, Queue, <<"classic">>)},
+        add_if_not_empty(
+          {overflow, queue_argument(<<"x-overflow">>, Queue)},
+          add_if_not_empty({policy, queue_policy(Queue)},
+                           [{vhost, queue_vhost(Queue)},
+                            {queue, queue_name(Queue)}])))).
+
+add_if_not_empty({_, ''}, Acc) ->
+    Acc;
+add_if_not_empty(Tuple, Acc) ->
+    [Tuple | Acc].
 
 catch_boolean(boolean) ->
     untyped;
@@ -158,6 +176,15 @@ queue_vhost(Queue) ->
 queue_name(Queue) ->
   proplists:get_value(name, Queue).
 
+queue_policy(Queue) ->
+    proplists:get_value(policy, Queue).
+
+queue_argument(Arg, Queue) ->
+    queue_argument(Arg, Queue, '').
+
+queue_argument(Arg, Queue, Default) ->
+    maps:get(Arg, proplists:get_value(arguments, Queue), Default).
+
 queue_dir_size(Queue) ->
   QueueDirName = queue_dir_name(Queue),
   FullPath = [mnesia:system_info(directory), "/queues/", QueueDirName],