bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/rabbitmq.go (about)

     1  package collectors
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"net/url"
     8  	"strings"
     9  
    10  	"bosun.org/metadata"
    11  	"bosun.org/opentsdb"
    12  )
    13  
    14  var (
    15  	rmqQueueStatusMap = map[string]int{
    16  		"running": 0,
    17  		"syncing": 1,
    18  		"flow":    2,
    19  		"idle":    3,
    20  		"down":    4,
    21  	}
    22  )
    23  
    24  const (
    25  	defaultRabbitmqURL string = "http://guest:guest@localhost:15672"
    26  	rmqPrefix                 = "rabbitmq."
    27  )
    28  
    29  func init() {
    30  	collectors = append(collectors, &IntervalCollector{F: c_rabbitmq_overview, Enable: enableRabbitmq})
    31  	collectors = append(collectors, &IntervalCollector{F: c_rabbitmq_queues, Enable: enableRabbitmq})
    32  	collectors = append(collectors, &IntervalCollector{F: c_rabbitmq_nodes, Enable: enableRabbitmq})
    33  }
    34  
    35  // RabbitMQ registers a RabbitMQ collector.
    36  func RabbitMQ(url string) error {
    37  	safeURL, err := urlUserHost(url)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	collectors = append(collectors,
    42  		&IntervalCollector{
    43  			F: func() (opentsdb.MultiDataPoint, error) {
    44  				return rabbitmqOverview(url)
    45  			},
    46  			name: fmt.Sprintf("rabbitmq-overview-%s", safeURL),
    47  		},
    48  		&IntervalCollector{
    49  			F: func() (opentsdb.MultiDataPoint, error) {
    50  				return rabbitmqNodes(url)
    51  			},
    52  			name: fmt.Sprintf("rabbitmq-nodes-%s", safeURL),
    53  		},
    54  		&IntervalCollector{
    55  			F: func() (opentsdb.MultiDataPoint, error) {
    56  				return rabbitmqQueues(url)
    57  			},
    58  			name: fmt.Sprintf("rabbitmq-queues-%s", safeURL),
    59  		})
    60  	return nil
    61  }
    62  
    63  func enableRabbitmq() bool {
    64  	return enableURL(defaultRabbitmqURL)()
    65  }
    66  
    67  func c_rabbitmq_overview() (opentsdb.MultiDataPoint, error) {
    68  	return rabbitmqOverview(defaultRabbitmqURL)
    69  
    70  }
    71  func c_rabbitmq_nodes() (opentsdb.MultiDataPoint, error) {
    72  	return rabbitmqNodes(defaultRabbitmqURL)
    73  }
    74  func c_rabbitmq_queues() (opentsdb.MultiDataPoint, error) {
    75  	return rabbitmqQueues(defaultRabbitmqURL)
    76  }
    77  
    78  func rabbitmqOverview(s string) (opentsdb.MultiDataPoint, error) {
    79  	p := rmqPrefix + "overview."
    80  	res, err := http.Get(s + "/api/overview")
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	defer res.Body.Close()
    85  	var o rmqOverview
    86  	if err := json.NewDecoder(res.Body).Decode(&o); err != nil {
    87  		return nil, err
    88  	}
    89  	var md opentsdb.MultiDataPoint
    90  	splitNode := strings.Split(o.Node, "@")
    91  	if len(splitNode) < 2 {
    92  		return nil, fmt.Errorf("Error: invalid RabbitMQ node name, can not split '%s'", o.Node)
    93  	}
    94  	host := splitNode[1]
    95  	ts := opentsdb.TagSet{"host": host}
    96  	Add(&md, p+"channels", o.ObjectTotals.Channels, ts, metadata.Gauge, metadata.Channel, DescRmqObjecttotalsChannels)
    97  	Add(&md, p+"connections", o.ObjectTotals.Connections, ts, metadata.Gauge, metadata.Connection, DescRmqObjectTotalsConnections)
    98  	Add(&md, p+"consumers", o.ObjectTotals.Consumers, ts, metadata.Gauge, metadata.Consumer, DescRmqObjectTotalsConsumers)
    99  	Add(&md, p+"exchanges", o.ObjectTotals.Exchanges, ts, metadata.Gauge, metadata.Exchange, DescRmqObjectTotalsExchanges)
   100  	Add(&md, p+"queues", o.ObjectTotals.Queues, ts, metadata.Gauge, metadata.Queue, DescRmqObjectTotalsQueues)
   101  	msgStats := rabbitmqMessageStats(p, ts, o.MessageStats)
   102  	md = append(md, msgStats...)
   103  	return md, nil
   104  }
   105  
   106  func rabbitmqQueues(s string) (opentsdb.MultiDataPoint, error) {
   107  	p := rmqPrefix + "queue."
   108  	res, err := http.Get(s + "/api/queues")
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  	defer res.Body.Close()
   113  	var qs []rmqQueue
   114  	if err := json.NewDecoder(res.Body).Decode(&qs); err != nil {
   115  		return nil, err
   116  	}
   117  	var md opentsdb.MultiDataPoint
   118  	for _, q := range qs {
   119  		if strings.HasPrefix(q.Name, "amq.gen-") {
   120  			continue // skip auto-generated queues
   121  		}
   122  		splitNode := strings.Split(q.Node, "@")
   123  		if len(splitNode) < 2 {
   124  			return nil, fmt.Errorf("Error: invalid RabbitMQ node name, can not split '%s'", q.Node)
   125  		}
   126  		host := splitNode[1]
   127  		ts := opentsdb.TagSet{"host": host, "queue": q.Name, "vhost": q.Vhost}
   128  		Add(&md, p+"consumers", q.Consumers, ts, metadata.Gauge, metadata.Consumer, DescRmqConsumers)
   129  		Add(&md, p+"memory", q.Memory, ts, metadata.Gauge, metadata.Bytes, DescRmqMemory)
   130  		Add(&md, p+"message_bytes_total", q.MessageBytes, ts, metadata.Gauge, metadata.Bytes, DescRmqMessageBytes)
   131  		Add(&md, p+"message_bytes_persistent", q.MessageBytesPersistent, ts, metadata.Gauge, metadata.Bytes, DescRmqMessageBytesPersistent)
   132  		Add(&md, p+"message_bytes_transient", q.MessageBytesRAM, ts, metadata.Gauge, metadata.Bytes, DescRmqMessageBytesRAM)
   133  		Add(&md, p+"message_bytes_ready", q.MessageBytesReady, ts, metadata.Gauge, metadata.Bytes, DescRmqMessageBytesReady)
   134  		Add(&md, p+"message_bytes_unack", q.MessageBytesUnacknowledged, ts, metadata.Gauge, metadata.Bytes, DescRmqMessageBytesUnacknowledged)
   135  		Add(&md, p+"messages_queue_depth", q.Messages, ts, metadata.Gauge, metadata.Message, DescRmqMessages)
   136  		Add(&md, p+"messages_persistent", q.MessagesPersistent, ts, metadata.Gauge, metadata.Message, DescRmqMessagesPersistent)
   137  		Add(&md, p+"messages_transient", q.MessagesRAM, ts, metadata.Gauge, metadata.Message, DescRmqMessagesRAM)
   138  		Add(&md, p+"messages_ready_total", q.MessagesReady, ts, metadata.Gauge, metadata.Message, DescRmqMessagesReady)
   139  		Add(&md, p+"messages_ready_transient", q.MessagesReadyRAM, ts, metadata.Gauge, metadata.Message, DescRmqMessagesReadyRAM)
   140  		Add(&md, p+"messages_unack_total", q.MessagesUnacknowledged, ts, metadata.Gauge, metadata.Message, DescRmqMessagesUnacknowledged)
   141  		Add(&md, p+"messages_unack_transient", q.MessagesUnacknowledgedRAM, ts, metadata.Gauge, metadata.Message, DescRmqMessagesUnacknowledgedRAM)
   142  		if sn, ok := q.SlaveNodes.([]interface{}); ok {
   143  			Add(&md, p+"slave_nodes", len(sn), ts, metadata.Gauge, metadata.Node, DescRmqSlaveNodes)
   144  		}
   145  		if dsn, ok := q.DownSlaveNodes.([]interface{}); ok {
   146  			Add(&md, p+"down_slave_nodes", len(dsn), ts, metadata.Gauge, metadata.Node, DescRmqDownSlaveNodes)
   147  
   148  		}
   149  		if ssn, ok := q.SynchronisedSlaveNodes.([]interface{}); ok {
   150  			Add(&md, p+"sync_slave_nodes", len(ssn), ts, metadata.Gauge, metadata.Node, DescRmqSynchronisedSlaveNodes)
   151  
   152  		}
   153  		if cu, ok := q.ConsumerUtilisation.(float64); ok {
   154  			Add(&md, p+"consumer_utilisation", cu, ts, metadata.Gauge, metadata.Fraction, DescRmqConsumerUtilisation)
   155  		}
   156  		msgStats := rabbitmqMessageStats(p, ts, q.MessageStats)
   157  		md = append(md, msgStats...)
   158  		backingQueueStatus := rabbitmqBackingQueueStatus(p+"backing_queue.", ts, q.BackingQueueStatus)
   159  		md = append(md, backingQueueStatus...)
   160  		if state, ok := rmqQueueStatusMap[q.State]; ok {
   161  			Add(&md, p+"state", state, ts, metadata.Gauge, metadata.StatusCode, DescRmqState)
   162  		} else {
   163  			Add(&md, p+"state", -1, ts, metadata.Gauge, metadata.StatusCode, DescRmqState)
   164  		}
   165  	}
   166  	return md, nil
   167  }
   168  func rabbitmqNodes(s string) (opentsdb.MultiDataPoint, error) {
   169  	p := rmqPrefix + "node."
   170  	res, err := http.Get(s + "/api/nodes")
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	defer res.Body.Close()
   175  	var ns []rmqNode
   176  	if err := json.NewDecoder(res.Body).Decode(&ns); err != nil {
   177  		return nil, err
   178  	}
   179  	var md opentsdb.MultiDataPoint
   180  	for _, n := range ns {
   181  		splitName := strings.Split(n.Name, "@")
   182  		if len(splitName) < 2 {
   183  			return nil, fmt.Errorf("Error: invalid RabbitMQ node name, can not split '%s'", n.Name)
   184  		}
   185  		host := splitName[1]
   186  		ts := opentsdb.TagSet{"host": host}
   187  		Add(&md, p+"disk_free", n.DiskFree, ts, metadata.Gauge, metadata.Consumer, DescRmqDiskFree)
   188  		Add(&md, p+"disk_free_alarm", n.DiskFreeAlarm, ts, metadata.Gauge, metadata.Bool, DescRmqDiskFreeAlarm)
   189  		Add(&md, p+"disk_free_limit", n.DiskFreeLimit, ts, metadata.Gauge, metadata.Consumer, DescRmqDiskFreeLimit)
   190  		Add(&md, p+"fd_total", n.FDTotal, ts, metadata.Gauge, metadata.Files, DescRmqFDTotal)
   191  		Add(&md, p+"fd_used", n.FDUsed, ts, metadata.Gauge, metadata.Files, DescRmqFDUsed)
   192  		Add(&md, p+"mem_used", n.MemUsed, ts, metadata.Gauge, metadata.Bytes, DescRmqMemUsed)
   193  		Add(&md, p+"mem_alarm", n.MemAlarm, ts, metadata.Gauge, metadata.Bool, DescRmqMemAlarm)
   194  		Add(&md, p+"mem_limit", n.MemLimit, ts, metadata.Gauge, metadata.Bytes, DescRmqMemLimit)
   195  		Add(&md, p+"proc_used", n.ProcUsed, ts, metadata.Gauge, metadata.Process, DescRmqProcUsed)
   196  		Add(&md, p+"proc_total", n.ProcTotal, ts, metadata.Gauge, metadata.Process, DescRmqProcTotal)
   197  		Add(&md, p+"sockets_used", n.SocketsUsed, ts, metadata.Gauge, metadata.Socket, DescRmqSocketsUsed)
   198  		Add(&md, p+"sockets_total", n.SocketsTotal, ts, metadata.Gauge, metadata.Socket, DescRmqSocketsTotal)
   199  		Add(&md, p+"uptime", n.Uptime, ts, metadata.Gauge, metadata.Second, DescRmqUptime)
   200  		Add(&md, p+"running", n.Running, ts, metadata.Gauge, metadata.StatusCode, DescRmqRunning)
   201  		if partitions, ok := n.Partitions.([]interface{}); ok {
   202  			Add(&md, p+"partitions", len(partitions), ts, metadata.Gauge, metadata.Node, DescRmqPartitions)
   203  		}
   204  
   205  	}
   206  	return md, nil
   207  }
   208  
   209  func rabbitmqMessageStats(p string, ts opentsdb.TagSet, ms rmqMessageStats) opentsdb.MultiDataPoint {
   210  	var md opentsdb.MultiDataPoint
   211  	Add(&md, p+"message_stats", ms.Ack, ts.Copy().Merge(opentsdb.TagSet{"method": "ack"}),
   212  		metadata.Counter, metadata.Message, DescRmqMessageStatsAck)
   213  	Add(&md, p+"message_stats", ms.Confirm, ts.Copy().Merge(opentsdb.TagSet{"method": "confirm"}),
   214  		metadata.Counter, metadata.Message, DescRmqMessageStatsConfirm)
   215  	Add(&md, p+"message_stats", ms.Deliver, ts.Copy().Merge(opentsdb.TagSet{"method": "deliver"}),
   216  		metadata.Counter, metadata.Message, DescRmqMessageStatsDeliver)
   217  	Add(&md, p+"message_stats", ms.DeliverGet, ts.Copy().Merge(opentsdb.TagSet{"method": "deliver_get"}),
   218  		metadata.Counter, metadata.Message, DescRmqMessageStatsDeliverGet)
   219  	Add(&md, p+"message_stats", ms.DeliverNoAck, ts.Copy().Merge(opentsdb.TagSet{"method": "deliver_noack"}),
   220  		metadata.Counter, metadata.Message, DescRmqMessageStatsDeliverNoAck)
   221  	Add(&md, p+"message_stats", ms.Get, ts.Copy().Merge(opentsdb.TagSet{"method": "get"}),
   222  		metadata.Counter, metadata.Message, DescRmqMessageStatsGet)
   223  	Add(&md, p+"message_stats", ms.GetNoAck, ts.Copy().Merge(opentsdb.TagSet{"method": "get_noack"}),
   224  		metadata.Counter, metadata.Message, DescRmqMessageStatsGetNoack)
   225  	Add(&md, p+"message_stats", ms.Publish, ts.Copy().Merge(opentsdb.TagSet{"method": "publish"}),
   226  		metadata.Counter, metadata.Message, DescRmqMessageStatsPublish)
   227  	Add(&md, p+"message_stats", ms.PublishIn, ts.Copy().Merge(opentsdb.TagSet{"method": "publish_in"}),
   228  		metadata.Counter, metadata.Message, DescRmqMessageStatsPublishIn)
   229  	Add(&md, p+"message_stats", ms.PublishOut, ts.Copy().Merge(opentsdb.TagSet{"method": "publish_out"}),
   230  		metadata.Counter, metadata.Message, DescRmqMessageStatsPublishOut)
   231  	Add(&md, p+"message_stats", ms.Redeliver, ts.Copy().Merge(opentsdb.TagSet{"method": "redeliver"}),
   232  		metadata.Counter, metadata.Message, DescRmqMessageStatsRedeliver)
   233  	Add(&md, p+"message_stats", ms.Return, ts.Copy().Merge(opentsdb.TagSet{"method": "return"}),
   234  		metadata.Counter, metadata.Message, DescRmqMessageStatsReturn)
   235  	return md
   236  }
   237  
   238  func rabbitmqBackingQueueStatus(p string, ts opentsdb.TagSet, bqs rmqBackingQueueStatus) opentsdb.MultiDataPoint {
   239  	var md opentsdb.MultiDataPoint
   240  	Add(&md, p+"avg_rate", bqs.AvgAckEgressRate, ts.Copy().Merge(opentsdb.TagSet{"method": "ack", "direction": "out"}),
   241  		metadata.Rate, metadata.Message, DescRmqBackingQueueStatusAvgAckEgressRate)
   242  	Add(&md, p+"avg_rate", bqs.AvgAckIngressRate, ts.Copy().Merge(opentsdb.TagSet{"method": "ack", "direction": "in"}),
   243  		metadata.Rate, metadata.Message, DescRmqBackingQueueStatusAvgAckIngressRate)
   244  	Add(&md, p+"avg_rate", bqs.AvgEgressRate, ts.Copy().Merge(opentsdb.TagSet{"method": "noack", "direction": "out"}),
   245  		metadata.Rate, metadata.Message, DescRmqBackingQueueStatusAvgEgressRate)
   246  	Add(&md, p+"avg_rate", bqs.AvgIngressRate, ts.Copy().Merge(opentsdb.TagSet{"method": "noack", "direction": "in"}),
   247  		metadata.Rate, metadata.Message, DescRmqBackingQueueStatusAvgIngressRate)
   248  	Add(&md, p+"len", bqs.Len, ts,
   249  		metadata.Gauge, metadata.Message, DescRmqBackingQueueStatusLen)
   250  	return md
   251  }
   252  
   253  func urlUserHost(s string) (string, error) {
   254  	u, err := url.Parse(s)
   255  	if err != nil {
   256  		return "", err
   257  	}
   258  	if u.User != nil {
   259  		res := fmt.Sprintf("%s@%s", u.User.Username(), u.Host)
   260  		return res, nil
   261  	}
   262  	res := fmt.Sprintf("%s", u.Host)
   263  	return res, nil
   264  }
   265  
   266  type rmqOverview struct {
   267  	ClusterName  string          `json:"cluster_name"`
   268  	MessageStats rmqMessageStats `json:"message_stats"`
   269  	QueueTotals  struct {
   270  		Messages               int `json:"messages"`
   271  		MessagesReady          int `json:"messages_ready"`
   272  		MessagesUnacknowledged int `json:"messages_unacknowledged"`
   273  	} `json:"queue_totals"`
   274  	ObjectTotals struct {
   275  		Consumers   int `json:"consumers"`
   276  		Queues      int `json:"queues"`
   277  		Exchanges   int `json:"exchanges"`
   278  		Connections int `json:"connections"`
   279  		Channels    int `json:"channels"`
   280  	} `json:"object_totals"`
   281  	Node string `json:"node"`
   282  }
   283  
   284  type rmqNode struct {
   285  	DiskFree      int64       `json:"disk_free"`
   286  	DiskFreeAlarm bool        `json:"disk_free_alarm"`
   287  	DiskFreeLimit int         `json:"disk_free_limit"`
   288  	FDTotal       int         `json:"fd_total"`
   289  	FDUsed        int         `json:"fd_used"`
   290  	MemAlarm      bool        `json:"mem_alarm"`
   291  	MemLimit      int64       `json:"mem_limit"`
   292  	MemUsed       int         `json:"mem_used"`
   293  	Name          string      `json:"name"`
   294  	Partitions    interface{} `json:"partitions"`
   295  	ProcTotal     int         `json:"proc_total"`
   296  	ProcUsed      int         `json:"proc_used"`
   297  	Processors    int         `json:"processors"`
   298  	RunQueue      int         `json:"run_queue"`
   299  	Running       bool        `json:"running"`
   300  	SocketsTotal  int         `json:"sockets_total"`
   301  	SocketsUsed   int         `json:"sockets_used"`
   302  	Uptime        int         `json:"uptime"`
   303  }
   304  
   305  type rmqQueue struct {
   306  	Messages                   int                   `json:"messages"`
   307  	MessagesReady              int                   `json:"messages_ready"`
   308  	MessagesUnacknowledged     int                   `json:"messages_unacknowledged"`
   309  	Consumers                  int                   `json:"consumers"`
   310  	ConsumerUtilisation        interface{}           `json:"consumer_utilisation"`
   311  	Memory                     int                   `json:"memory"`
   312  	SlaveNodes                 interface{}           `json:"slave_nodes"`
   313  	SynchronisedSlaveNodes     interface{}           `json:"synchronised_slave_nodes"`
   314  	DownSlaveNodes             interface{}           `json:"down_slave_nodes"`
   315  	BackingQueueStatus         rmqBackingQueueStatus `json:"backing_queue_status"`
   316  	State                      string                `json:"state"`
   317  	MessagesRAM                int                   `json:"messages_ram"`
   318  	MessagesReadyRAM           int                   `json:"messages_ready_ram"`
   319  	MessagesUnacknowledgedRAM  int                   `json:"messages_unacknowledged_ram"`
   320  	MessagesPersistent         int                   `json:"messages_persistent"`
   321  	MessageBytes               int                   `json:"message_bytes"`
   322  	MessageBytesReady          int                   `json:"message_bytes_ready"`
   323  	MessageBytesUnacknowledged int                   `json:"message_bytes_unacknowledged"`
   324  	MessageBytesRAM            int                   `json:"message_bytes_ram"`
   325  	MessageBytesPersistent     int                   `json:"message_bytes_persistent"`
   326  	Name                       string                `json:"name"`
   327  	Vhost                      string                `json:"vhost"`
   328  	Durable                    bool                  `json:"durable"`
   329  	Node                       string                `json:"node"`
   330  	MessageStats               rmqMessageStats       `json:"message_stats"`
   331  }
   332  
   333  type rmqMessageStats struct {
   334  	Ack          int `json:"ack"`
   335  	Confirm      int `json:"confirm"`
   336  	Deliver      int `json:"deliver"`
   337  	DeliverGet   int `json:"deliver_get"`
   338  	DeliverNoAck int `json:"deliver_no_ack"`
   339  	Get          int `json:"get"`
   340  	GetAck       int `json:"get_ack"`
   341  	GetNoAck     int `json:"get_noack"`
   342  	Publish      int `json:"publish"`
   343  	PublishIn    int `json:"publish_in"`
   344  	PublishOut   int `json:"publish_out"`
   345  	Redeliver    int `json:"redeliver"`
   346  	Return       int `json:"return"`
   347  }
   348  
   349  type rmqBackingQueueStatus struct {
   350  	Len               int     `json:"len"`
   351  	AvgIngressRate    float64 `json:"avg_ingress_rate"`
   352  	AvgEgressRate     float64 `json:"avg_egress_rate"`
   353  	AvgAckIngressRate float64 `json:"avg_ack_ingress_rate"`
   354  	AvgAckEgressRate  float64 `json:"avg_ack_egress_rate"`
   355  	MirrorSeen        int     `json:"mirror_seen"`
   356  	MirrorSenders     int     `json:"mirror_senders"`
   357  }
   358  
   359  const (
   360  	DescRmqBackingQueueStatusAvgAckEgressRate  = "Rate at which unacknowledged message records leave RAM, e.g. because acks arrive or unacked messages are paged out"
   361  	DescRmqBackingQueueStatusAvgAckIngressRate = "Rate at which unacknowledged message records enter RAM, e.g. because messages are delivered requiring acknowledgement"
   362  	DescRmqBackingQueueStatusAvgEgressRate     = "Average egress (outbound) rate, not including messages that straight through to auto-acking consumers."
   363  	DescRmqBackingQueueStatusAvgIngressRate    = "Average ingress (inbound) rate, not including messages that straight through to auto-acking consumers."
   364  	DescRmqBackingQueueStatusLen               = "Total backing queue length."
   365  	DescRmqConsumers                           = "Number of consumers."
   366  	DescRmqConsumerUtilisation                 = "Fraction of the time (between 0.0 and 1.0) that the queue is able to immediately deliver messages to consumers. This can be less than 1.0 if consumers are limited by network congestion or prefetch count."
   367  	DescRmqDiskFreeAlarm                       = "Whether the disk alarm has gone off."
   368  	DescRmqDiskFree                            = "Disk free space in bytes."
   369  	DescRmqDiskFreeLimit                       = "Point at which the disk alarm will go off."
   370  	DescRmqDownSlaveNodes                      = "Count of down nodes having a copy of the queue."
   371  	DescRmqFDTotal                             = "File descriptors available."
   372  	DescRmqFDUsed                              = "Used file descriptors."
   373  	DescRmqIOReadAvgTime                       = "Average wall time (milliseconds) for each disk read operation in the last statistics interval."
   374  	DescRmqIOReadBytes                         = "Total number of bytes read from disk by the persister."
   375  	DescRmqIOReadCount                         = "Total number of read operations by the persister."
   376  	DescRmqIOReopenCount                       = "Total number of times the persister has needed to recycle file handles between queues. In an ideal world this number will be zero; if the number is large, performance might be improved by increasing the number of file handles available to RabbitMQ."
   377  	DescRmqIOSeekAvgTime                       = "Average wall time (milliseconds) for each seek operation in the last statistics interval."
   378  	DescRmqIOSeekCount                         = "Total number of seek operations by the persister."
   379  	DescRmqIOSyncAvgTime                       = "Average wall time (milliseconds) for each sync operation in the last statistics interval."
   380  	DescRmqIOSyncCount                         = "Total number of fsync() operations by the persister."
   381  	DescRmqIOWriteAvgTime                      = "Average wall time (milliseconds) for each write operation in the last statistics interval."
   382  	DescRmqIOWriteBytes                        = "Total number of bytes written to disk by the persister."
   383  	DescRmqIOWriteCount                        = "Total number of write operations by the persister."
   384  	DescRmqMemAlarm                            = ""
   385  	DescRmqMemLimit                            = "Point at which the memory alarm will go off."
   386  	DescRmqMemory                              = "Bytes of memory consumed by the Erlang process associated with the queue, including stack, heap and internal structures."
   387  	DescRmqMemUsed                             = "Memory used in bytes."
   388  	DescRmqMessageBytesPersistent              = "Like messageBytes but counting only those messages which are persistent."
   389  	DescRmqMessageBytesRAM                     = "Like messageBytes but counting only those messages which are in RAM."
   390  	DescRmqMessageBytesReady                   = "Like messageBytes but counting only those messages ready to be delivered to clients."
   391  	DescRmqMessageBytes                        = "Sum of the size of all message bodies in the queue. This does not include the message properties (including headers) or any overhead."
   392  	DescRmqMessageBytesUnacknowledged          = "Like messageBytes but counting only those messages delivered to clients but not yet acknowledged."
   393  	DescRmqMessagesPersistent                  = "Total number of persistent messages in the queue (will always be 0 for transient queues)."
   394  	DescRmqMessagesRAM                         = "Total number of messages which are resident in ram."
   395  	DescRmqMessagesReady                       = "Number of messages ready to be delivered to clients."
   396  	DescRmqMessagesReadyRAM                    = "Number of messages from messagesReady which are resident in ram."
   397  	DescRmqMessages                            = "Sum of ready and unacknowledged messages (queue depth)."
   398  	DescRmqMessageStatsAck                     = "Count of acknowledged messages."
   399  	DescRmqMessageStatsConfirm                 = "Count of messages confirmed."
   400  	DescRmqMessageStatsDeliver                 = "Count of messages delivered in acknowledgement mode to consumers."
   401  	DescRmqMessageStatsDeliverGet              = "Sum of deliver, deliverNoack, get, getNoack."
   402  	DescRmqMessageStatsDeliverNoAck            = "Count of messages delivered in no-acknowledgement mode to consumers."
   403  	DescRmqMessageStatsGet                     = "Count of messages delivered in acknowledgement mode in response to basic.get."
   404  	DescRmqMessageStatsGetNoack                = "Count of messages delivered in no-acknowledgement mode in response to basic.get."
   405  	DescRmqMessageStatsPublish                 = "Count of messages published."
   406  	DescRmqMessageStatsPublishIn               = "Count of messages published \"in\" to an exchange, i.e. not taking account of routing."
   407  	DescRmqMessageStatsPublishOut              = "Count of messages published \"out\" of an exchange, i.e. taking account of routing."
   408  	DescRmqMessageStatsRedeliver               = "Count of subset of messages in deliverGet which had the redelivered flag set."
   409  	DescRmqMessageStatsReturn                  = "Count of messages returned to publisher as unroutable."
   410  	DescRmqMessagesUnacknowledged              = "Number of messages delivered to clients but not yet acknowledged."
   411  	DescRmqMessagesUnacknowledgedRAM           = "Number of messages from messagesUnacknowledged which are resident in ram."
   412  	DescRmqMnesiaDiskTxCount                   = "Number of Mnesia transactions which have been performed that required writes to disk. (e.g. creating a durable queue). Only transactions which originated on this node are included."
   413  	DescRmqMnesiaRAMTxCount                    = "Number of Mnesia transactions which have been performed that did not require writes to disk. (e.g. creating a transient queue). Only transactions which originated on this node are included."
   414  	DescRmqMsgStoreReadCount                   = "Number of messages which have been read from the message store."
   415  	DescRmqMsgStoreWriteCount                  = "Number of messages which have been written to the message store."
   416  	DescRmqObjecttotalsChannels                = "Overall number of channels."
   417  	DescRmqObjectTotalsConnections             = "Overall number of connections."
   418  	DescRmqObjectTotalsConsumers               = "Overall number of consumers."
   419  	DescRmqObjectTotalsExchanges               = "Overall number of exchanges."
   420  	DescRmqObjectTotalsQueues                  = "Overall number of queues."
   421  	DescRmqPartitions                          = "Count of network partitions this node is seeing."
   422  	DescRmqProcessors                          = "Number of cores detected and usable by Erlang."
   423  	DescRmqProcTotal                           = "Maximum number of Erlang processes."
   424  	DescRmqProcUsed                            = "Number of Erlang processes in use."
   425  	DescRmqQueueIndexJournalWriteCount         = "Number of records written to the queue index journal. Each record represents a message being published to a queue, being delivered from a queue, and being acknowledged in a queue."
   426  	DescRmqQueueIndexReadCount                 = "Number of records read from the queue index."
   427  	DescRmqQueueIndexWriteCount                = "Number of records written to the queue index."
   428  	DescRmqQueueTotalsMessages                 = "Overall sum of ready and unacknowledged messages (queue depth)."
   429  	DescRmqQueueTotalsMessagesReady            = "Overall number of messages ready to be delivered to clients."
   430  	DescRmqQueueTotalsMessagesUnacknowledged   = "Overall number of messages delivered to clients but not yet acknowledged."
   431  	DescRmqRunning                             = "Boolean for whether this node is up. Obviously if this is false, most other stats will be missing."
   432  	DescRmqRunQueue                            = "Average number of Erlang processes waiting to run."
   433  	DescRmqSlaveNodes                          = "Count of nodes having a copy of the queue."
   434  	DescRmqSocketsTotal                        = "File descriptors available for use as sockets."
   435  	DescRmqSocketsUsed                         = "File descriptors used as sockets."
   436  	DescRmqState                               = "The state of the queue. Unknown=> -1, Running=> 0, Syncing=> 1, Flow=> 2, Down=> 3"
   437  	DescRmqSynchronisedSlaveNodes              = "Count of nodes having synchronised copy of the queue."
   438  	DescRmqSyncMessages                        = "Count of already synchronised messages on a slave node."
   439  	DescRmqUptime                              = "Node uptime in seconds."
   440  )