Skip to content

Commit aceb1d6

Browse files
authored
[receiver/rabbitmq] Enhancement/rabbitmq Added node level metrics (#38473)
<!-- Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description This PR enhances the RabbitMQ receiver by adding support for node-level metrics collection. It introduces the ability to individually enable the collection of specific node metrics, including: - `rabbitmq.node.disk_free`: Free disk space on the node. - `rabbitmq.node.fd_used`: The number of file descriptors used on the node. - `rabbitmq.node.mem_limit`: The memory limit on the node. - `rabbitmq.node.mem_used`: The memory used on the node. This enhancement improves the flexibility and granularity of the metrics collection for RabbitMQ monitoring by allowing users to configure which node metrics to collect. <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes #36925 <!--Describe what testing was performed and which tests were added.--> #### Testing - Added unit tests to validate the enabling and disabling of individual node metrics. - Verified that each node metric is correctly collected when enabled and omitted when disabled. - Ran integration tests to ensure the receiver operates without issues in various configurations. <!--Describe the documentation added.--> #### Documentation - Updated the `README.md` with details about the new per-metric configuration options for enabling node-level metrics. - Added examples in `config.yaml` to demonstrate how to configure the receiver with the new metrics. - Included explanations for node-specific metrics in `metadata.yaml`.
1 parent 20d03fa commit aceb1d6

File tree

16 files changed

+725
-9
lines changed

16 files changed

+725
-9
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
5+
component: rabbitmqreceiver
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: "Enhance the RabbitMQ receiver to collect and report node-level metrics (`rabbitmq.node.disk_free`, `rabbitmq.node.fd_used`, `rabbitmq.node.mem_limit`, and `rabbitmq.node.mem_used`). This provides additional observability into the state and resource usage of RabbitMQ nodes."
9+
10+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
11+
issues: [36925]

receiver/rabbitmqreceiver/README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,19 @@ receivers:
4545
username: otelu
4646
password: ${env:RABBITMQ_PASSWORD}
4747
collection_interval: 10s
48+
metrics: # Enable node metrics by explicitly setting them to true
49+
rabbitmq.node.disk_free:
50+
enabled: true
51+
rabbitmq.node.fd_used:
52+
enabled: true
53+
rabbitmq.node.mem_limit:
54+
enabled: true
55+
rabbitmq.node.mem_used:
56+
enabled: true
4857
```
4958
5059
The full list of settings exposed for this receiver are documented in [config.go](./config.go) with detailed sample configurations in [testdata/config.yaml](./testdata/config.yaml). TLS config is documented further under the [opentelemetry collector's configtls package](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md).
5160
5261
## Metrics
5362
54-
Details about the metrics produced by this receiver can be found in [metadata.yaml](./metadata.yaml)
55-
63+
Details about the metrics produced by this receiver can be found in [metadata.yaml](./metadata.yaml)

receiver/rabbitmqreceiver/client.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@ import (
1616
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/rabbitmqreceiver/internal/models"
1717
)
1818

19-
// queuePath is the path to queues endpoint
20-
const queuePath = "/api/queues"
19+
const (
20+
// queuePath is the endpoint for RabbitMQ queues.
21+
queuePath = "/api/queues"
22+
23+
// nodePath is the endpoint for RabbitMQ nodes.
24+
nodePath = "/api/nodes"
25+
)
2126

2227
type client interface {
2328
// GetQueues calls "/api/queues" endpoint to get list of queues for the target node
2429
GetQueues(ctx context.Context) ([]*models.Queue, error)
30+
// GetNodes calls "/api/nodes" endpoint to get list of nodes for the target node
31+
GetNodes(ctx context.Context) ([]*models.Node, error)
2532
}
2633

2734
var _ client = (*rabbitmqClient)(nil)
@@ -66,6 +73,17 @@ func (c *rabbitmqClient) GetQueues(ctx context.Context) ([]*models.Queue, error)
6673
return queues, nil
6774
}
6875

76+
func (c *rabbitmqClient) GetNodes(ctx context.Context) ([]*models.Node, error) {
77+
var nodes []*models.Node
78+
79+
if err := c.get(ctx, nodePath, &nodes); err != nil {
80+
c.logger.Debug("Failed to retrieve nodes", zap.Error(err))
81+
return nil, err
82+
}
83+
84+
return nodes, nil
85+
}
86+
6987
func (c *rabbitmqClient) get(ctx context.Context, path string, respObj any) error {
7088
// Construct endpoint and create request
7189
url := c.hostEndpoint + path

receiver/rabbitmqreceiver/client_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
const (
2828
queuesAPIResponseFile = "get_queues_response.json"
29+
nodesAPIResponseFile = "get_nodes_response.json"
2930
)
3031

3132
func TestNewClient(t *testing.T) {
@@ -161,6 +162,75 @@ func TestGetQueuesDetails(t *testing.T) {
161162
}
162163
}
163164

165+
func TestGetNodesDetails(t *testing.T) {
166+
testCases := []struct {
167+
desc string
168+
testFunc func(*testing.T)
169+
}{
170+
{
171+
desc: "Non-200 Response for GetNodes",
172+
testFunc: func(t *testing.T) {
173+
// Setup test server
174+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
175+
w.WriteHeader(http.StatusForbidden)
176+
}))
177+
defer ts.Close()
178+
179+
tc := createTestClient(t, ts.URL)
180+
181+
nodes, err := tc.GetNodes(context.Background())
182+
require.Nil(t, nodes)
183+
require.EqualError(t, err, "non 200 code returned 403")
184+
},
185+
},
186+
{
187+
desc: "Bad payload returned for GetNodes",
188+
testFunc: func(t *testing.T) {
189+
// Setup test server
190+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
191+
_, err := w.Write([]byte("{invalid-json}"))
192+
assert.NoError(t, err)
193+
}))
194+
defer ts.Close()
195+
196+
tc := createTestClient(t, ts.URL)
197+
198+
nodes, err := tc.GetNodes(context.Background())
199+
require.Nil(t, nodes)
200+
require.ErrorContains(t, err, "failed to decode response payload")
201+
},
202+
},
203+
{
204+
desc: "Successful GetNodes call",
205+
testFunc: func(t *testing.T) {
206+
data := loadAPIResponseData(t, nodesAPIResponseFile)
207+
208+
// Setup test server
209+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
210+
_, err := w.Write(data)
211+
assert.NoError(t, err)
212+
}))
213+
defer ts.Close()
214+
215+
tc := createTestClient(t, ts.URL)
216+
217+
// Load the valid data into a struct to compare
218+
var expected []*models.Node
219+
err := json.Unmarshal(data, &expected)
220+
require.NoError(t, err)
221+
222+
nodes, err := tc.GetNodes(context.Background())
223+
require.NoError(t, err)
224+
require.Equal(t, expected, nodes)
225+
},
226+
},
227+
}
228+
229+
for _, tc := range testCases {
230+
t.Run(tc.desc, tc.testFunc)
231+
}
232+
}
233+
164234
func createTestClient(t *testing.T, baseEndpoint string) client {
165235
t.Helper()
166236
cfg := createDefaultConfig().(*Config)

receiver/rabbitmqreceiver/documentation.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,48 @@ The number of messages published to a queue.
6666
| ---- | ----------- | ---------- | ----------------------- | --------- |
6767
| {messages} | Sum | Int | Cumulative | true |
6868
69+
## Optional Metrics
70+
71+
The following metrics are not emitted by default. Each of them can be enabled by applying the following configuration:
72+
73+
```yaml
74+
metrics:
75+
<metric_name>:
76+
enabled: true
77+
```
78+
79+
### rabbitmq.node.disk_free
80+
81+
Free disk space on the node.
82+
83+
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
84+
| ---- | ----------- | ---------- | ----------------------- | --------- |
85+
| {bytes} | Sum | Int | Cumulative | false |
86+
87+
### rabbitmq.node.fd_used
88+
89+
The number of file descriptors used on the node.
90+
91+
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
92+
| ---- | ----------- | ---------- | ----------------------- | --------- |
93+
| {fd} | Sum | Int | Cumulative | false |
94+
95+
### rabbitmq.node.mem_limit
96+
97+
The memory limit on the node.
98+
99+
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
100+
| ---- | ----------- | ---------- | ----------------------- | --------- |
101+
| {bytes} | Sum | Int | Cumulative | false |
102+
103+
### rabbitmq.node.mem_used
104+
105+
The memory used on the node.
106+
107+
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
108+
| ---- | ----------- | ---------- | ----------------------- | --------- |
109+
| {bytes} | Sum | Int | Cumulative | false |
110+
69111
## Resource Attributes
70112
71113
| Name | Description | Values | Enabled |

receiver/rabbitmqreceiver/internal/metadata/generated_config.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/rabbitmqreceiver/internal/metadata/generated_config_test.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)