GithubHelp home page GithubHelp logo

go-agent's Introduction

Community Plus header

New Relic Go Agent GoDoc Go Report Card codecov

The New Relic Go Agent allows you to monitor your Go applications with New Relic. It helps you track transactions, outbound requests, database calls, and other parts of your Go application's behavior and provides a running overview of garbage collection, goroutine activity, and memory use.

Go is a compiled language, and doesn’t use a virtual machine. This means that setting up New Relic for your Golang app requires you to use our Go agent API and manually add New Relic methods to your source code. Our API provides exceptional flexibility and control over what gets instrumented.

Installation

Compatibility and Requirements

For the latest version of the agent, Go 1.18+ is required.

Linux, OS X, and Windows (Vista, Server 2008 and later) are supported.

Installing and using the Go agent

To install the agent, follow the instructions in our GETTING_STARTED document or our GUIDE.

We recommend instrumenting your Go code to get the maximum benefits from the New Relic Go agent. But we make it easy to get great data in couple of ways:

  • Even without adding instrumentation, just importing the agent and creating an application will provide useful runtime information about your number of goroutines, garbage collection statistics, and memory and CPU usage.
  • You can use our many INTEGRATION packages for out-of-the box support for many popular Go web frameworks and libraries. We continue to add integration packages based on your feedback. You can weigh in on potential integrations by opening an Issue here in our New Relic Go agent GitHub project.

Upgrading

If you have already been using version 2.X of the agent and are upgrading to version 3.0, see our MIGRATION guide for details.

Getting Started

v3/examples/server/main.go is an example that will appear as "Example App" in your New Relic applications list. To run it:

env NEW_RELIC_LICENSE_KEY=__YOUR_NEW_RELIC_LICENSE_KEY__LICENSE__ \
    go run v3/examples/server/main.go

Some endpoints exposed are http://localhost:8000/ and http://localhost:8000/notice_error

Usage

Integration Packages

The following integration packages extend the base newrelic package to support the following frameworks and libraries. Frameworks and databases which don't have an integration package may still be instrumented using the newrelic package primitives.

Service Frameworks

Project Integration Package
gin-gonic/gin v3/integrations/nrgin Instrument inbound requests through the Gin framework
gorilla/mux v3/integrations/nrgorilla Instrument inbound requests through the Gorilla framework
google.golang.org/grpc v3/integrations/nrgrpc Instrument gRPC servers and clients
labstack/echo v3/integrations/nrecho-v3 Instrument inbound requests through version 3 of the Echo framework
labstack/echo v3/integrations/nrecho-v4 Instrument inbound requests through version 4 of the Echo framework
julienschmidt/httprouter v3/integrations/nrhttprouter Instrument inbound requests through the HttpRouter framework
micro/go-micro v3/integrations/nrmicro Instrument servers, clients, publishers, and subscribers through the Micro framework

Datastores

More information about instrumenting databases without an integration package using newrelic package primitives can be found here.

Project Integration Package
lib/pq v3/integrations/nrpq Instrument PostgreSQL driver (pq driver for database/sql)
jackc/pgx v3/integrations/nrpgx Instrument PostgreSQL driver (pgx driver for database/sql)
jackc/pgx/v5 v3/integrations/nrpgx5 Instrument PostgreSQL driver (pgx/v5 driver for database/sql)
go-mssqldb v3/integrations/nrmssql Instrument MS SQL driver
go-sql-driver/mysql v3/integrations/nrmysql Instrument MySQL driver
elastic/go-elasticsearch v3/integrations/nrelasticsearch-v7 Instrument Elasticsearch datastore calls
database/sql Use a supported database driver or builtin instrumentation Instrument database calls with SQL
jmoiron/sqlx Use a supported database driver or builtin instrumentation Instrument database calls with SQLx
go-redis/redis v3/integrations/nrredis-v7 Instrument Redis 7 calls
go-redis/redis v3/integrations/nrredis-v8 Instrument Redis 8 calls
redis/go-redis v3/integrations/nrredis-v9 Instrument Redis 9 calls
mattn/go-sqlite3 v3/integrations/nrsqlite3 Instrument SQLite driver
snowflakedb/gosnowflake v3/integrations/nrsnowflake Instrument Snowflake driver
mongodb/mongo-go-driver v3/integrations/nrmongo Instrument MongoDB calls

