Skip to content

Commit 3e29a18

Browse files
authored
Merge pull request #48 from newrelic/unique-keys
Unique keys
2 parents 30b9b37 + 89be532 commit 3e29a18

32 files changed

+3519
-129
lines changed

CHANGELOG.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ 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+
## 4.0.0 - 2019-04-22
9+
### Changed
10+
- Prefixed namespace to provide better uniqueness
11+
- Cluster name and environment are now identity attributes
12+
### Added
13+
- Added a reporting endpoint to the entities
14+
15+
816
## 3.0.0 - 2019-02-04
917
### Changed
1018
- Updated definition version
@@ -65,4 +73,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6573

6674
## 0.1.0 - 2018-08-28
6775
### Added
68-
- Initial version: Includes Metrics and Inventory data
76+
- Initial version: Includes Metrics and Inventory data

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 = "3.0.0"
31+
integrationVersion = "4.0.0"
3232
)
3333

3434
var (

src/metrics.go

+24-26
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func populateMetrics(i *integration.Integration, client Client, env string) {
3939
}
4040
}
4141

42-
func populateNodesMetrics(i *integration.Integration, client Client, clusterName *string) error {
42+
func populateNodesMetrics(i *integration.Integration, client Client, clusterName string) error {
4343
log.Info("Collecting node metrics")
4444
nodeResponse := new(NodeResponse)
4545
err := client.Request(nodeStatsEndpoint, &nodeResponse)
@@ -52,35 +52,31 @@ func populateNodesMetrics(i *integration.Integration, client Client, clusterName
5252
}
5353

5454
// setNodesMetricsResponse calls setMetricsResponse for each node in the response
55-
func setNodesMetricsResponse(integration *integration.Integration, resp *NodeResponse, clusterName *string) {
55+
func setNodesMetricsResponse(integration *integration.Integration, resp *NodeResponse, clusterName string) {
5656
for node := range resp.Nodes {
57-
err := setMetricsResponse(integration, resp.Nodes[node], *resp.Nodes[node].Name, "node", clusterName)
57+
err := setMetricsResponse(integration, resp.Nodes[node], *resp.Nodes[node].Name, "es-node", clusterName)
5858
if err != nil {
5959
log.Error("There was an error setting metrics for node metrics on %s: %v", node, err)
6060
}
6161
}
6262
}
6363

64-
func populateClusterMetrics(i *integration.Integration, client Client, env string) (*string, error) {
64+
func populateClusterMetrics(i *integration.Integration, client Client, env string) (string, error) {
6565
log.Info("Collecting cluster metrics.")
6666
clusterResponse := new(ClusterResponse)
6767
err := client.Request(clusterEndpoint, &clusterResponse)
6868
if err != nil {
69-
return nil, err
69+
return "", err
7070
}
7171

7272
if clusterResponse.Name == nil {
73-
return nil, errors.New("cannot set metric response, missing cluster name")
74-
}
75-
76-
if env != "" {
77-
*clusterResponse.Name = *clusterResponse.Name + ":" + env
73+
return "", errors.New("cannot set metric response, missing cluster name")
7874
}
7975

80-
return clusterResponse.Name, setMetricsResponse(i, clusterResponse, *clusterResponse.Name, "cluster", nil)
76+
return *clusterResponse.Name, setMetricsResponse(i, clusterResponse, *clusterResponse.Name, "es-cluster", *clusterResponse.Name)
8177
}
8278

83-
func populateCommonMetrics(i *integration.Integration, client Client, clusterName *string) (*CommonMetrics, error) {
79+
func populateCommonMetrics(i *integration.Integration, client Client, clusterName string) (*CommonMetrics, error) {
8480
log.Info("Collecting common metrics.")
8581
commonResponse := new(CommonMetrics)
8682
err := client.Request(commonStatsEndpoint, &commonResponse)
@@ -89,13 +85,13 @@ func populateCommonMetrics(i *integration.Integration, client Client, clusterNam
8985
}
9086

9187
if args.CollectPrimaries {
92-
err = setMetricsResponse(i, commonResponse.All, "commonMetrics", "common", clusterName)
88+
err = setMetricsResponse(i, commonResponse.All, "commonMetrics", "es-common", clusterName)
9389
}
9490

9591
return commonResponse, err
9692
}
9793

98-
func populateIndicesMetrics(i *integration.Integration, client Client, commonStats *CommonMetrics, clusterName *string) error {
94+
func populateIndicesMetrics(i *integration.Integration, client Client, commonStats *CommonMetrics, clusterName string) error {
9995
log.Info("Collecting indices metrics")
10096
indicesStats := make([]*IndexStats, 0)
10197
err := client.Request(indicesStatsEndpoint, &indicesStats)
@@ -122,7 +118,7 @@ func buildRegex() (indexRegex *regexp.Regexp, err error) {
122118
return indexRegex, nil
123119
}
124120

125-
func setIndicesStatsMetricsResponse(integration *integration.Integration, indexResponse []*IndexStats, commonResponse *CommonMetrics, clusterName *string, indexRegex *regexp.Regexp) {
121+
func setIndicesStatsMetricsResponse(integration *integration.Integration, indexResponse []*IndexStats, commonResponse *CommonMetrics, clusterName string, indexRegex *regexp.Regexp) {
126122
type indexStatsObject struct {
127123
name string
128124
stats *IndexStats
@@ -164,7 +160,7 @@ func setIndicesStatsMetricsResponse(integration *integration.Integration, indexR
164160
}
165161

166162
for _, index := range indicesToCollect {
167-
if err := setMetricsResponse(integration, index.stats, index.name, "index", clusterName); err != nil {
163+
if err := setMetricsResponse(integration, index.stats, index.name, "es-index", clusterName); err != nil {
168164
log.Error("There was an error setting metrics for indices metrics: %v", err)
169165
}
170166
}
@@ -180,27 +176,29 @@ func getIndexFromCommon(indexName string, indexList map[string]*Index) (*Index,
180176

181177
// setMetricsResponse creates an entity and a metric set for the
182178
// type of response and calls MarshalMetrics using that response
183-
func setMetricsResponse(integration *integration.Integration, resp interface{}, name string, namespace string, clusterName *string) error {
184-
entity, err := integration.Entity(name, namespace)
179+
func setMetricsResponse(i *integration.Integration, resp interface{}, name string, namespace string, clusterName string) error {
180+
entityIDAttrs := []integration.IDAttribute{
181+
{Key: "clusterName", Value: clusterName},
182+
}
183+
if args.ClusterEnvironment != "" {
184+
entityIDAttrs = append(entityIDAttrs, integration.IDAttribute{Key: "env", Value: args.ClusterEnvironment})
185+
}
186+
187+
entity, err := i.EntityReportedVia(fmt.Sprintf("%s:%d", args.Hostname, args.Port), name, namespace, entityIDAttrs...)
185188
if err != nil {
186189
return err
187190
}
188191

189-
idAttributes := []metric.Attribute{
192+
msAttributes := []metric.Attribute{
190193
{Key: "displayName", Value: entity.Metadata.Name},
191194
{Key: "entityName", Value: entity.Metadata.Namespace + ":" + entity.Metadata.Name},
192195
}
193196

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...)
197+
metricSet := entity.NewMetricSet(getSampleName(namespace), msAttributes...)
200198

201199
return metricSet.MarshalMetrics(resp)
202200
}
203201

204202
func getSampleName(entityType string) string {
205-
return fmt.Sprintf("Elasticsearch%sSample", strings.Title(entityType))
203+
return fmt.Sprintf("Elasticsearch%sSample", strings.Title(strings.TrimPrefix(entityType, "es-")))
206204
}

src/metrics_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestPopulateNodesMetrics(t *testing.T) {
5858
client := createNewTestClient()
5959
client.init("nodeStatsMetricsResult.json", nodeStatsEndpoint, t)
6060

61-
populateNodesMetrics(i, client, &testClusterName)
61+
populateNodesMetrics(i, client, testClusterName)
6262

6363
sourceFile := filepath.Join("testdata", "nodeStatsMetricsResult.json")
6464
goldenFile, actualContents := createGoldenFile(i, sourceFile)
@@ -78,7 +78,7 @@ func TestPopulateNodesMetrics_Error(t *testing.T) {
7878
mockClient.ReturnRequestError = true
7979

8080
i := getTestingIntegration(t)
81-
err := populateNodesMetrics(i, mockClient, &testClusterName)
81+
err := populateNodesMetrics(i, mockClient, testClusterName)
8282
assert.Error(t, err, "should be an error")
8383
}
8484

@@ -99,7 +99,7 @@ func TestPopulateClusterMetrics(t *testing.T) {
9999
}
100100

101101
actualLength := len(i.Entities[0].Metrics[0].Metrics)
102-
expectedLength := 11
102+
expectedLength := 12
103103

104104
assert.Equal(t, expectedContents, actualContents)
105105
assert.Equal(t, expectedLength, actualLength)
@@ -121,7 +121,7 @@ func TestPopulateCommonMetrics(t *testing.T) {
121121
args.CollectPrimaries = true
122122
client.init("commonMetricsResult.json", commonStatsEndpoint, t)
123123

124-
populateCommonMetrics(i, client, &testClusterName)
124+
populateCommonMetrics(i, client, testClusterName)
125125

126126
sourceFile := filepath.Join("testdata", "commonMetricsResult.json")
127127
goldenFile, actualContents := createGoldenFile(i, sourceFile)
@@ -143,7 +143,7 @@ func TestPopulateCommonMetrics_Error(t *testing.T) {
143143
mockClient.ReturnRequestError = true
144144

145145
i := getTestingIntegration(t)
146-
_, err := populateCommonMetrics(i, mockClient, &testClusterName)
146+
_, err := populateCommonMetrics(i, mockClient, testClusterName)
147147
assert.Error(t, err, "should be an error")
148148
}
149149

@@ -156,7 +156,7 @@ func TestPopulateIndicesMetrics(t *testing.T) {
156156
commonData, _ := ioutil.ReadFile(filepath.Join("testdata", "indicesMetricsResult_Common.json"))
157157
json.Unmarshal(commonData, commonStruct)
158158

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

161161
sourceFile := filepath.Join("testdata", "indicesMetricsResult.json")
162162
goldenFile, actualContents := createGoldenFile(i, sourceFile)
@@ -202,7 +202,7 @@ func TestSetIndicesStatsMetricsResponse_TooManyIndices(t *testing.T) {
202202
},
203203
}
204204

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

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

215215
i := getTestingIntegration(t)
216-
err := populateIndicesMetrics(i, mockClient, new(CommonMetrics), &testClusterName)
216+
err := populateIndicesMetrics(i, mockClient, new(CommonMetrics), testClusterName)
217217
assert.Error(t, err, "should be an error")
218218
}
219219

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

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

232232
actualLength := len(i.Entities)
233233
expectedLength := 1
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"Test","protocol_version":"2","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{"config/process/id":{"value":0},"config/process/mlockall":{"value":false}},"events":[]}]}
1+
{"name":"Test","protocol_version":"3","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{"config/process/id":{"value":0},"config/process/mlockall":{"value":false}},"events":[]}]}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"cluster.dataNodes":3,"cluster.nodes":6,"cluster.status":"yellow","displayName":"es6-dev-cluster","entityName":"cluster:es6-dev-cluster","event_type":"ElasticsearchClusterSample","shards.active":30,"shards.initializing":0,"shards.primaryActive":10,"shards.relocating":0,"shards.unassigned":7}
1+
{"cluster.dataNodes":3,"cluster.nodes":6,"cluster.status":"yellow","displayName":"es6-dev-cluster","entityName":"es-cluster:es6-dev-cluster","event_type":"ElasticsearchClusterSample","reportingEndpoint":":0","shards.active":30,"shards.initializing":0,"shards.primaryActive":10,"shards.relocating":0,"shards.unassigned":7}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
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}
1+
{"displayName":"commonMetrics","entityName":"es-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,"reportingEndpoint":":0"}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"Test","protocol_version":"2","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{"config/network.host":{"value":"0.0.0.0"},"config/path.data":{"value":"/var/lib/elasticsearch"},"config/path.logs":{"value":"/var/log/elasticsearch"}},"events":[]}]}
1+
{"name":"Test","protocol_version":"3","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{"config/network.host":{"value":"0.0.0.0"},"config/path.data":{"value":"/var/lib/elasticsearch"},"config/path.logs":{"value":"/var/log/elasticsearch"}},"events":[]}]}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"Test","protocol_version":"2","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{},"events":[]}]}
1+
{"name":"Test","protocol_version":"3","integration_version":"0.0.1","data":[{"metrics":[],"inventory":{},"events":[]}]}

0 commit comments

Comments
 (0)