github.com/newrelic/go-agent@v3.26.0+incompatible/MIGRATION.md (about)

     1  # Migration Guide - 3.0
     2  
     3  This guide is intended to help with upgrading from version 2.x (`"github.com/newrelic/go-agent"`) to version 3.x (`"github.com/newrelic/go-agent/v3/newrelic"`). This information can also be found on
     4  [our documentation website](https://docs.newrelic.com/docs/agents/go-agent/installation/update-go-agent).
     5  
     6  * [List of all changes](#all-changes)
     7  * [Checklist for upgrading](#checklist-for-upgrading)
     8  
     9  ## All Changes
    10  
    11  ### Dropped support for Go versions < 1.7
    12  
    13  The minimum required Go version to run the New Relic Go Agent is now 1.7.
    14  
    15  ### Package names
    16  
    17  The agent has been placed in a new `/v3` directory, leaving the top level directory with the now deprecated v2 agent. More specifically:
    18  * The `newrelic` package has moved from `"github.com/newrelic/go-agent"` to `"github.com/newrelic/go-agent/v3/newrelic"`. This makes named imports unnecessary.
    19  * The underscore in the `_integrations` directory is removed.  Thus the `"github.com/newrelic/go-agent/_integrations/nrlogrus"` import path becomes `"github.com/newrelic/go-agent/v3/integrations/nrlogrus"`.  Some of the integration packages have had other changes as well:
    20    * `_integrations/nrawssdk/v1` moves to `v3/integrations/nrawssdk-v1`
    21    * `_integrations/nrawssdk/v2` moves to `v3/integrations/nrawssdk-v2`
    22    * `_integrations/nrgin/v1` moves to `v3/integrations/nrgin`
    23    * `_integrations/nrgorilla/v1` moves to `v3/integrations/nrgorilla`
    24    * `_integrations/nrlogxi/v1` moves to `v3/integrations/nrlogxi`
    25    * `_integrations/nrecho` moves to `v3/integrations/nrecho-v3` and a new  `v3/integrations/nrecho-v4` has been added to support Echo version 4.
    26  
    27  ### Transaction Name Changes
    28  
    29  Transaction names created by [`WrapHandle`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WrapHandle),
    30  [`WrapHandleFunc`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WrapHandleFunc),
    31  [nrecho-v3](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v3),
    32  [nrecho-v4](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v4),
    33  [nrgorilla](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgorilla), and
    34  [nrgin](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgin) now
    35  include the HTTP method.  For example, the following code:
    36  
    37  ```go
    38  http.HandleFunc(newrelic.WrapHandleFunc(app, "/users", usersHandler))
    39  ```
    40  
    41  now creates a metric called `WebTransaction/Go/GET /users` instead of
    42  `WebTransaction/Go/users`.
    43  
    44  **As a result of this change, you may need to update your alerts and dashboards.**
    45  
    46  ### Go modules
    47  
    48  We have added go module support. The top level `"github.com/newrelic/go-agent/v3/newrelic"` package now has a `go.mod` file. Separate `go.mod` files are also included with each integration in the integrations directory.
    49  
    50  ### Configuration
    51  
    52  `NewConfig` was removed and the [`NewApplication`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewApplication) signature has changed to:
    53  
    54  ```go
    55  func NewApplication(opts ...ConfigOption) (*Application, error)
    56  `````
    57  
    58  New [`ConfigOption`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigOption) functions are provided to modify the [`Config`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Config). Here's what your Application creation will look like:
    59  
    60  ```go
    61  app, err := newrelic.NewApplication(
    62      newrelic.ConfigAppName("My Application"),
    63      newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
    64  )
    65  ```
    66  
    67  A complete list of `ConfigOption`s can be found in the [Go Docs](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigOption).
    68  
    69  ### Config.TransactionTracer
    70  
    71  The location of two [`Config`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Config) fields have been moved. The `Config.TransactionTracer.SegmentThreshold` field has moved to `Config.TransactionTracer.Segments.Threshold` and the  `Config.TransactionTracer.StackTraceThreshold` field has moved to to `Config.TransactionTracer.Segments.StackTraceThreshold`.
    72  
    73  ###  Remove API error return values
    74  
    75  The following method signatures have changed to no longer return an error; instead the error is logged to the agent logs.
    76  
    77  ```go
    78  func (txn *Transaction) End() {...}
    79  func (txn *Transaction) Ignore() {...}
    80  func (txn *Transaction) SetName(name string) {...}
    81  func (txn *Transaction) NoticeError(err error) {...}
    82  func (txn *Transaction) AddAttribute(key string, value interface{}) {...}
    83  func (txn *Transaction) SetWebRequestHTTP(r *http.Request) {...}
    84  func (txn *Transaction) SetWebRequest(r *WebRequest) {...}
    85  func (txn *Transaction) AcceptDistributedTracePayload(t TransportType, payload interface{}) {...}
    86  func (txn *Transaction) BrowserTimingHeader() *BrowserTimingHeader {...}
    87  func (s *Segment) End() {...}
    88  func (s *DatastoreSegment) End() {...}
    89  func (s *ExternalSegment) End() {...}
    90  func (s *MessageProducerSegment) End() {...}
    91  func (app *Application) RecordCustomEvent(eventType string, params map[string]interface{}) {...}
    92  func (app *Application) RecordCustomMetric(name string, value float64) {...}
    93  ```
    94  
    95  ### `Application.StartTransaction` signature change
    96  
    97  The signature of [`Application.StartTransaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application.StartTransaction)
    98  has changed to no longer take a `http.ResponseWriter` or `*http.Request`. The new signature just takes a string for
    99  the transaction name:
   100  
   101  ```go
   102  func (app *Application) StartTransaction(name string) *Transaction
   103  ```
   104  
   105  If you previously had code that used all three parameters, such as:
   106  
   107  ```go
   108  var writer http.ResponseWriter
   109  var req *http.Request
   110  txn := h.App.StartTransaction("server-txn", writer, req)
   111  ```
   112  
   113  After the upgrade, it should look like this:
   114  
   115  ```go
   116  var writer http.ResponseWriter
   117  var req *http.Request
   118  txn := h.App.StartTransaction("server-txn")
   119  writer = txn.SetWebResponse(writer)
   120  txn.SetWebRequestHTTP(req)
   121  ```
   122  
   123  ### Application and Transaction
   124  
   125  [`Application`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application) and [`Transaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction) have changed from interfaces to structs. All methods on these types have pointer receivers. Methods on these types are now nil-safe. References to these types in your code will need a pointer added. See the [checklist](#checklist-for-upgrading) for examples.
   126  
   127  ### Renamed attributes
   128  
   129  Two attributes have been renamed.  The old names will still be reported, but are deprecated and will be removed entirely in a future release.
   130  
   131  | Old (deprecated) attribute   | New attribute                |
   132  |------------------------------|------------------------------|
   133  | `httpResponseCode`           | `http.statusCode`            |
   134  | `request.headers.User-Agent` | `request.headers.userAgent`  |
   135  
   136  Since in v3.0 both the deprecated and the new attribute are being reported, if you have configured your application to ignore one or both of these attributes, such as with `Config.Attributes.Exclude`, you will now need to specify both the deprecated and the new attribute name in your configuration.
   137  
   138  ### RecordPanics configuration option
   139  
   140  This version introduces a new configuration option, `Config.ErrorCollector.RecordPanics`. This configuration controls whether or not a deferred `Transaction.End` will attempt to recover panics, record them as errors, and then re-panic them.  By default, this is set to `false`.  Previous versions of the agent always recovered panics, i.e. a default of `true`.
   141  
   142  ### New config option for getting data from environment variables
   143  
   144  Along with the new format for configuring an application, there is now an option to populate the configuration from environment variables. The full list of environment variables that are considered are included in the [Go Docs](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigFromEnvironment). The new configuration function is used as follows:
   145  
   146  ```go
   147  app, err := newrelic.NewApplication(newrelic.ConfigFromEnvironment())
   148  ```
   149  
   150  ### `Transaction` no longer implements `http.ResponseWriter`.
   151  
   152  As mentioned above, the [`Application.StartTransaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application.StartTransaction) no longer takes a `http.ResponseWriter` or `http.Request`; instead, after you start the transaction, you can set the `ResponseWriter` by calling [`Transaction.SetWebResponse`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebResponse):
   153  
   154  ```go
   155  txn := h.App.StartTransaction("server-txn")
   156  writer = txn.SetWebResponse(writer)
   157  ```
   158  
   159  The [`Transaction.SetWebResponse`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebResponse) method now returns a replacement `http.ResponseWriter` that implements the combination of `http.CloseNotifier`, `http.Flusher`, `http.Hijacker`, and `io.ReaderFrom` implemented by the input `http.ResponseWriter`.
   160  
   161  ### The `WebRequest` type has changed from an interface to a struct
   162  
   163  [`WebRequest`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WebRequest) has changed from an interface to a struct, which can be created via code like this:
   164  
   165  ```go
   166  webReq := newrelic.WebRequest{
   167  	Header:    hdrs,
   168  	URL:       url,
   169  	Method:    method,
   170  	Transport: newrelic.TransportHTTP,
   171  }
   172  ```
   173  
   174  The [`Transaction.SetWebRequest`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebRequest) method takes one of these structs.
   175  
   176  ### `SetWebRequestHTTP` method added
   177  
   178  In addition to the [`Transaction.SetWebRequest`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebRequest) method discussed in the section above, we have added a method [`Transaction.SetWebRequestHTTP`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebRequestHTTP) that takes an `*http.Request` and sets the appropriate fields.
   179  
   180  As described in the [earlier section](#applicationstarttransaction-signature-change), this can be used in your code as part of the signature change of [`Application.StartTransaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application.StartTransaction):
   181  
   182  ```go
   183  var writer http.ResponseWriter
   184  var req *http.Request
   185  txn := h.App.StartTransaction("server-txn")
   186  writer = txn.SetWebResponse(writer)
   187  txn.SetWebRequestHTTP(req)
   188  ```
   189  
   190  ### `NewRoundTripper`
   191  
   192  The transaction parameter to [`NewRoundTripper`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewRoundTripper) has been removed. The function signature is now:
   193  
   194  ```go
   195  func NewRoundTripper(t http.RoundTripper) http.RoundTripper
   196  ```
   197  
   198  [`NewRoundTripper`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewRoundTripper) will look for a transaction in the request's context using [`FromContext`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#FromContext).
   199  
   200  ### Distributed Trace methods
   201  
   202  When manually creating or accepting Distributed Tracing payloads, the method signatures have changed.
   203  
   204  This [`Transaction.InsertDistributedTraceHeaders`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.InsertDistributedTraceHeaders) method will insert the Distributed Tracing headers into the `http.Header` object passed as a parameter:
   205  
   206  ```go
   207  func (txn *Transaction) InsertDistributedTraceHeaders(hdrs http.Header)
   208  ```
   209  
   210  This [`Transaction.AcceptDistributedTraceHeaders`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.AcceptDistributedTraceHeaders) method takes a [`TransportType`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#TransportType) and an `http.Header` object that contains Distributed Tracing header(s) and links this transaction to other transactions specified in the headers:
   211  
   212  ```go
   213  func (txn *Transaction) AcceptDistributedTraceHeaders(t TransportType, hdrs http.Header)
   214  ```
   215  
   216  Additionally, the `DistributedTracePayload` struct is no longer needed and has been removed from the agent's API. Instead, distributed tracing information is passed around as key/value pairs in the `http.Header` object.
   217  
   218  ### Several functions marked as deprecated
   219  
   220  The functions [`StartSegmentNow`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#StartSegmentNow) and [`StartSegment`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#StartSegment) have been marked as deprecated.  The preferred new method of starting a segment have moved to [`Transaction.StartSegmentNow`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.StartSegmentNow) and [`Transaction.StartSegment`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.StartSegment) respectively.
   221  
   222  ```go
   223  // DEPRECATED:
   224  startTime := newrelic.StartSegmentNow(txn)
   225  // and
   226  sgmt := newrelic.StartSegment(txn, "segment1")
   227  ```
   228  
   229  ```go
   230  // NEW, PREFERRED WAY:
   231  startTime := txn.StartSegmentNow()
   232  // and
   233  sgmt := txn.StartSegment("segment1")
   234  ```
   235  
   236  Additionally the functions [`NewLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewLogger) and [`NewDebugLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewDebugLogger) have been marked as deprecated.  The preferred new method of configuring agent logging is using the [`ConfigInfoLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigInfoLogger) and [`ConfigDebugLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigDebugLogger) `ConfigOptions` respectively.
   237  
   238    ```go
   239    // DEPRECATED:
   240    app, err := newrelic.NewApplication(
   241        ...
   242        func(cfg *newrelic.Config) {
   243            cfg.Logger = newrelic.NewLogger(os.Stdout)
   244        }
   245    )
   246  
   247    // or
   248  
   249    app, err := newrelic.NewApplication(
   250        ...
   251        func(cfg *newrelic.Config) {
   252            cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
   253        }
   254    )
   255    ```
   256  
   257    ```go
   258    // NEW, PREFERRED WAY:
   259    app, err := newrelic.NewApplication(
   260        ...
   261        newrelic.ConfigInfoLogger(os.Stdout),
   262    )
   263  
   264    // or
   265  
   266    app, err := newrelic.NewApplication(
   267        ...
   268        newrelic.ConfigDebugLogger(os.Stdout),
   269    )
   270    ```
   271  
   272  ### Removed optional interfaces from error
   273  
   274  The interfaces `ErrorAttributer`, `ErrorClasser`, `StackTracer` are no longer exported. Thus, if you have any code checking to ensure that your custom type fulfills these interfaces, that code will no longer work. Example:
   275  
   276  ```go
   277  // This will no longer compile.
   278  type MyErrorType struct{}
   279  var _ newrelic.ErrorAttributer = MyErrorType{}
   280  ```
   281  
   282  ### Changed Distributed Tracing Constant
   283  
   284  `DistributedTracePayloadHeader` has been changed to `DistributedTraceNewRelicHeader`.
   285  
   286  ### `TransportType`
   287  
   288  [`TransportType`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#TransportType) type is changed from a struct to a string.
   289  
   290  ## Checklist for upgrading
   291  
   292  - [ ] Ensure your Go version is at least 1.7 (older versions are no longer supported).
   293  
   294  - [ ] Update imports. The v3.x agent now lives at "github.com/newrelic/go-agent/v3/newrelic" and no longer requires a named import.
   295  
   296    From:
   297  
   298    ```go
   299    import newrelic "github.com/newrelic/go-agent"
   300    ```
   301  
   302    To:
   303  
   304    ```go
   305    import "github.com/newrelic/go-agent/v3/newrelic"
   306    ```
   307  
   308    Additionally, if you are using any integrations, they too have moved. Each has its own version which matches the version of the 3rd party package it supports.
   309  
   310    From:
   311  
   312    ```go
   313    import "github.com/newrelic/go-agent/_integrations/nrlogrus"
   314    ```
   315  
   316    To:
   317  
   318    ```go
   319    import "github.com/newrelic/go-agent/v3/integrations/nrlogrus"
   320    ```
   321  
   322  - [ ] Update how you configure your application. The [`NewApplication`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewApplication) function now accepts [`ConfigOption`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigOption)s a list of which can be [found here](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigOption). If a [`ConfigOption`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigOption) is not available for your setting, create one yourself!
   323  
   324    From:
   325  
   326    ```go
   327    cfg := newrelic.NewConfig("appName", "__license__")
   328    cfg.CrossApplicationTracer.Enabled = false
   329    cfg.CustomInsightsEvents.Enabled = false
   330    cfg.ErrorCollector.IgnoreStatusCodes = []int{404, 418}
   331    cfg.DatastoreTracer.SlowQuery.Threshold = 3
   332    cfg.DistributedTracer.Enabled = true
   333    cfg.TransactionTracer.Threshold.Duration = 2
   334    cfg.TransactionTracer.Threshold.IsApdexFailing = false
   335    app, err := newrelic.NewApplication(cfg)
   336    ````
   337  
   338    To:
   339  
   340    ```go
   341    app, err := newrelic.NewApplication(
   342        newrelic.ConfigAppName("appName"),
   343        newrelic.ConfigLicense("__license__"),
   344        func(cfg *newrelic.Config) {
   345            cfg.CrossApplicationTracer.Enabled = false
   346            cfg.CustomInsightsEvents.Enabled = false
   347            cfg.ErrorCollector.IgnoreStatusCodes = []int{404, 418}
   348            cfg.DatastoreTracer.SlowQuery.Threshold = 3
   349            cfg.DistributedTracer.Enabled = true
   350            cfg.TransactionTracer.Threshold.Duration = 2
   351            cfg.TransactionTracer.Threshold.IsApdexFailing = false
   352        },
   353    )
   354    ```
   355  
   356    You can use [`ConfigFromEnvironment`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigFromEnvironment) to provide configuration from environment variables:
   357  
   358    ```go
   359    app, err := newrelic.NewApplication(newrelic.ConfigFromEnvironment())
   360    ```
   361  
   362  - [ ] Update the Transaction Tracer configuration. Change the fields for the two changed configuration options.
   363  
   364    | Old Config Field                               | New Config Field                                        |
   365    |------------------------------------------------|---------------------------------------------------------|
   366    | `Config.TransactionTracer.SegmentThreshold`    | `Config.TransactionTracer.Segments.Threshold`           |
   367    | `Config.TransactionTracer.StackTraceThreshold` | `Config.TransactionTracer.Segments.StackTraceThreshold` |
   368  
   369  - [ ] If you choose, set the `Config.ErrorCollector.RecordPanics` configuration option. This is a new configuration option that controls whether or not a deferred [`Transaction.End`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.End) will attempt to recover panics, record them as errors, and then re-panic them. Previously, the agent acted as though this option was set to `true`; with the new configuration it defaults to `false`.  If you wish to maintain the old agent behavior with regards to panics, be sure to set this to `true`.
   370  
   371  - [ ] Update code to use the new [`Application.StartTransaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application.StartTransaction) signature.
   372  
   373    From:
   374  
   375    ```go
   376    txn := app.StartTransaction("name", nil, nil)
   377  
   378    // or
   379  
   380    // writer is an http.ResponseWriter
   381    // req is an *http.Request
   382    txn := app.StartTransaction("name", writer, req)
   383    txn.WriteHeader(500)
   384    ```
   385  
   386    To, respectively:
   387  
   388    ```go
   389    txn := app.StartTransaction("name")
   390  
   391    // or
   392  
   393    // writer is an http.ResponseWriter
   394    // req is an *http.Request
   395    txn:= app.StartTransaction("name")
   396    writer = txn.SetWebResponse(writer)
   397    txn.SetWebRequestHTTP(req)
   398    writer.WriteHeader(500)
   399    ```
   400  
   401    Notice too that the [`Transaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction) no longer fulfills the `http.ResponseWriter` interface. Instead, the writer returned from [`Transaction.SetWebResponse`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.SetWebResponse) should be used.
   402  
   403  - [ ] Update code to no longer expect an error returned from these updated methods. Instead, check the agent logs for errors by using one of the [`ConfigLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigLogger), [`ConfigInfoLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigInfoLogger), or [`ConfigDebugLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigDebugLogger) configuration options.
   404  
   405    ```go
   406    func (txn *Transaction) End() {...}
   407    func (txn *Transaction) Ignore() {...}
   408    func (txn *Transaction) SetName(name string) {...}
   409    func (txn *Transaction) NoticeError(err error) {...}
   410    func (txn *Transaction) AddAttribute(key string, value interface{}) {...}
   411    func (txn *Transaction) SetWebRequestHTTP(r *http.Request) {...}
   412    func (txn *Transaction) SetWebRequest(r *WebRequest) {...}
   413    func (txn *Transaction) AcceptDistributedTracePayload(t TransportType, payload interface{}) {...}
   414    func (txn *Transaction) BrowserTimingHeader() *BrowserTimingHeader {...}
   415    func (s *Segment) End() {...}
   416    func (s *DatastoreSegment) End() {...}
   417    func (s *ExternalSegment) End() {...}
   418    func (s *MessageProducerSegment) End() {...}
   419    func (app *Application) RecordCustomEvent(eventType string, params map[string]interface{}) {...}
   420    func (app *Application) RecordCustomMetric(name string, value float64) {...}
   421    ```
   422  
   423  - [ ] Update uses of [`Application`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Application) and [`Transaction`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction) to be pointers, instead of direct references.
   424  
   425    From:
   426  
   427    ```go
   428    func doSomething(txn newrelic.Transaction) {...}
   429    func instrumentSomething(app newrelic.Application, h http.Handler, name string) {...}
   430    ```
   431  
   432    To:
   433  
   434    ```go
   435    func doSomething(txn *newrelic.Transaction) {...}
   436    func instrumentSomething(app *newrelic.Application, h http.Handler,  name string) {...}
   437    ```
   438  
   439  - [ ] If you are using a [`WebRequest`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WebRequest) type, it has changed from an interface to a struct. You can use it as follows:
   440  
   441    ```go
   442    wr := newrelic.WebRequest{
   443        Header:    r.Header,
   444        URL:       r.URL,
   445        Method:    r.Method,
   446        Transport: newrelic.TransportHTTP,
   447    }
   448    txn.SetWebRequest(wr)
   449    ```
   450  
   451  - [ ] Remove the `Transaction` parameter from the [`NewRoundTripper`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewRoundTripper), and instead ensure that the transaction is available via the request's context, using [`RequestWithTransactionContext`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#RequestWithTransactionContext).
   452  
   453    From:
   454  
   455    ```go
   456    client := &http.Client{}
   457    client.Transport = newrelic.NewRoundTripper(txn, client.Transport)
   458    req, _ := http.NewRequest("GET", "http://example.com", nil)
   459    client.Do(req)
   460    ```
   461  
   462    To:
   463  
   464    ```go
   465    client := &http.Client{}
   466    client.Transport = newrelic.NewRoundTripper(client.Transport)
   467    req, _ := http.NewRequest("GET", "http://example.com", nil)
   468    req = newrelic.RequestWithTransactionContext(req, txn)
   469    client.Do(req)
   470    ```
   471  
   472  - [ ] Update any usage of Distributed Tracing accept/create functions. The method for creating a distributed trace payload has changed to [`Transaction.InsertDistributedTraceHeaders`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.InsertDistributedTraceHeaders). Instead of returning a payload, it now accepts an `http.Header` and inserts the header(s) directly into it.
   473  
   474    From:
   475  
   476    ```go
   477    hdrs := http.Header{}
   478    payload := txn.CreateDistributedTracePayload()
   479    hdrs.Set(newrelic.DistributedTracePayloadHeader, payload.Text())
   480    ```
   481  
   482    To:
   483  
   484    ```go
   485    hdrs := http.Header{}
   486    txn.InsertDistributedTraceHeaders(hdrs)
   487    ```
   488  
   489    Similarly, the method for accepting distributed trace payloads has changed to [`Transaction.AcceptDistributedTraceHeaders`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.AcceptDistributedTraceHeaders). Instead of taking an interface representing the payload value, it now accepts an `http.Header` representing both the keys and values.
   490  
   491    From:
   492  
   493    ```go
   494    hdrs := request.Headers()
   495    payload := hdrs.Get(newrelic.DistributedTracePayloadHeader)
   496    txn.AcceptDistributedTracePayload(newrelic.TransportKafka, payload)
   497    ```
   498  
   499    To:
   500  
   501    ```go
   502    hdrs := request.Headers()
   503    txn.AcceptDistributedTraceHeaders(newrelic.TransportKafka, hdrs)
   504    ```
   505  
   506    Additionally, the `DistributedTracePayload` struct is no longer needed and has been removed from the agent's API. Instead, distributed tracing information is passed around as key/value pairs in the `http.Header` object. You should remove all references to `DistributedTracePayload` in your code.
   507  
   508  - [ ] Change `newrelic.DistributedTracePayloadHeader` to `newrelic.DistributedTraceNewRelicHeader`.
   509  
   510  - [ ] If you have configured your application to **ignore** either attribute described [here](#renamed-attributes), you will now need to specify both the deprecated and the new attribute name in your configuration.
   511  
   512    Configuration options where these codes might be used:
   513  
   514    ```go
   515    Config.TransactionEvents.Attributes
   516    Config.ErrorCollector.Attributes
   517    Config.TransactionTracer.Attributes
   518    Config.TransactionTrace.Segments.Attributes
   519    Config.BrowserMonitoring.Attributes
   520    Config.SpanEvents.Attributes
   521    Config.Attributes
   522    ```
   523  
   524    From old configuration example:
   525  
   526    ```go
   527    config.ErrorCollector.Attributes.Exclude = []string{
   528        "httpResponseCode",
   529        "request.headers.User-Agent",
   530    }
   531    // or
   532    config.ErrorCollector.Attributes.Exclude = []string{
   533        newrelic.AttributeResponseCode,
   534        newrelic.AttributeRequestUserAgent,
   535    }
   536    ```
   537  
   538    To:
   539  
   540    ```go
   541    config.ErrorCollector.Attributes.Exclude = []string{
   542        "http.statusCode",
   543        "httpResponseCode",
   544        "request.headers.userAgent",
   545        "request.headers.User-Agent",
   546    }
   547    // or
   548    config.ErrorCollector.Attributes.Exclude = []string{
   549        newrelic.AttributeResponseCode,
   550        newrelic.AttributeResponseCodeDeprecated,
   551        newrelic.AttributeRequestUserAgent,
   552        newrelic.AttributeRequestUserAgentDeprecated,
   553    }
   554    ```
   555  
   556  - [ ] Update alerts and dashboards with new transaction names:
   557  
   558    Transaction names created by
   559    [`WrapHandle`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WrapHandle),
   560    [`WrapHandleFunc`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#WrapHandleFunc),
   561    [nrecho-v3](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v3),
   562    [nrecho-v4](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v4),
   563    [nrgorilla](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgorilla), and
   564    [nrgin](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgin) now
   565    include the HTTP method.  Thus the transaction name `WebTransaction/Go/users` becomes `WebTransaction/Go/GET /users`.
   566  
   567  - [ ] Not required for upgrade, but recommended: update your usages of the now deprecated [`StartSegment`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#StartSegment) and [`StartSegmentNow`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#StartSegmentNow) to use the methods on the transaction: [`Transaction.StartSegment`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Transaction.StartSegment) and [`Transaction.StartSegmentNow`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#Trnasaction.StartSEgmentNow) respectively. This step is optional but highly recommended.
   568  
   569    From:
   570  
   571    ```go
   572    startTime := newrelic.StartSegmentNow(txn)
   573    // and
   574    sgmt := newrelic.StartSegment(txn, "segment1")
   575    ```
   576  
   577    To:
   578  
   579    ```go
   580    startTime := txn.StartSegmentNow()
   581    // and
   582    sgmt := txn.StartSegment("segment1")
   583    ```
   584  
   585  - [ ] Not required for upgrade, but recommended: update your usages of the now deprecated [`NewLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewLogger) and [`NewDebugLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#NewDebugLogger).  Instead use the new `ConfigOption`s [`ConfigInfoLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigInfoLogger) and [`ConfigDebugLogger`](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#ConfigDebugLogger) respectively.
   586  
   587    From:
   588  
   589    ```go
   590    app, err := newrelic.NewApplication(
   591        ...
   592        func(cfg *newrelic.Config) {
   593            cfg.Logger = newrelic.NewLogger(os.Stdout)
   594        }
   595    )
   596  
   597    // or
   598  
   599    app, err := newrelic.NewApplication(
   600        ...
   601        func(cfg *newrelic.Config) {
   602            cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
   603        }
   604    )
   605    ```
   606  
   607    To:
   608  
   609    ```go
   610    app, err := newrelic.NewApplication(
   611        ...
   612        newrelic.ConfigInfoLogger(os.Stdout),
   613    )
   614  
   615    // or
   616  
   617    app, err := newrelic.NewApplication(
   618        ...
   619        newrelic.ConfigDebugLogger(os.Stdout),
   620    )
   621    ```