AI

Project Integration Package
sashabaranov/go-openai v3/integrations/nropenai Send AI Monitoring Events with OpenAI
aws/aws-sdk-go-v2/tree/main/service/bedrockruntime v3/integrations/nrawsbedrock Send AI Monitoring Events with AWS Bedrock

Agent Logging

Project Integration Package
sirupsen/logrus v3/integrations/nrlogrus Send agent log messages to Logrus
mgutz/logxi v3/integrations/nrlogxi Send agent log messages to Logxi
uber-go/zap v3/integrations/nrzap Send agent log messages to Zap

Logs in Context

Project Integration Package
sirupsen/logrus v3/integrations/logcontext-v2/nrlogrus Send data collected from Logrus log messages to New Relic
log v3/integrations/logcontext-v2/logWriter Send data collected from the standard library logger log messages to New Relic
rs/zerolog v3/integrations/logcontext-v2/zerologWriter Send data collected from zerolog log messages to New Relic

AWS

Project Integration Package
aws/aws-sdk-go v3/integrations/nrawssdk-v1 Instrument outbound calls made using Go AWS SDK
aws/aws-sdk-go-v2 v3/integrations/nrawssdk-v2 Instrument outbound calls made using Go AWS SDK v2
aws/aws-lambda-go v3/integrations/nrlambda Instrument AWS Lambda applications

GraphQL

Project Integration Package
graph-gophers/graphql-go v3/integrations/nrgraphgophers Instrument inbound requests using graph-gophers/graphql-go
graphql-go/graphql v3/integrations/nrgraphqlgo Instrument inbound requests using graphql-go/graphql

Misc

Project Integration Package
pkg/errors v3/integrations/nrpkgerrors Wrap pkg/errors errors to improve stack traces and error class information
openzipkin/b3-propagation v3/integrations/nrb3 Add B3 headers to outgoing requests
nats-io/nats.go v3/integrations/nrnats Instrument publishers and subscribers using the NATS client
nats-io/stan.go v3/integrations/nrstan Instrument publishers and subscribers using the NATS streaming client

These integration packages must be imported along with the newrelic package, as shown in this nrgin example.

Alternatives

If you are already using another open source solution to gather telemetry data, you may find it easier to use one of our open source exporters to send this data to New Relic:

Support

Should you need assistance with New Relic products, you are in good hands with several support channels.

If the issue has been confirmed as a bug or is a Feature request, please file a Github issue.

Privacy

At New Relic we take your privacy and the security of your information seriously, and are committed to protecting your information. We must emphasize the importance of not sharing personal data in public forums, and ask all users to scrub logs and diagnostic information for sensitive information, whether personal, proprietary, or otherwise.

We define "Personal Data" as any information relating to an identified or identifiable individual, including, for example, your name, phone number, post code or zip code, Device ID, IP address and email address.

For more information, review New Relic’s General Data Privacy Notice.

Contribute

We encourage your contributions to improve the Go Agent! Keep in mind when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. You only have to sign the CLA one time per project.

If you have any questions, or to execute our corporate CLA, required if your contribution is on behalf of a company, please drop us an email at [email protected].

A note about vulnerabilities

As noted in our security policy, New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.

If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through HackerOne.

If you would like to contribute to this project, please review these guidelines.

To all contributors, we thank you! Without your contribution, this project would not be what it is today. We also host a community project page dedicated to the Go Agent.

License

The New Relic Go agent is licensed under the Apache 2.0 License.

go-agent's People

Contributors

aayush-ap avatar abeltay avatar adomaskizogian avatar alrs avatar astormnewrelic avatar bearcherian avatar benweint avatar dependabot[bot] avatar egon12 avatar gunturaf avatar iamemilio avatar ignacio83 avatar jodeev avatar julien4218 avatar lawngnome avatar melissaklein24 avatar mhmtszr avatar mirackara avatar newrelic-eheinlein avatar nr-swilloughby avatar nrlhj avatar pliu-newrelic avatar profawxhawk avatar purple4reina avatar richvanderwal avatar rvanderwal-newrelic avatar sdbedi avatar taufik-rama avatar tylerconlee avatar vinhnewrelic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-agent's Issues

