newrelic / newrelic-client-go Goto Github PK
View Code? Open in Web Editor NEWNew Relic Client for the Go programming language
Home Page: https://newrelic.github.io/observability-as-code
License: Apache License 2.0
New Relic Client for the Go programming language
Home Page: https://newrelic.github.io/observability-as-code
License: Apache License 2.0
TBD
In order to provider user metrics, we would need a user's permission to track their usage statistics. This is not an uncommon request these days in CLI frameworks.
This would also likely require a Terms and Privacy Policy acceptance as well.
We need a high-level overview of the primary features and responsibilities that the client should incorporate.
Starting point:
paultyng/go-newrelic
dollarshaveclub/new-relic-synthetics-go
Some preliminary questions:
terraform-provider-newrelic
leverages paultyng/go-newrelic
and dollarshaveclub/new-relic-synthetics-go
. If we include a CLI in this project, will we include Terraform features in it?Updating package versions should be automated in some way so that we do not have to remember to update them.
/pkg/*
are automated / required./pkg/*
automate / require change to /newrelic/version.go
/newrelic/version.go
is kept in sync with the git tagWe have permission to use go-newrelic as the base for the client, we need to:
We need to publicly expose the client's error types since they are important to state tracking in terraform-provider-newrelic.
Migrate synthetics.go from dollarshaveclub/new-relic-synthetics-go
to our project. We probably want to break this large file out into domain-specific files.
go-newrelic
since it will likely already exist in this new repo - e.g. GET /alerts_synthetics_conditions
exists in go-newrelic
and in new-relic-synthetics-go
, but we will likely already have migrated the go-newrelic
code.Migrate alert_synthetics_conditions.go from go-newrelic
to our project.
Migrate components.go, component_metrics.go, and component_metric_data.go from go-newrelic
to our project.
Migrate alert_policies.go from go-newrelic
to our project.
Migrate dashboards.go from go-newrelic
to our project.
Migrate applications.go from go-newrelic
to our project.
Add validation for public/exported APIs.
Migrate types.go from go-newrelic
to our project.
Consider whether or not we should put types within their specific domain instead of having all of the types in a single file, which is how go-newrelic
has done it. Something like alert_channels_types.go
and dashboard_types.go
could be a design pattern worth discussing. What advantages/disadvantages would this introduce?
Enable automation of testing, linting, etc via CircleCI.
Feel free to use CircleCI's guide for Go to get things started.
Attempting to add multiple channels to an alert policy does not work. Only
When callingalerts.UpdatePolicyChannels(321, []int{123345, 678899})
with multiple channel IDs only the last channel in the slice of IDs is added to the policy. The client generates a call that looks like the URL below.
Example API call:
PUT https://api.newrelic.com/v2/alerts_policy_channels.json?channel_ids=<id1>&channel_ids=<id2>&policy_id=<policyID>
Our current client implementation doesn't seem to handle the multiple instances of the query param channel_ids
. Instead of create an array of IDs, it only uses the last one in the query string.
Attempting to add multiple channel IDs to an alert policy should ensure all IDs passed to the method are added to the associated policy ID.
Steps to reproduce the behavior:
alerts.UpdatePolicyChannels(policyID, []channelIDs)
with a known existing policy ID and at least 2 known existing channel IDs. Can be set up in an integration test.This is needed to help support the ease of adding multiple channels to an alert policy via the Terraform provider.
Consolidate the current HTTP client implementations from paultyng/go-newrelic
and dollarshaveclub/new-relic-synthetics-go
into a single HTTP abstraction layer in our new project. Thanks for Paul and David, we have a pretty good foundation to build from.
eu
)eu
)go-newrelic
client_test.go as a potential referenceWe might want to avoid using an HTTP client library if possible, but some potential HTTP libraries to use are:
paultyng/go-newrelic
)References:
go-newrelic
HTTP client implementation as a reference (even potentially reuse parts of it)dollarshaveclub/new-relic-synthetics-go
HTTP client implementationInfra API appears to return the data that caused an error and a 400 HTTP response for invalid config of infra_process_running
, which we do not correctly handle.
The newrelic-client-go attempts to unmarshal the JSON into an int, which does not work.
Concise error returned to the caller.
Reported in here on the Terraform provider.
Migrate labels.go from go-newrelic
to our project.
Add support for Alerts Incidents
and the following endpoints:
https://rpm.newrelic.com/api/explore/alerts_incidents/show
https://rpm.newrelic.com/api/explore/alerts_incidents/acknowledge
https://rpm.newrelic.com/api/explore/alerts_incidents/close
Migrate alert_nrql_conditions.go from go-newrelic
to our project.
Placeholder for this issue in the Terraform provider
Migrate key_transactions.go from go-newrelic
to our project.
Migrate alert_infra_conditions.go from go-newrelic
to our project.
Provide a consistent contract for all methods.
func UpdateEntity(entity Entity) (*Entity, error) {}
even if the endpoint this method uses doesn't really return us a response bodyThe client should support the applications metrics and metrics data endpoionts:
Provide the cleanest representation of resource types possible for the project.
types.go
file per packageWe have some test helpers that are available per package, but they since they are repeated per package, we can consolidate into a test helpers package to use in all the packages.
Some examples of these helpers are newMockResponse
and newIntegrationTestClient
that are located in the {basePackage}_test.go
files - i.e. in apm_test.go
.
Currently, some objects around alerts.Condition
and soon to be alerts.MultiLocationSyntheticsCondition
are inconsistent about how they make use of the PolicyID. In both cases, the API object does not contain the PolicyID, but in the case of alerts.Condition
, we create an extra field for PolicyID
and attache the ID of the policy to the object after the call is made, before returning the object to the user.
We should determine which approach we want to take here and make the code consistent.
Support the CRUD operations for Entity Tags as provided by Nerdgraph.
taggingAddTagsToEntity
taggingDeleteTagFromEntity
taggingDeleteTagValuesFromEntity
taggingReplaceTagsOnEntity
Hi,
I have been playing with new relic terraform plugin which is using newrelic-client-go. I noticed that when I was searching for an alert notification channel - depending on environment - sometimes it was found, sometimes not. When I tried to compare the difference between environments - the only one was number of already defined channels. I thought that problem might be with plugin getting just one page of data - but since it is using newrelic-client-go - it should receive all data regardless how many is defined in NewRelic.
Playing with the code - I've noticed that data returned from newrelic-client-go ListChannels method is corrupted - multiple entries were duplicated. I think it is caused by using reference for response (&response) when calling alerts.client.Get - as same object is being reuse - it does not reallocate memory, which cause entries in array overwritten. Call ends up with proper number of elements in alertChannels slice, but with duplicated entries.
I've checked that assigning fresh value for response works as expected. As I'm not a Go expert maybe there is a better solution.
func (alerts *Alerts) ListChannels() ([]*Channel, error) {
response := alertChannelsResponse{}
alertChannels := []*Channel{}
nextURL := "/alerts_channels.json"
for nextURL != "" {
resp, err := alerts.client.Get(nextURL, nil, &response)
if err != nil {
return nil, err
}
alertChannels = append(alertChannels, response.Channels...)
paging := alerts.pager.Parse(resp)
nextURL = paging.Next
response = alertChannelsResponse{}
}
return alertChannels, nil
}
Thanks.
We need to define the layout including but not limited to:
Some useful information can be found in golang-standards/project-layout
Currently, we pass the entire response body to the internal http
client to for page handling. If the responses are particularly large, that is a bunch of data to pass around.
Migrate alert_conditions.go from go-newrelic
to our project.
Migrate alert_policy_channels.go from go-newrelic
to our project.
Migrate plugins.go from go-newrelic
to our project.
AC:
Three Alerts objects have time-like fields, but are represented in two different ways. These should ideally be the same way, my preference is for them all to be plain int
types, discussed below.
Incident has OpenedAt and ClosedAt timestamp fields represented by an int
:
newrelic-client-go/pkg/alerts/alerts_types.go
Lines 86 to 87 in 8eda621
InfrastructureCondition has CreatedAt and UpdatedAt represented by the internal *serialization.EpochTime
(a redeclaration of time.Time
):
newrelic-client-go/pkg/alerts/alerts_types.go
Lines 101 to 113 in 8eda621
Policy has CreatedAt and UpdatedAt represented by the internal *serialization.EpochTime
(a redeclaration of time.Time
):
newrelic-client-go/pkg/alerts/alerts_types.go
Lines 174 to 175 in 8eda621
int
s, possibly with helper functions on the type to translate to time.Time
for other uses like displaying to humans.0
(January 1, 1970)Will comment below on the specific application I'm working on and why I'd prefer int
types, happy to have the conversation in squaring it with other uses of this library.
Infrastructure alert condition thresholds can apparently be set to float values via the New Relic UI. Our Go client should support this as well. The type update would happen here.
The original issue was reported in the terraform-provider-newrelic
project.
Migrate deployments.go from go-newrelic
to our project.
To facilitate better test coverage and ease of writing tests, we need a some helper functions to help create generic mocks.
Migrate alert_channels.go from go-newrelic
to our project.
Decide on a path forward for integrating with the features available in the Nerdgraph API.
Migrate alert_plugins_conditions.go from go-newrelic
to our project.
Add support for the recently GA Multi-location Synthetics Condition type. Documentation: https://rpm.newrelic.com/api/explore/alerts_location_failure_conditions/create
Research if we can migrate the existing synthetics implementation or if we should rewrite.
Rewrite is out of scope, migration would remain in scope.
We need some preliminary feedback from internal developers.
Add a version.go
file for our primary client package to facilitate querying for usage metrics in New Relic.
version.go
file should follow a similar format to this version.goVersion
variable should be applied to the userAgent
header to facilitate querying for usage metrics in New Relic.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.