Skip to content

Commit 9aa3ae3

Browse files
camdencheekCorbin Phelps
authored and
Corbin Phelps
committed
Adde clustername to all entities. Changed node names to be their ip/hostname (#37)
1 parent c8eafb0 commit 9aa3ae3

12 files changed

+63
-44
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## 1.2.0 - 2018-11-29
9+
### Added
10+
- Cluster name is now attached to allow entities within a cluster
11+
### Changed
12+
- Nodes are no identified by hostname/IP rather than ID
13+
814
## 1.1.0 - 2018-11-28
915
### Added
1016
- ClusterEnvironment argument to help further identify clusters

src/elasticsearch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type argumentList struct {
2828

2929
const (
3030
integrationName = "com.newrelic.elasticsearch"
31-
integrationVersion = "1.1.0"
31+
integrationVersion = "1.2.0"
3232
)
3333

3434
var (

src/inventory.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func parseLocalNode(nodeStats *LocalNodeResponse) (string, *LocalNode, error) {
5353
nodes := nodeStats.Nodes
5454
if len(nodes) == 1 {
5555
for k := range nodes {
56-
return k, nodes[k], nil
56+
return *nodes[k].Host, nodes[k], nil
5757
}
5858
}
5959
return "", nil, errors.New("could not identify local node")

src/inventory_definition.go

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type LocalNodeResponse struct {
77

88
// LocalNode is the node API object
99
type LocalNode struct {
10+
Host *string `json:"host"`
1011
Process *LocalNodeProcess `json:"process"`
1112
Ingest *LocalNodeIngest `json:"ingest"`
1213
Plugins []*LocalNodeAddon `json:"plugins"`

src/inventory_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func TestGetLocalNode(t *testing.T) {
155155
fakeClient.On("Request", "/_nodes/_local").Return(mockedReturnVal, nil).Once()
156156

157157
resultName, resultStats, _ := getLocalNode(&fakeClient)
158-
assert.Equal(t, "z9ZPp87vT92qG1cRVRIcMQ", resultName)
158+
assert.Equal(t, "10.77.10.83", resultName)
159159

160160
actualString, _ := json.Marshal(resultStats)
161161
writeGoldenFile(t, goldenPath, actualString)

src/metrics.go

+35-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"errors"
45
"fmt"
56
"regexp"
67
"strings"
@@ -14,70 +15,72 @@ const indexLimit = 500
1415

1516
// populateMetrics wrapper to call each of the individual populate functions
1617
func populateMetrics(i *integration.Integration, client Client, env string) {
17-
err := populateNodesMetrics(i, client)
18+
clusterName, err := populateClusterMetrics(i, client, env)
1819
if err != nil {
19-
log.Error("There was an error populating metrics for nodes: %v", err)
20+
log.Error("There was an error populating metrics for clusters: %v", err)
2021
}
2122

22-
err = populateClusterMetrics(i, client, env)
23+
err = populateNodesMetrics(i, client, clusterName)
2324
if err != nil {
24-
log.Error("There was an error populating metrics for clusters: %v", err)
25+
log.Error("There was an error populating metrics for nodes: %v", err)
2526
}
2627

2728
// we want to use the response from common to populate some index-specific stats.
28-
commonResponse, err := populateCommonMetrics(i, client)
29+
commonResponse, err := populateCommonMetrics(i, client, clusterName)
2930
if err != nil {
3031
log.Error("There was an error populating metrics for common metrics: %v", err)
3132
}
3233

3334
if args.CollectIndices {
34-
err = populateIndicesMetrics(i, client, commonResponse)
35+
err = populateIndicesMetrics(i, client, commonResponse, clusterName)
3536
if err != nil {
3637
log.Error("There was an error populating metrics for indices: %v", err)
3738
}
3839
}
3940
}
4041

41-
func populateNodesMetrics(i *integration.Integration, client Client) error {
42+
func populateNodesMetrics(i *integration.Integration, client Client, clusterName *string) error {
4243
log.Info("Collecting node metrics")
4344
nodeResponse := new(NodeResponse)
4445
err := client.Request(nodeStatsEndpoint, &nodeResponse)
4546
if err != nil {
4647
return err
4748
}
4849

49-
setNodesMetricsResponse(i, nodeResponse)
50+
setNodesMetricsResponse(i, nodeResponse, clusterName)
5051
return nil
5152
}
5253

5354
// setNodesMetricsResponse calls setMetricsResponse for each node in the response
54-
func setNodesMetricsResponse(integration *integration.Integration, resp *NodeResponse) {
55+
func setNodesMetricsResponse(integration *integration.Integration, resp *NodeResponse, clusterName *string) {
5556
for node := range resp.Nodes {
56-
err := setMetricsResponse(integration, resp.Nodes[node], node, "node")
57+
err := setMetricsResponse(integration, resp.Nodes[node], *resp.Nodes[node].Host, "node", clusterName)
5758
if err != nil {
5859
log.Error("There was an error setting metrics for node metrics on %s: %v", node, err)
5960
}
6061
}
6162
}
6263

63-
func populateClusterMetrics(i *integration.Integration, client Client, env string) error {
64+
func populateClusterMetrics(i *integration.Integration, client Client, env string) (*string, error) {
6465
log.Info("Collecting cluster metrics.")
6566
clusterResponse := new(ClusterResponse)
6667
err := client.Request(clusterEndpoint, &clusterResponse)
6768
if err != nil {
68-
return err
69+
return nil, err
6970
}
7071

7172
if clusterResponse.Name == nil {
72-
return fmt.Errorf("cannot set metric response, missing cluster name")
73+
return nil, errors.New("cannot set metric response, missing cluster name")
7374
}
75+
7476
if env != "" {
7577
*clusterResponse.Name = *clusterResponse.Name + ":" + env
7678
}
77-
return setMetricsResponse(i, clusterResponse, *clusterResponse.Name, "cluster")
79+
80+
return clusterResponse.Name, setMetricsResponse(i, clusterResponse, *clusterResponse.Name, "cluster", nil)
7881
}
7982

80-
func populateCommonMetrics(i *integration.Integration, client Client) (*CommonMetrics, error) {
83+
func populateCommonMetrics(i *integration.Integration, client Client, clusterName *string) (*CommonMetrics, error) {
8184
log.Info("Collecting common metrics.")
8285
commonResponse := new(CommonMetrics)
8386
err := client.Request(commonStatsEndpoint, &commonResponse)
@@ -86,13 +89,13 @@ func populateCommonMetrics(i *integration.Integration, client Client) (*CommonMe
8689
}
8790

8891
if args.CollectPrimaries {
89-
err = setMetricsResponse(i, commonResponse.All, "commonMetrics", "common")
92+
err = setMetricsResponse(i, commonResponse.All, "commonMetrics", "common", clusterName)
9093
}
9194

9295
return commonResponse, err
9396
}
9497

95-
func populateIndicesMetrics(i *integration.Integration, client Client, commonStats *CommonMetrics) error {
98+
func populateIndicesMetrics(i *integration.Integration, client Client, commonStats *CommonMetrics, clusterName *string) error {
9699
log.Info("Collecting indices metrics")
97100
indicesStats := make([]*IndexStats, 0)
98101
err := client.Request(indicesStatsEndpoint, &indicesStats)
@@ -105,7 +108,7 @@ func populateIndicesMetrics(i *integration.Integration, client Client, commonSta
105108
return err
106109
}
107110

108-
setIndicesStatsMetricsResponse(i, indicesStats, commonStats, indexRegex)
111+
setIndicesStatsMetricsResponse(i, indicesStats, commonStats, clusterName, indexRegex)
109112
return nil
110113
}
111114

@@ -119,7 +122,7 @@ func buildRegex() (indexRegex *regexp.Regexp, err error) {
119122
return indexRegex, nil
120123
}
121124

122-
func setIndicesStatsMetricsResponse(integration *integration.Integration, indexResponse []*IndexStats, commonResponse *CommonMetrics, indexRegex *regexp.Regexp) {
125+
func setIndicesStatsMetricsResponse(integration *integration.Integration, indexResponse []*IndexStats, commonResponse *CommonMetrics, clusterName *string, indexRegex *regexp.Regexp) {
123126
type indexStatsObject struct {
124127
name string
125128
stats *IndexStats
@@ -161,7 +164,7 @@ func setIndicesStatsMetricsResponse(integration *integration.Integration, indexR
161164
}
162165

163166
for _, index := range indicesToCollect {
164-
if err := setMetricsResponse(integration, index.stats, index.name, "index"); err != nil {
167+
if err := setMetricsResponse(integration, index.stats, index.name, "index", clusterName); err != nil {
165168
log.Error("There was an error setting metrics for indices metrics: %v", err)
166169
}
167170
}
@@ -177,16 +180,23 @@ func getIndexFromCommon(indexName string, indexList map[string]*Index) (*Index,
177180

178181
// setMetricsResponse creates an entity and a metric set for the
179182
// type of response and calls MarshalMetrics using that response
180-
func setMetricsResponse(integration *integration.Integration, resp interface{}, name string, namespace string) error {
183+
func setMetricsResponse(integration *integration.Integration, resp interface{}, name string, namespace string, clusterName *string) error {
181184
entity, err := integration.Entity(name, namespace)
182185
if err != nil {
183186
return err
184187
}
185188

186-
metricSet := entity.NewMetricSet(getSampleName(namespace),
187-
metric.Attribute{Key: "displayName", Value: entity.Metadata.Name},
188-
metric.Attribute{Key: "entityName", Value: entity.Metadata.Namespace + ":" + entity.Metadata.Name},
189-
)
189+
idAttributes := []metric.Attribute{
190+
{Key: "displayName", Value: entity.Metadata.Name},
191+
{Key: "entityName", Value: entity.Metadata.Namespace + ":" + entity.Metadata.Name},
192+
}
193+
194+
// If clusterName is non empty apply it
195+
if clusterName != nil {
196+
idAttributes = append(idAttributes, metric.Attribute{Key: "clusterName", Value: *clusterName})
197+
}
198+
199+
metricSet := entity.NewMetricSet(getSampleName(namespace), idAttributes...)
190200

191201
return metricSet.MarshalMetrics(resp)
192202
}

src/metrics_test.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"github.com/stretchr/testify/assert"
1313
)
1414

15+
var testClusterName = "goTestCluster"
16+
1517
type testClient struct {
1618
endpointMapping map[string]string
1719
ReturnRequestError bool
@@ -56,7 +58,7 @@ func TestPopulateNodesMetrics(t *testing.T) {
5658
client := createNewTestClient()
5759
client.init("nodeStatsMetricsResult.json", nodeStatsEndpoint, t)
5860

59-
populateNodesMetrics(i, client)
61+
populateNodesMetrics(i, client, &testClusterName)
6062

6163
sourceFile := filepath.Join("testdata", "nodeStatsMetricsResult.json")
6264
goldenFile, actualContents := createGoldenFile(i, sourceFile)
@@ -76,7 +78,7 @@ func TestPopulateNodesMetrics_Error(t *testing.T) {
7678
mockClient.ReturnRequestError = true
7779

7880
i := getTestingIntegration(t)
79-
err := populateNodesMetrics(i, mockClient)
81+
err := populateNodesMetrics(i, mockClient, &testClusterName)
8082
assert.Error(t, err, "should be an error")
8183
}
8284

@@ -108,7 +110,7 @@ func TestPopulateClusterMetrics_Error(t *testing.T) {
108110
mockClient.ReturnRequestError = true
109111

110112
i := getTestingIntegration(t)
111-
err := populateClusterMetrics(i, mockClient, "")
113+
_, err := populateClusterMetrics(i, mockClient, "")
112114
assert.Error(t, err, "should be an error")
113115
}
114116

@@ -119,7 +121,7 @@ func TestPopulateCommonMetrics(t *testing.T) {
119121
args.CollectPrimaries = true
120122
client.init("commonMetricsResult.json", commonStatsEndpoint, t)
121123

122-
populateCommonMetrics(i, client)
124+
populateCommonMetrics(i, client, &testClusterName)
123125

124126
sourceFile := filepath.Join("testdata", "commonMetricsResult.json")
125127
goldenFile, actualContents := createGoldenFile(i, sourceFile)
@@ -130,7 +132,7 @@ func TestPopulateCommonMetrics(t *testing.T) {
130132
}
131133

132134
actualLength := len(i.Entities[0].Metrics[0].Metrics)
133-
expectedLength := 36
135+
expectedLength := 37
134136

135137
assert.Equal(t, expectedContents, actualContents)
136138
assert.Equal(t, expectedLength, actualLength)
@@ -141,7 +143,7 @@ func TestPopulateCommonMetrics_Error(t *testing.T) {
141143
mockClient.ReturnRequestError = true
142144

143145
i := getTestingIntegration(t)
144-
_, err := populateCommonMetrics(i, mockClient)
146+
_, err := populateCommonMetrics(i, mockClient, &testClusterName)
145147
assert.Error(t, err, "should be an error")
146148
}
147149

@@ -154,15 +156,15 @@ func TestPopulateIndicesMetrics(t *testing.T) {
154156
commonData, _ := ioutil.ReadFile(filepath.Join("testdata", "indicesMetricsResult_Common.json"))
155157
json.Unmarshal(commonData, commonStruct)
156158

157-
populateIndicesMetrics(i, client, commonStruct)
159+
populateIndicesMetrics(i, client, commonStruct, &testClusterName)
158160

159161
sourceFile := filepath.Join("testdata", "indicesMetricsResult.json")
160162
goldenFile, actualContents := createGoldenFile(i, sourceFile)
161163

162164
for j := range i.Entities {
163165
resultStruct := i.Entities[j].Metrics[0].Metrics
164166
actualLength := len(resultStruct)
165-
expectedLength := 10
167+
expectedLength := 11
166168
assert.Equal(t, expectedLength, actualLength)
167169
}
168170

@@ -200,7 +202,7 @@ func TestSetIndicesStatsMetricsResponse_TooManyIndices(t *testing.T) {
200202
},
201203
}
202204

203-
setIndicesStatsMetricsResponse(i, indexResponse, commonResponse, nil)
205+
setIndicesStatsMetricsResponse(i, indexResponse, commonResponse, &testClusterName, nil)
204206

205207
// should not collect any entities since there are more than 100 of them.
206208
assert.Equal(t, 0, len(i.Entities))
@@ -211,7 +213,7 @@ func TestPopulateIndicesMetrics_Error(t *testing.T) {
211213
mockClient.ReturnRequestError = true
212214

213215
i := getTestingIntegration(t)
214-
err := populateIndicesMetrics(i, mockClient, new(CommonMetrics))
216+
err := populateIndicesMetrics(i, mockClient, new(CommonMetrics), &testClusterName)
215217
assert.Error(t, err, "should be an error")
216218
}
217219

@@ -225,7 +227,7 @@ func TestIndicesRegex(t *testing.T) {
225227
commonData, _ := ioutil.ReadFile(filepath.Join("testdata", "indicesMetricsResult_Common.json"))
226228
json.Unmarshal(commonData, commonStruct)
227229

228-
populateIndicesMetrics(i, client, commonStruct)
230+
populateIndicesMetrics(i, client, commonStruct, &testClusterName)
229231

230232
actualLength := len(i.Entities)
231233
expectedLength := 1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"displayName":"commonMetrics","entityName":"common:commonMetrics","event_type":"ElasticsearchCommonSample","primaries.docsDeleted":0,"primaries.docsnumber":2,"primaries.flushTotalTimeInMilliseconds":15,"primaries.flushesTotal":10,"primaries.get.documentsExist":0,"primaries.get.documentsExistInMilliseconds":0,"primaries.get.documentsMissing":0,"primaries.get.documentsMissingInMilliseconds":0,"primaries.get.requests":0,"primaries.get.requestsCurrent":0,"primaries.get.requestsInMilliseconds":0,"primaries.index.docsCurrentlyDeleted":0,"primaries.index.docsCurrentlyDeletedInMilliseconds":0,"primaries.index.docsCurrentlyIndexing":0,"primaries.index.docsCurrentlyIndexingInMilliseconds":67,"primaries.index.docsDeleted":0,"primaries.index.docsTotal":1,"primaries.indexRefreshesTotal":46,"primaries.indexRefreshesTotalInMilliseconds":88,"primaries.merges.current":0,"primaries.merges.docsSegmentsCurrentlyMerged":0,"primaries.merges.docsTotal":0,"primaries.merges.segmentsCurrentlyMergedInBytes":0,"primaries.merges.segmentsTotal":0,"primaries.merges.segmentsTotalInBytes":0,"primaries.merges.segmentsTotalInMilliseconds":0,"primaries.queriesInMilliseconds":0,"primaries.queriesTotal":0,"primaries.queryActive":0,"primaries.queryFetches":0,"primaries.queryFetchesInMilliseconds":0,"primaries.queryFetchesTotal":0,"primaries.sizeInBytes":9364}
1+
{"clusterName":"goTestCluster","displayName":"commonMetrics","entityName":"common:commonMetrics","event_type":"ElasticsearchCommonSample","primaries.docsDeleted":0,"primaries.docsnumber":2,"primaries.flushTotalTimeInMilliseconds":15,"primaries.flushesTotal":10,"primaries.get.documentsExist":0,"primaries.get.documentsExistInMilliseconds":0,"primaries.get.documentsMissing":0,"primaries.get.documentsMissingInMilliseconds":0,"primaries.get.requests":0,"primaries.get.requestsCurrent":0,"primaries.get.requestsInMilliseconds":0,"primaries.index.docsCurrentlyDeleted":0,"primaries.index.docsCurrentlyDeletedInMilliseconds":0,"primaries.index.docsCurrentlyIndexing":0,"primaries.index.docsCurrentlyIndexingInMilliseconds":67,"primaries.index.docsDeleted":0,"primaries.index.docsTotal":1,"primaries.indexRefreshesTotal":46,"primaries.indexRefreshesTotalInMilliseconds":88,"primaries.merges.current":0,"primaries.merges.docsSegmentsCurrentlyMerged":0,"primaries.merges.docsTotal":0,"primaries.merges.segmentsCurrentlyMergedInBytes":0,"primaries.merges.segmentsTotal":0,"primaries.merges.segmentsTotalInBytes":0,"primaries.merges.segmentsTotalInMilliseconds":0,"primaries.queriesInMilliseconds":0,"primaries.queriesTotal":0,"primaries.queryActive":0,"primaries.queryFetches":0,"primaries.queryFetchesInMilliseconds":0,"primaries.queryFetchesTotal":0,"primaries.sizeInBytes":9364}

0 commit comments

Comments
 (0)