Native Golang Profiling

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?

External Services shows up as "unknown" if no Request is provided.

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?

Error on newrelic.WrapHandle() about a missing ‘<autogenerated>’ file

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?

beego framework support

Any plans to add beego framework support.
beego.me is their site. Similar to Spring, so the interest

Segments doesn't appear on NewRelic

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?

Support windows build

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.

Agent needs configurability via environment variables

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.

Using _integrations can result in type errors

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:

  • Document this so that it's less confusing for others in the future.
  • Having several separate repos for extensions would provide an immediate solution that wouldn't require the underscore prefix, but it may be a bit annoying to maintain.
  • In the longer term, once people adopt dep, you will be able to remove the underscore prefix from _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.

Major licensing issues

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.

_integrations/nrlogrus/nrlogrus.go should import lowercase "github.com/sirupsen/logrus"

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

use of internal package not allowed

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

Versioning Question

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?

413 payload too large

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?

Add custom name support to `newrelic.ExternalSegment`

newrelic.ExternalSegment with support for name

We 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.

Captura de Tela 2019-05-03 às 10 13 40

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.

How it is registered
Captura de Tela 2019-05-04 às 09 29 08

How I would like register
Captura de Tela 2019-05-04 às 09 33 06


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?

Segments without transaction variable

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?

How to skip specific errors while logging to newrelic

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.

Different API calls to the same host are clubbed together in external segments

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

Empty httpResponseStatus with Nrgin

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.

Captura de Tela 2019-05-31 às 18 42 30

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 ?

Grammatical error in license

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.

Metric Grouping Issue

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

Show all parameters of a request on trace

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?

How to handle multiple mux routers

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.

undefined: mysql.NewConnector

../../../../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

Cross Application Tracing Support

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.

NewRoundTripper for injected http clients

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.

proposal: Add profiling with net/http/pprof

In ruby APM we have thread profiler. Work in 5 step

  1. Clink on button start profiler on one if instance
  2. Newrelic send command to server(newrelic magic)
  3. On server newrelic agent collect samples.
  4. Send samples to newrelic server(newrelic magic)
  5. Analysing and visualisation in newrelic APM UI(newrelic magic)
    This very cool fetcher in ruby.

Now I have idea for golang.

  1. Clink on button start profiler on one if instance
  2. Newrelic send command to server(same newrelic magic)
  3. On server newrelic agent collect samples with net/http/pprof
  4. Send samples to newrelic server(standard golang profile dump)
  5. Analysing and visualisation in newrelic APM UI(same newrelic magic).

Standard golang profile dump include.

  1. cpuprofile
  2. memoryprofile
  3. map of calls functions
  4. Other good staff about runtime application.

How to run without providing a license key?

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?

proposal: Add Transaction.RecordCustomEvent

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.

dpc update for the app name

app name come as Example App from the sample examples and not as My Go Application on the new relic. update the doc ?

concurrency and transactions

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?

Test failures in Go 1.8

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

Due to name and package name clashing, go-agent is unusable with goimports

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)

Gin Framework support

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?

Get Transaction from Transaction?

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.

Feature request: Agent stats

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.

[NFR] Custom metric support

Hey!

I cannot find it inside any documentation for this library, I find only attributes but it's only for Transacations

Thank

Timing issue makes multiple harvests go to same "minute".

After a recent deploy we observed that throughput was fluctuating greatly:

throughput

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.

Set SegmentStartTime to time in the past

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?

Best way to identify an http transaction error

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:

image

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.

txn pass with context not work

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

Feedback Wanted: Proposed API: SetWebRequest

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:

  1. 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.

  2. 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?

  1. Or we could have two Transaction methods: one which takes a Request and another which takes a *http.Request.

  2. 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

Support alternate method of having a "web" transaction

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.

could you please remove windows carriage returns in these files

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

New Relic Browser support

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!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.