---
title: Instrument Go segments
source: https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-segments
---

With New Relic for Go, you can monitor the specific segments of a [transaction](https://docs.newrelic.com/docs/apm/transactions/intro-transactions/transactions-new-relic-apm) in a Go application to get more detail about specific functions or code blocks.

## Measure time for functions and code blocks [#go-segments]

**Segments** are the specific parts of a [transaction](https://docs.newrelic.com/docs/apm/transactions/intro-transactions/transactions-new-relic-apm) in an application. By instrumenting segments, you can measure the time taken by functions and code blocks, such as external calls, datastore calls, adding messages to queues, and background tasks.

**Example:** You have a transaction associated with a checkout process, which processes both shipping information and credit card information. You could instrument your application to break that transaction up into two pieces: one segment for shipping and one segment for payment.

## Block-of-code segments [#segment-code-block]

Once you instrument a [transaction](https://docs.newrelic.com/docs/agents/go-agent/get-started/instrument-go-transactions), you are ready to instrument one or more segments in that transaction.

To instrument an arbitrary block of code as a segment, use the following pattern, and include [`txn`](https://docs.newrelic.com/docs/agents/go-agent/get-started/instrument-go-transactions) as the variable name set for the transaction:

```go
segment := newrelic.Segment{}
segment.Name = "mySegmentName"
segment.StartTime = txn.StartSegmentNow()
// ... code you want to time here ...
segment.End()
```

`StartSegment` is a convenient helper. It creates a segment and starts it:

```go
segment := txn.StartSegment("mySegmentName")
// ... code you want to time here ...
segment.End()
```

## Function segments [#segment-function]

Instrumenting a function as a segment is essentially the same as instrumenting an arbitrary block of code as a segment. The main difference is that, because a function has a discrete ending, you can use Go's [defer statement](https://gobyexample.com/defer).

To instrument a function as a segment, add the following code at the start of the function, and include [`txn`](https://docs.newrelic.com/docs/agents/go-agent/get-started/instrument-go-transactions) as the variable name set for the transaction:

```go
defer txn.StartSegment("mySegmentName").End()
```

## Nest segments [#go-nesting-segments]

Segments can be nested. The segment being ended must be the most recently started segment.

Here's an example of a segment starting and ending inside another segment:

```go
s1 := txn.StartSegment("outerSegment")
s2 := txn.StartSegment("innerSegment")
// s2 must end before s1
s2.End()
s1.End()
```

A zero value segment may safely be ended. Therefore, the following code is safe even if the conditional fails:

```go
var s newrelic.Segment
if recordSegment {
    s.StartTime = txn.StartSegmentNow()
}
// ... code you wish to time here ...
s.End()
```

## Datastore segments [#go-datastore-segments]

You can instrument Go application datastore calls. Datastore segments appear in the APM **Transactions breakdown** table and **Databases** tab of the [**Transactions** page](https://docs.newrelic.com/docs/apm/applications-menu/monitoring/transactions-page) in New Relic.

If you are using a MySQL, PostgreSQL, or SQLite database driver, the easiest way to add Datastore segments is to use our pre-built integration packages. Otherwise, you can manually create Datastore segments for each database call.

**Use instrumentation package**

There is an integration package for each database driver that we support:

| Database library supported                                    | Integration package                                                                                   |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| [go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) | [v3/integrations/nrmysql](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql)     |
| [lib/pq](https://github.com/lib/pq)                           | [v3/integrations/nrpq](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpq)           |
| [mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)       | [v3/integrations/nrsqlite3](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsqlite3) |

To use one of these integrations, first replace the driver with our integration version:

````go
import (
	// import our integration package in place of "github.com/go-sql-driver/mysql"
	_ "github.com/newrelic/go-agent/v3/integrations/nrmysql"
)

func main() {
	// open "nrmysql" in place of "mysql"
	db, err := sql.Open("nrmysql", "user@unix(/path/to/socket)/dbname")
}
```

Second, use the `ExecContext`, `QueryContext`, and `QueryRowContext` methods of [sql.DB](https://golang.org/pkg/database/sql/#DB), [sql.Conn](https://golang.org/pkg/database/sql/#Conn), [sql.Tx](https://golang.org/pkg/database/sql/#Tx), and [sql.Stmt](https://golang.org/pkg/database/sql/#Stmt) and provide a transaction-containing context. Calls to `Exec`, `Query`, and `QueryRow` do not get instrumented.

```go
ctx := newrelic.NewContext(context.Background(), txn)
row := db.QueryRowContext(ctx, "SELECT count(*) from tables")
```

If you are using a [database/sql](https://golang.org/pkg/database/sql/) database not listed above, you can write your own instrumentation for it using [InstrumentConnector](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#InstrumentConnector), [InstrumentDriver](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#InstrumentDriver), and [DriverSegmentBuilder](https://godoc.org/github.com/newrelic/go-agent/v3/newrelic#DriverSegmentBuilder). The integration packages act as examples of how to do this.

<Callout variant="important">
  Datastore integration packages for MySQL, PostgreSQL, and SQLite were added in Go agent v2.8.0 and require Go v1.10 or above.
</Callout>

````

**Use `DatastoreSegment`**

Just like basic segments, datastore segments begin when the `StartTime` field is populated and finish when the `End` method is called. To instrument a datastore segment, place the following at the beginning of the function you want to monitor:

````go
s := newrelic.DatastoreSegment{
    Product: newrelic.DatastoreMySQL,
    Collection: "users",
    Operation: "INSERT",
    ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)",
    QueryParameters: map[string]interface{}{
        "name": "Dracula",
        "age": 439,
    },
    Host: "mysql-server-1",
    PortPathOrID: "3306",
    DatabaseName: "my_database",
}
s.StartTime = txn.StartSegmentNow()
// ... make the datastore call
s.End()
```

For more information about:

* Assigning the `Collection`, `Operation`, `DatabaseName`, and other parameter values: See the [New Relic datastore segment documentation on GoDoc](https://godoc.org/github.com/newrelic/go-agent#DatastoreSegment).
* Available values for `Product`: See the [New Relic documentation on GitHub](https://github.com/newrelic/go-agent/blob/master/datastore.go).

When instrumenting a datastore call that spans an entire function call, you can use the defer statement to simplify instrumentation:

```go
s := newrelic.DatastoreSegment{
    StartTime: txn.StartSegmentNow(),
    Product: newrelic.DatastoreMySQL,
    Collection: "users",
    Operation: "INSERT",
    ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)",
    QueryParameters: map[string]interface{}{
        "name": "Dracula",
        "age": 439,
    },
    Host: "mysql-server-1",
    PortPathOrID: "3306",
    DatabaseName: "my_database",
}
defer s.End()
```

````

## External segments [#go-external-segments]

You can instrument Go application calls to external services, such as web services, resources in the cloud, and any other network calls. External segments appear in the APM **Transactions breakdown** table and the [**External services** page](https://docs.newrelic.com/docs/apm/applications-menu/monitoring/external-services-page) in New Relic.

There are two ways to instrument external segments:

**Use `StartExternalSegment()`**

Recommendation: Use the `StartExternalSegment` helper, since New Relic uses it to trace activity between your applications using [Distributed tracing](https://docs.newrelic.com/docs/agents/go-agent/features/distributed-tracing-go).

````go
func external(txn *newrelic.Transaction, req *http.Request) (*http.Response, error) {
    s := newrelic.StartExternalSegment(txn, req)
    response, err := http.DefaultClient.Do(req)
    s.Response = response
    s.End()
    return response, err
}
```

````

**Use `NewRoundTripper()`**

`NewRoundTripper` returns an [http.RoundTripper](https://golang.org/pkg/net/http/#RoundTripper), which allows you to instrument external calls without calling `StartExternalSegment` by modifying your `http.Client`'s `Transport` field. The `RoundTripper` returned will look for a `Transaction` in the request's context using [FromContext](https://godoc.org/github.com/newrelic/go-agent#FromContext).

Here is an example of `NewRoundTripper` instrumentation:

````go
client := &http.Client{}
client.Transport = newrelic.NewRoundTripper(client.Transport)

request, _ := http.NewRequest("GET", "http://example.com", nil)
request = newrelic.RequestWithTransactionContext(request, txn)

response, err := client.Do(request)
```

````

## Message producer segments [#go-message-producer-segments]

You can instrument Go application calls that add messages to queuing systems like RabbitMQ and Kafka. Message producer segments appear in the APM **Transactions breakdown** in New Relic.

There is only one way to instrument message producer segments:

**Use `MessageProducerSegment`**

Just like basic segments, message producer segments begin when the `StartTime` field is populated, and finish when the `End` method is called. To instrument a message producer segment, place the following at the beginning of the function you want to monitor:

````go
s := newrelic.MessageProducerSegment{
    Library:              "RabbitMQ",
    DestinationType:      newrelic.MessageExchange,
    DestinationName:      "myExchange",
    DestinationTemporary: false,
}
s.StartTime = txn.StartSegmentNow()
// ... add message to queue
s.End()
```

For more information about assigning the `Library`, `DestinationType`, `DestinationName`, or `DestinationTemporary` fields, see the [New Relic message producer segment documentation on GoDoc](https://godoc.org/github.com/newrelic/go-agent#MessageProducerSegment).

When instrumenting a message producer call that spans an entire function call, you can use the defer statement to simplify instrumentation:

```go
s := newrelic.MessageProducerSegment{
    StartTime:            txn.StartSegmentNow(),
    Library:              "RabbitMQ",
    DestinationType:      newrelic.MessageExchange,
    DestinationName:      "myExchange",
    DestinationTemporary: false,
}
defer s.End()
// ... add message to queue
```

<Callout variant="important">
  Message producer segments were added in Go agent version 2.14.0.
</Callout>

````
