newrelic / go-agent Goto Github PK
View Code? Open in Web Editor NEWNew Relic Go Agent
License: Apache License 2.0
New Relic Go Agent
License: Apache License 2.0
In local development mode, in CI testing, etc we don't want to send metrics to New Relic. There is not an obvious way to disable the agent on startup. If you don't create an application, the instrumentation blows up all over the place with nil pointer errors. If you don't provide a license it returns an error from NewApplication()
. If you provide an invalid license it still tries to talk to New Relic. So, I've put together some stubs that implement the Application
and Transaction
interfaces, but this is fairly ugly and subject to breakage. Is there an obvious way to do this now that I'm missing?
When configuring ErrorCollector.Enabled = false one expects errors not to be reported to APM view ("Error Analytics" and "Errors" under EVENTS).
Despite this configuration errors still arrive.
Please see Pull request #15
If you have installed the goimports plugin with gosublime for sublime text, the plugin automatically manages import statements. Since the go-agent name is different from the newrelic package name called inside main or init, the goimports plugin immediately wipes the import statement from the file on save. See discussion with the go team: golang/go#17576
Per bradfitz:
goimports will respect any of these options:
package newrelic in github.com/newrelic/go-agent/newrelic
package agent in github.com/newrelic/go-agent
package goagent in github.com/newrelic/go-agent (after #17546 at least)
If my app makes 2 requests e.g. http://example.com/api/first
and http://example.com/api/second
then the metrics for both APIs are clubbed together as metrics for 1 external segment named http://example.com
. For Java and Rails apps using NewRelic it actually shows up as two separate external segments.
I was going through the code and observed that this field might be being left blank and I think this might be the cause. Can someone confirm if this is correct? If not, can someone please help me figure out why this might be happening? I'd be happy to send a pull request to fix this issue.
Edit: Forgot to mention, I'm instrumenting external segment calls as it's described here
I have an API and some times I get these errors in the NewRelic Dashboard:
/tmp/tmp.Z4mrDnatAl/.go/src/bitbucket.org/luizacorp/moc-pricing-arquimedes/vendor/github.com/newrelic/go-agent/internal_txn.go (go-agent.(*txn).WriteHeader:201)
<autogenerated> (go-agent.wrapCFHR.WriteHeader:500)
/tmp/tmp.Z4mrDnatAl/.go/src/bitbucket.org/luizacorp/moc-pricing-arquimedes/prices.go (main.fetchPricesData:47)
/tmp/cache/go1.8/go/src/net/http/server.go (http.HandlerFunc.ServeHTTP:1942)
/tmp/tmp.Z4mrDnatAl/.go/src/bitbucket.org/luizacorp/moc-pricing-arquimedes/vendor/github.com/newrelic/go-agent/instrumentation.go (go-agent.WrapHandle.func1:30)
/tmp/cache/go1.8/go/src/net/http/server.go (http.HandlerFunc.ServeHTTP:1942)
/tmp/tmp.Z4mrDnatAl/.go/src/bitbucket.org/luizacorp/moc-pricing-arquimedes/vendor/github.com/newrelic/go-agent/instrumentation.go (go-agent.WrapHandleFunc.func1:38)
/tmp/cache/go1.8/go/src/net/http/server.go (http.HandlerFunc.ServeHTTP:1942)
/tmp/tmp.Z4mrDnatAl/.go/src/bitbucket.org/luizacorp/moc-pricing-arquimedes/vendor/github.com/gorilla/mux/mux.go (mux.(*Router).ServeHTTP:114)
/tmp/cache/go1.8/go/src/net/http/server.go (http.serverHandler.ServeHTTP:2568)
/tmp/cache/go1.8/go/src/net/http/server.go (http.(*conn).serve:1825)
/tmp/cache/go1.8/go/src/runtime/asm_amd64.s (runtime.goexit:2197)
I see that my file prices.go
is in the trace and this is the block where the problem happens.
I have used Delve to debug my code and I get the same error every time I run it!
if err != nil {
response := Response{Message: err.Error(), Code: 500}
w.WriteHeader(500)
json.NewEncoder(w).Encode(response)
return
}
When json
is reached it goes to http.ServeHTTP()
and then to newrelic.WrapHandle()
and then I get the following error message:
Unable to open '<autogenerated>': File not found (/<autogenerated>).
Any ideas?
Do you guys have a plan to support gin-go?
Or, do you have any idea can make it possible to allow me to build one by myself?
Any plans to add beego framework support.
beego.me is their site. Similar to Spring, so the interest
I'm trying to create a Segment in some piece of my code, but it doesn't appear on NewRelic.
I followed the documentation, I implemented all the exemples, but it doesn't works.
All the other things its ok (Transactions, Errors, Web External).
Somebody has some problem with that?
Have some particularity to do this?
Hi guys, how are you?
So, I'm trying using new relic agent with gin and I'm using your nrgin adapter but something wrong are happing.
The http status code is always empty when I just send an empty response.
Why do you don't set the http status code when WriteHeader
is called ?
Look this code:
func (w *replacementResponseWriter) WriteHeader(code int) {
w.code = code
w.ResponseWriter.WriteHeader(code)
}
So if I wanna an empty response body with some status code new relic doesn't will save the status code because gin just call WriteHeader
:
Code: https://github.com/gin-gonic/gin/blob/master/context.go
Line: 730
// Status sets the HTTP response code.
func (c *Context) Status(code int) {
c.writermem.WriteHeader(code)
}
What we can do about it ?
while using newrelic.Transaction
as http.ResponseWriter
, the status code errors are shown in newrelic Error Analytics and Errors, how could we skip specific status codes?
I'm concerned about this because this error rate affects the Appdex Score, and can't have alerts on Appdex Low or specific to status codes.
Hello! Any future plans for adding module support?
I have two params in my URL. When I am wrapping that API call then it is showing url with differnet params.
example:
My url - /v1/dr/{pramas1}/ds/{pramas2}
Actual request
/v1/dr/1/ds/2
/v1/dr/3/ds/4
/v1/dr/4/ds/3
/v1/dr/5/ds/6
/v1/dr/7/ds/8
On new relic dashboard it is showing something like this:
/v1/dr//ds/2
/v1/dr//ds/4
/v1/dr//ds/3
/v1/dr//ds/6
/v1/dr/*/ds/8
Can someone tell how to fix this issue. I am using go-agent
The trace of a request show the endpoint, user-agent, etc.. but, don't show the query string the user made, how can i enable this? Do i need to generate custom events?
The license for the agent appears to indicate that you may only use the code in conjunction with your services:
You may install, execute, and distribute these files and their contents only in conjunction with your direct use of New Relic’s services.
This makes sense for other agents but does not make sense for the Go agent, and appears overly restrictive.
You cannot simply remove the Go agent from an application, because Go code requires that you instrument the code all over the place by hand. This means the code as it stands can only be executed, even internally, as long as you have an valid subscription. It appears that you would be in violation of your license without removing all the calls to the agent code from your application in at least the following scenarios:
You instrumented an application with New Relic's Go agent and want to open source it. You can't run an instrumented application internally and provide it publicly as open source: they would have to be two different code bases or a patch set to add instrumentation. Also, for example, you cannot instrument any off the shelf AGPL-licensed application with the Go agent and run it in production.
You instrumented an application with the Go agent and your subscription lapses. Even if you can no longer benefit from New Relic's services, you would be in violation of the license without removing all the code from your application that calls the agent.
These are strong disincentives to using the Go agent. My belief from reading this license is that your intent is to prevent your own code from being used to compete with you either by helping a competitor or by supporting an open clone. That makes a lot of sense. Unfortunately the next line of the license is even more restrictive:
These files and their contents shall not be used in conjunction with any other
product or software, including but not limited to those that may compete with
any New Relic product, feature, or software.
This is so broadly worded that it appears to actually prevent using the agent!
Can we get a legal review of this license? As it stands, as a long time, loyal New Relic customer we can't use the Go agent.
I have problems with new API. In version 0.6.1 this work.
I need pass txn with context in other functions.
newrelic.wrap this private struct and not have StartSegmentNow
txn := App.StartTransaction("task 1:", nil, nil)
ctx := context.WithValue(context.Background(), "txn", txn)
datafrom_redis := getFromList("test", ctx)
func getFromList(name string,ctx context.Context){
content := ctx.Value("txn")
txn := content.(newrelic.Transaction)
defer newrelic.DatastoreSegment{
StartTime: newrelic.StartSegmentNow(txn),
Product: newrelic.DatastoreRedis,
Collection: "my_table",
Operation: "select",
}.End()
}
panic: interface conversion: newrelic.wrap is not newrelic.Transaction: missing method StartSegmentNow
golang is a great microservice language, and there would be immense value in supporting Cross Application Tracing in that context, even if it means manually extracting/adding the X-NewRelic-*
headers to http requests.
Hi All!
We have a question for you about versioning!
As we add new features, we have been adding new methods to the Application
and Transaction
interface types. For example, in the latest release we introduced an Transaction.Application
method. We have not been increasing the major version number when these interfaces change. Although there is no formal specification about what constitutes a breaking change, many view new interface methods to be breaking since other implementations of these interfaces need the new methods. In light of Go Module support, we are thinking more about this problem and when we should increase the major version number. Possible paths forward:
Keep introducing new methods to the Application
and Transaction
types and increment the major version number. Using modules, lots of major versions could be painful.
Avoid introducing new methods by implementing new functionality as functions. eg. Transaction.Application()
method could have been newrelic.GetApplication(txn Transaction)
. This has the downside that auto-complete is less useful and it's harder to see what you can do with an Application
or a Transaction
.
Make a big breaking change release where we turn the Application
and Transaction
types into structs with pointer receiver methods. This has the downside that people who are passing around the transaction around their functions would need to change all their parameters from txn newrelic.Transaction
to txn *newrelic.Transaction
.
Keep adding methods to the Transaction
and Application
interfaces as minor version changes.
The pain caused by adding new methods could be minimized by introducing StubTransaction
and StubApplication
structs which consumers could embed into their own Transaction
and Application
implementations.
What do you think?
I'm developing a server using gorilla websocket
Can I monitor websocket by using this newrelic library?
It would be very useful if a couple of stats could be tracked and fetched from the agent pkg.
The main one I am interested in at the moment is bandwidth usage.
newrelic.ExternalSegment
with support for nameWe would like to be able to enter the name in the newrelic.ExternalSegment
to solve the problem of calls to APIGateway
/Router
.
In MicroServices
the APIGateway
is widely used to centralize calls to others API, hence, external calls are centralized at the APIGateway
.
This makes analyzing different paths to the same host difficult from newrelic's main dashboard.
This could be easily solved if the newrelic.ExternalSegment
supported a name.
As shown in the drawing, the newrelic.ExternalSegment
only registers the call to the host api_gateway
even though it is the same host, I would like to register the calls differently, calls to api_gateway/service_01
a segment and calls toapi_gateway/service_02
other segment.
The implementation could follow the following pattern: If the name of newrelic.ExternalSegment
is entered it registers this name, if it is not informed it registers the Host (current behavior), in this way it would not change the behavior of the applications that already use it.
This would be a great evolution, for the applications we build here on @mercadolibre.
Can I follow through with this implementation? Is this change feasible?
app name come as Example App from the sample examples and not as My Go Application on the new relic. update the doc ?
After upgrading our QA environment to Go 1.8 (rc2), we lost insight into New Relic metrics.
Running tests on master (commit 7d12ae2) with Go 1.7 is successful (❯ go17 test ./...
).
However, tests are failing when running with Go 1.8 (rc2).
❯ go version
go version go1.8rc2 darwin/amd64
❯ go test ./...
--- FAIL: TestCopyConfigReferenceFieldsPresent (0.00s)
internal_config_test.go:119: [{"pid":123,"language":"go","agent_version":"0.2.2","host":"my-hostname","settings":{"AppName":"my appname","Attributes":{"Enabled":true,"Exclude":["2"],"Include":["1"]},"CustomInsightsEvents":{"Enabled":true},"DatastoreTracer":{"DatabaseNameReporting":{"Enabled":true},"InstanceReporting":{"Enabled":true},"QueryParameters":{"Enabled":true},"SlowQuery":{"Enabled":true,"Threshold":10000000}},"Enabled":true,"ErrorCollector":{"Attributes":{"Enabled":true,"Exclude":["6"],"Include":["5"]},"CaptureEvents":true,"Enabled":true,"IgnoreStatusCodes":[404,405]},"HighSecurity":false,"HostDisplayName":"","Labels":{"zip":"zap"},"Logger":"*logger.logFile","RuntimeSampler":{"Enabled":true},"TransactionEvents":{"Attributes":{"Enabled":true,"Exclude":["4"],"Include":["3"]},"Enabled":true},"TransactionTracer":{"Attributes":{"Enabled":true,"Exclude":["8"],"Include":["7"]},"Enabled":true,"SegmentThreshold":2000000,"StackTraceThreshold":500000000,"Threshold":{"Duration":500000000,"IsApdexFailing":true}},"Transport":"*http.Transport","UseTLS":true,"Utilization":{"BillingHostname":"","DetectAWS":true,"DetectDocker":true,"LogicalProcessors":0,"TotalRAMMIB":0}},"app_name":["my appname"],"high_security":false,"labels":[{"label_type":"zip","label_value":"zap"}],"environment":[["runtime.Compiler","comp"],["runtime.GOARCH","arch"],["runtime.GOOS","goos"],["runtime.Version","vers"],["runtime.NumCPU",8]],"identifier":"my appname","utilization":{"metadata_version":2,"logical_processors":16,"total_ram_mib":1024,"hostname":"my-hostname"}}]
--- FAIL: TestCopyConfigReferenceFieldsAbsent (0.00s)
internal_config_test.go:208: [{"pid":123,"language":"go","agent_version":"0.2.2","host":"my-hostname","settings":{"AppName":"my appname","Attributes":{"Enabled":true,"Exclude":null,"Include":null},"CustomInsightsEvents":{"Enabled":true},"DatastoreTracer":{"DatabaseNameReporting":{"Enabled":true},"InstanceReporting":{"Enabled":true},"QueryParameters":{"Enabled":true},"SlowQuery":{"Enabled":true,"Threshold":10000000}},"Enabled":true,"ErrorCollector":{"Attributes":{"Enabled":true,"Exclude":null,"Include":null},"CaptureEvents":true,"Enabled":true,"IgnoreStatusCodes":null},"HighSecurity":false,"HostDisplayName":"","Labels":null,"Logger":null,"RuntimeSampler":{"Enabled":true},"TransactionEvents":{"Attributes":{"Enabled":true,"Exclude":null,"Include":null},"Enabled":true},"TransactionTracer":{"Attributes":{"Enabled":true,"Exclude":null,"Include":null},"Enabled":true,"SegmentThreshold":2000000,"StackTraceThreshold":500000000,"Threshold":{"Duration":500000000,"IsApdexFailing":true}},"Transport":null,"UseTLS":true,"Utilization":{"BillingHostname":"","DetectAWS":true,"DetectDocker":true,"LogicalProcessors":0,"TotalRAMMIB":0}},"app_name":["my appname"],"high_security":false,"environment":[["runtime.Compiler","comp"],["runtime.GOARCH","arch"],["runtime.GOOS","goos"],["runtime.Version","vers"],["runtime.NumCPU",8]],"identifier":"my appname","utilization":{"metadata_version":2,"logical_processors":16,"total_ram_mib":1024,"hostname":"my-hostname"}}]
FAIL
FAIL github.com/newrelic/go-agent 0.037s
? github.com/newrelic/go-agent/examples/server [no test files]
? github.com/newrelic/go-agent/examples/short-lived-process [no test files]
ok github.com/newrelic/go-agent/internal 0.042s
? github.com/newrelic/go-agent/internal/crossagent [no test files]
ok github.com/newrelic/go-agent/internal/jsonx 0.012s
? github.com/newrelic/go-agent/internal/logger [no test files]
ok github.com/newrelic/go-agent/internal/sysinfo 0.030s
? github.com/newrelic/go-agent/internal/tools/rules [no test files]
? github.com/newrelic/go-agent/internal/tools/utilization [no test files]
ok github.com/newrelic/go-agent/internal/utilization 0.319s
Go 1.8 (rc2) announcement: https://groups.google.com/forum/#!topic/golang-announce/iI13Nx0BP2E
Hey!
I cannot find it inside any documentation for this library, I find only attributes but it's only for Transacations
Thank
Is it possible to create segments without having the Transaction variable?
We want to monitor different areas of the code but if we need to have the Transaction variable, we need to modify a lot our code and start sending the variable through a lot of functions to have it where is needed.
Is there any way to solve this issue?
I am using gokit, and want to monitor multiple routers, as i am creating multiple routers in different transport.go file.
I want to achieve like this or let me know the alternative way.
For instance: nrgorilla.InstrumentRoutes(r, r1, r2, app)
; where r, r1 ... are mux routers.
Is it possible to add RecordCustomEvent and RecordCustomMetric to the Transaction interface?
We pass transaction throughout a lot of our code. When we want to record custom events or metrics, we also need to thread the Application type through the code too. It definitely adds a lot of verbosity to our code, and again, these are passed deep into our code.
If the internal transaction type is already carrying around the necessary app data, it might be easy to add these methods to the transaction type.
It seems like "External Services" does not use the URL provided if Request is not set:
Simplified usage:
func BenchExternal(ctx context.Context, host string, f func()) {
tx := newRelicTx(ctx)
defer newrelic.ExternalSegment{
StartTime: newrelic.StartSegmentNow(tx),
URL: host,
}.End()
f()
I know this isn't the recommended way of doing external segments, but when using API packages that is commonly what we have available. The URL field states:
// If you do not have access to the request, this URL field should be
// used to indicate the endpoint.
URL string
In New Relic these all show up as "External service: unknown" when using "abc.def.com" for instance. Are there special requirements we need to fulfill for this field to be transferred?
I ran into an unusual issue today when adding nrgorilla
to a project.
cannot use r (type *"github.com/myorg/myrepo/vendor/github.com/gorilla/mux".Router) as
type *"github.com/gorilla/mux".Router in argument to nrgorilla.InstrumentRoutes
Where I work, we use gvt to vendor code. It didn't vendor the _integrations
code at all, likely due to the underscore prefix that tools tend to ignore. I'm guessing that it was intentional on your part to use the underscore prefix so users don't need to get/vendor every package and dependency in that folder.
The rather strange error above is because Go was reaching outside of the vendor folder for nrgorilla while go-agent itself was vendored. That resulted in several type errors such as the one above.
There are a few possible solutions I can think of:
_integrations
and have everything work nicely. The reason is that dep looks at the import graph, so it can determine whether it needs to vendor the dependencies of nrgorilla based on whether or not it's used.Hi All,
For the next agent release, we are considering a new Transaction method called SetWebRequest
. This method allow consumers to provide request information without having an *http.Request
, or without having the request at the beginning of the Transaction. We're thinking it could look something like this:
type Transaction interface {
// ... other methods
// SetWebRequest adds request attributes and marks the transaction as a
// web transaction.
SetWebRequest(Request) error
}
// Request provides request information to Transaction.SetWebRequest.
type Request interface {
Header() http.Header
URL() *url.URL
Method() string
Transport() TransportType
}
What do you think?
It would be nice to allow consumers to provide a *http.Request
to SetWebRequest
. Possible ways of making this happen:
We could change the Transaction.SetWebRequest
parameter to an interface{}
(which could be either a Request
or a *http.Request
). Unfortunately, this would lose strong type safety.
We could have a func NewRequest(*http.Request) Request
helper function do the necessary transformation. This would look something like this:
txn.SetWebRequest(newrelic.NewRequest(req))
What would be a better name for the NewRequest
helper?
Or we could have two Transaction methods: one which takes a Request
and another which takes a *http.Request
.
We could change the Transaction.SetWebRequest
parameter to an *http.Request
, and ask consumers to convert their requests into *http.Request
format. Is it easier to convert into a *http.Request
, or to satisfy the Request
interface? The Request
interface makes it explicit which fields we will access, which is nice.
This will satisfy: #19
In using this new-relic agent, I am only able to use an http.X type to classify a request as an http or web request - however, due not using the standard net/http library I am only able to track my transactions as "background" requests - which is alright however does not accurately reflect what the data is actually doing.
As an example if I use a framework such as fasthttp where it is essentially io.writer and io.reader - I am unable to create a web transaction with the current agent - although I may have all the data needed to send a web transaction.
We really want to be able to deploy the Browser agent from Golang backends like one can do with all the other backend languages. Is this being worked on?
We currently have to create Browser apps manually, and ship some janky JS to determine which Browser appId to use, and use that instead of the hardcoded appId that comes in the snippet. So when updating the Browser agent, we not only have to re-copy-paste it, we have to go back and modify part of it again.
To make this work without having several copies of the snippet in our repo, we actually have a separate webpack entry that gets compiled and inlined into a script tag in the <head>
... it looks like this:
// `import` automatically enables strict mode, which breaks the New Relic Browser snippet
const { SERVER_TYPE, SERVER_TYPES } = require('constants/Environment')
const NR_APP_IDS = {
[SERVER_TYPES.PRODUCTION]: '......36',
[SERVER_TYPES.LOCAL]: '......18',
[SERVER_TYPES.TEST]: '......22',
[SERVER_TYPES.EA]: '......98'
}
const NR_APP_ID = NR_APP_IDS[SERVER_TYPE]
/* eslint-disable */
// New Relic Browser snippet
// <most of Browser agent loader omitted for brevity>
;NREUM.info = {/* ... */ applicationID: NR_APP_ID }
That's pretty sad, but it's going to get worse when the app in question needs to have separate deployments for individual enterprise customers -- we'll need to manually create each browser app and add each Browser appId to the list.
I'm curious about the challenges behind making this work. Is there anything we could manually do to achieve an at least half-baked version of first-class Browser support?
Any information or help would be appreciated!
Your license here says:
or be used for the purpose of research, reverse engineering
or developing such competitive products, features, or software.
It appears that it should say
or be used for the purpose of researching, reverse engineering
or developing such competitive products, features, or software.
The sentence as is does not make sense. The sentence as corrected is clear, parallel, and makes sense in the context of the license.
The documentation for NewRoundTripper
and Transaction
explicitly say that they should only be used in a single goroutine, but looking at the code it doesn't appear that there would be any problems using them from multiple goroutines. We have a web application that may spawn multiple goroutines to make requests to other services from a single source request. Ideally, we would not have to create a transaction per subrequest. Is the documentation correct, or are Transaction and NewRoundTripper
safe for use from multiple goroutines?
Currently the nrlogrus.StandardLogger()
imports "github.com/Sirupsen/logrus"
. This causes errors inside of existing projects that are already using logrus as described in in their README.
Seeing weird case-sensitive problems? It's in the past been possible to import Logrus as both upper- and lower-case. Due to the Go package environment, this caused issues in the community and we needed a standard. Some environments experienced problems with the upper-case variant, so the lower-case was decided. Everything using logrus will need to use the lower-case: github.com/sirupsen/logrus. Any package that isn't, should be changed.
There is an open pull request for this already #52
Its not calling newrelic.WrapHandle
function if Path variable is present in API endpoint. while WrapHandle function being invoked when there is no path variable.
http.Handle(newrelic.WrapHandle(app, "/api/v1/search/{entityType}", searchHandler)
Could you please fix this or let me the know the quick solution? Its urgent.
../../../../go/pkg/mod/github.com/newrelic/[email protected]+incompatible/_integrations/nrmysql/nrmysql.go:79:20: undefined: mysql.NewConnector
I've started implementing the new MySQL client added in v2.8.0
and immediately get a compiler error.
It's worth noting here that I am using jmoiron/sqlx, but I am not sure if that's related. I tried with the regular standard library and got the same issue.
I did see the documentation about using nrmysql.NewConnector
instead of mysql.NewConnector
but I'm not calling that method anywhere in my code. The only place I can find a call to that method in my code, and all of its' dependencies, is in this library.
30:// If your code is using mysql.NewConnector, simply use nrmysql.NewConnector
76:// NewConnector can be used in place of mysql.NewConnector to get an
79: connector, err := mysql.NewConnector(cfg)
This happened after only changing the client, nothing else. Here is that diff:
diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go
index 3b721f2..f33762f 100644
--- a/cmd/serve/serve.go
+++ b/cmd/serve/serve.go
@@ -17,6 +17,9 @@ import (
"github.com/spf13/cobra"
"go.uber.org/zap"
+
+ // new relic mysql client
+ _ "github.com/newrelic/go-agent/_integrations/nrmysql"
)
// Command contains the serve command implementation
@@ -38,7 +41,7 @@ func Command() *cobra.Command {
conf := database.Config(spec, nil)
- db, err := sqlx.Connect("mysql", conf.FormatDSN())
+ db, err := sqlx.Connect("nrmysql", conf.FormatDSN())
if err != nil {
ctxlog.Fatal(err.Error())
}
go version go1.12.6 darwin/amd64
After a recent deploy we observed that throughput was fluctuating greatly:
We could not find any reasonable explanation for this, and was unable to see this fluctuation on the load balancer. A re-deploy "fixed" the issue. Since we have recently upgraded to this client we took a look at it.
It seems like the harvester is relying on a time.Ticker to start a harvest. However, this does not guarantee a steady time increment between each harvest. Looking at the logs for the problematic deploy, we observed that it was started "14:38:59".
So my best explanation is that due to timing issues a harvest would have a start time of ":59..." and some harvests a start time of ":00". It seems that when New Relic receives a harvest they are accumulated into 1 minute buckets. So if the last harvest started at :00 and another at :59 they are grouped together.
I would propose to use a constant 1 minute increment for harvests instead of relying on a ticker value that can fluctuate, so the "minute" always is the same.
Thank you for your great client. It is a huge upgrade.
Getting this while building with go1.8
package <redacted>
imports github.com/newrelic/go-agent
imports github.com/newrelic/go-agent/internal: use of internal package not allowed
package <redacted>
imports github.com/newrelic/go-agent
imports github.com/newrelic/go-agent/internal/logger: use of internal package not allowed
package <redacted>
imports github.com/newrelic/go-agent
imports github.com/newrelic/go-agent/internal/utilization: use of internal package not allowed
Our Go http service is using New Relic to log transactions for each request, and I'm curious what controls the "Message" field in the error log? Currently it appears to be filled in with the text version of the http status code (ie Internal Server Error for any 500), for example:
We have custom errors in our code, and I would like to set that Message field to the text of the actual error. Is that possible? I tried using SetName, but that change the URL, not the Message.
Note that if I start my own Transaction and call NoticeError, then the error text appears as the Message field. This is the behavior I want to mimic for http transactions.
The current implementation of NewRoundTripper
makes it difficult to use when a http.client
is passed into a service via dependency injection. Instead of the implementation being transaction specific, it should check the http.request
context for a rewrelic.Transaction
.
Consider this example of a very basic API client:
type APIClient struct {
instance string
client *http.Client
}
func NewAPIClient(instance string, httpClient *http.Client) *APIClient {
return &APIClient{
instance: instance,
httpClient: httpClient,
}
}
func (c *APIClient) DoSomeAction(ctx context.Context) (res *http.Response, err error) {
r := http.NewRequest("GET", c.instance, nil)
r = r.WithContext(ctx)
return c.client.Do(r)
}
It would be very helpful if the injected http.Client
could be configured to automatically instrument requests. The desired usage would look something like:
client := new(http.Client)
client.Transport = rewrelic.NewRoundTripper(c.Transport)
apiClient := NewAPIClient("http://example.com", client)
Proposed NewRoundTripper Implementation:
func NewRoundTripper(original http.RoundTripper) http.RoundTripper {
return roundTripperFunc(func(request *http.Request) (*http.Response, error) {
txn := FromContext(request.Context())
segment := StartExternalSegment(txn, request)
if nil == original {
original = http.DefaultTransport
}
response, err := original.RoundTrip(request)
segment.Response = response
segment.End()
return response, err
})
}
I'm fairly new to using the go agent so if there is an existing way to achieve what I've outlined, I'd be happy to hear about it. If not I'd be happy to submit a pull request after some discussion.
Currently the go-agent is not configurable (other than the license key) via environment variables, where most other NR agents are fully configurable via environment variables.
My biggest need right now is to set the hostname/display name so my go applications appear in infrastructure.
See my NR support ticket 263915.
Are you guys planning to support it for windows?
Right now I can't even separate out handlers_windows/linux, because go get doesn't work.
Can you at least add implementation functions for windows so that it would complain on run time, but would still compile.
I'm using Negroni in my project. How would you integrate NewRelic with it? Sorry if this is not a real issue but I just couldn't get it to work.
Can we make it possible to set SegmentStartTime to a specific time in the past.
Use case:
currently in one of my projects I use an ORM called Upperio. In this ORM and most they give you the ability to add a query logger. This query logger has in it all the information I would need to pass to newrelic.DatastoreSegment
(context, start time, end time, query string). This is problematic when trying to implement this logger with newrelic as right now it seems you guys require me to run
// defer newrelic.DatastoreSegment{
// StartTime: newrelic.StartSegmentNow(txn),
// Product: newrelic.DatastoreMySQL,
// Collection: "my_table",
// Operation: "SELECT",
// }.End()
before any query call. I would like to not flood my code base with these calls if they can be in one place.
Do you guys have any suggestions on how i should do this? Does the newrelic client already provide me with a way to generate a StartTime that i'm just missing?
When I think about assessing the behavior of goroutines, memory, cpu, etc. in the context of go, native golang profiling is the first thing I think about. There are many open source tools that use the raw data that is produced by the golang profile and turn it into meaningful graph (uber's go-touch comes to mind).
I briefly browsed through the code and it doesn't look like New Relic is utilizing native golang profiling but instead implementing their own (If I am wrong please correct me). However, if I am right, could you provide context as to why New Relic is solving the problem in the way as opposed to using the native tools the language provides?
I have a support ticket open (353273) but perhaps there is a faster answer here? :D I am wondering what actual number is the limit in order to hit that 413? Also what is it based on, the total request body size compressed?
Would be great to be able to see how much time my app is spending in Redis, same as I do in my Python app.
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/proc_cpuinfo/2pack_2core_2logical.txt
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/proc_cpuinfo/4pack_4core_4logical.txt
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/proc_cpuinfo/8pack_8core_8logical.txt
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/proc_cpuinfo/Xpack_Xcore_2logical.txt
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/no_end_header.html
github.com/newrelic/go-agent/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiple_tags.html
it's only in these files in the repo
Hi,
I've built a system around context.Context to pass down the newrelic Transaction to various call stacks, but now the problem I'm facing is that I hit a code block which spawns a goroutine, and that goroutine inherits the context. I want to create a new newrelic.Transaction for it, but all I have is the Transaction, not the app. So far I've got through this without creating my own tracing wrapper package, but now I'll have to in order to store the global Application instance (which is currently created in my 'main' and so not importable anywhere).
It would be nice if it were possible to access the equivalent of Application.StartTransaction from another Transaction object, specifically for the case of goroutines. I'm just going to have to disable tracing for this goroutine in the meantime.
I thought you might be interested in this API design feedback, but it's not critical for me.
In ruby APM we have thread profiler. Work in 5 step
Now I have idea for golang.
Standard golang profile dump include.
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.