Operations 6 min read

Parsing RabbitMQ cluster_status JSON with Go: A Step‑by‑Step Guide

This article explains how to use Go to parse the JSON output of the RabbitMQ cluster_status command, defines matching Go structs, and demonstrates extracting key cluster information such as node lists, feature flags, listeners, and version details.

Ops Development & AI Practice
Ops Development & AI Practice
Ops Development & AI Practice
Parsing RabbitMQ cluster_status JSON with Go: A Step‑by‑Step Guide

In modern software development, monitoring the health of RabbitMQ, a widely used message‑queue service, is essential. The rabbitmqctl cluster_status command provides the current state of a RabbitMQ cluster, and its JSON‑formatted output can be programmatically processed.

JSON Output Structure

The command rabbitmqctl cluster_status --formatter json returns a JSON object containing fields like cluster_name, disk_nodes, feature_flags, listeners, maintenance_status, running_nodes, and versions. A sample output is shown below.

{
  "alarms": [],
  "cluster_name": "rabbit@pam-rabbitmq",
  "disk_nodes": ["rabbit@pam-rabbitmq"],
  "feature_flags": [
    {
      "desc": "Count unroutable publishes to be dropped in stats",
      "doc_url": "",
      "name": "drop_unroutable_metric",
      "provided_by": "rabbitmq_management_agent",
      "stability": "stable",
      "state": "enabled"
    }
  ],
  "listeners": {
    "rabbit@pam-rabbitmq": [
      {
        "interface": "[::]",
        "node": "rabbit@pam-rabbitmq",
        "port": 15692,
        "protocol": "http/prometheus",
        "purpose": "Prometheus exporter API over HTTP"
      }
    ]
  },
  "maintenance_status": {"rabbit@pam-rabbitmq": "not under maintenance"},
  "partitions": {},
  "ram_nodes": [],
  "running_nodes": ["rabbit@pam-rabbitmq"],
  "versions": {
    "rabbit@pam-rabbitmq": {
      "erlang_version": "24.1.7",
      "rabbitmq_name": "RabbitMQ",
      "rabbitmq_version": "3.8.26"
    }
  }
}

Defining Go Structs

To deserialize the JSON, a set of Go structs mirroring the JSON hierarchy is required. The key structs are ClusterStatus, FeatureFlag, Listener, and VersionInfo. Each field includes a JSON tag matching the source key.

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type ClusterStatus struct {
    Alarms            []interface{}          `json:"alarms"`
    ClusterName       string                 `json:"cluster_name"`
    DiskNodes         []string               `json:"disk_nodes"`
    FeatureFlags      []FeatureFlag          `json:"feature_flags"`
    Listeners         map[string][]Listener  `json:"listeners"`
    MaintenanceStatus map[string]string      `json:"maintenance_status"`
    Partitions        map[string]interface{} `json:"partitions"`
    RamNodes          []interface{}          `json:"ram_nodes"`
    RunningNodes      []string               `json:"running_nodes"`
    Versions          map[string]VersionInfo `json:"versions"`
}

type FeatureFlag struct {
    Description string `json:"desc"`
    DocURL      string `json:"doc_url"`
    Name        string `json:"name"`
    ProvidedBy  string `json:"provided_by"`
    Stability   string `json:"stability"`
    State       string `json:"state"`
}

type Listener struct {
    Interface string `json:"interface"`
    Node      string `json:"node"`
    Port      int    `json:"port"`
    Protocol  string `json:"protocol"`
    Purpose   string `json:"purpose"`
}

type VersionInfo struct {
    ErlangVersion   string `json:"erlang_version"`
    RabbitmqName    string `json:"rabbitmq_name"`
    RabbitmqVersion string `json:"rabbitmq_version"`
}

func parseJSON(data string) *ClusterStatus {
    var status ClusterStatus
    err := json.Unmarshal([]byte(data), &status)
    if err != nil {
        log.Fatal(err)
    }
    return &status
}

func main() {
    jsonData := `{"alarms":[],"cluster_name":"rabbit@pam-rabbitmq","disk_nodes":["rabbit@pam-rabbitmq"],"feature_flags":[{"desc":"Count unroutable publishes to be dropped in stats","doc_url":"","name":"drop_unroutable_metric","provided_by":"rabbitmq_management_agent","stability":"stable","state":"enabled"}],"listeners":{"rabbit@pam-rabbitmq":[{"interface":"[::]","node":"rabbit@pam-rabbitmq","port":15692,"protocol":"http/prometheus","purpose":"Prometheus exporter API over HTTP"}]},"maintenance_status":{"rabbit@pam-rabbitmq":"not under maintenance"},"partitions":{},"ram_nodes":[],"running_nodes":["rabbit@pam-rabbitmq"],"versions":{"rabbit@pam-rabbitmq":{"erlang_version":"24.1.7","rabbitmq_name":"RabbitMQ","rabbitmq_version":"3.8.26"}}}`
    status := parseJSON(jsonData)
    fmt.Printf("Cluster Name: %s
", status.ClusterName)
    fmt.Printf("Running Nodes: %v
", status.RunningNodes)
    for _, flag := range status.FeatureFlags {
        fmt.Printf("Feature: %s, State: %s
", flag.Name, flag.State)
    }
}

Code Execution and Output

The program creates a JSON string identical to the command output, parses it into a ClusterStatus instance, and prints the cluster name, running nodes, and each feature flag with its state. Running the program confirms that the JSON structure is correctly mapped to Go types.

By following this example, developers can learn how to handle RabbitMQ monitoring data in Go, which is useful when building middleware, APIs, or other systems that need to exchange structured status information.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

monitoringGoRabbitMQjson-parsing
Ops Development & AI Practice
Written by

Ops Development & AI Practice

DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.