19 November 2018 Releases

Elastic APM Go Agent 1.0.0 Released

By Andrew Wilkins

We’re thrilled to announce that our Elastic APM Go agent is now generally available (GA)!

Elastic Application Performance Monitoring (APM) is our open source solution for application performance monitoring. Elastic APM has support for Go, Java, Node.js, Python, Ruby, and Real User Monitoring (RUM) JavaScript.

The Go agent GA release (v1.0.0) comes with new features, bug fixes, and optimizations. For newcomers we will take a quick look at instrumenting Go applications, and then we will cover some of the changes in this release.

Instrumenting your Go Application

Elastic APM provides an API and various built-in modules for instrumenting your Go application, in order to monitor its performance and capture errors. To instrument your application, start by fetching the agent:

go get go.elastic.co/apm

Now that you’ve got the agent source, you can instrument your application. For a web service, you can install the middleware provided by module/apmhttp, or one of the other framework-specific modules, to measure the performance of incoming requests, and capture errors or panics raised during their processing.

Within a request, you can add detail in the form of “spans”. A span measures the duration of a code path, and may be nested within other spans. We provide modules that measure various operations, such as database/sql queries, or net/http client requests. You can also record custom spans with the agent’s API.

See the supported technologies documentation for a list of what instrumentation we support out of the box.

Configuring the Go agent

The Go agent is typically configured using environment variables. If your application and the APM Server are running on the same host, then you do not need to configure anything. Otherwise, you must configure the APM Server URL(s):

export ELASTIC_APM_SERVER_URLS=http://apm-server.local:8200

If your server requires a secret token for authentication, you must also set ELASTIC_APM_SECRET_TOKEN.

You can find the full list of environment variables in the agent’s configuration documentation. For instructions on setting up the APM Server, along with Elasticsearch and Kibana, see the Elastic APM Getting Started guide.

Visualizing Application Performance

After you have instrumented your application, and configured the agent to send data to your APM Server, you can start visualizing the monitoring data in the APM UI. The agent will report data to the APM Server grouped under a service. Unless you configure it otherwise, the service name is derived from the application’s binary name. e.g. If it’s called “/usr/local/bin/opbeans-go”, it will appear in the UI as “opbeans-go”.

In the APM UI you can view the number of requests, and distribution of response times over a configurable time period, broken down per service, transaction name (e.g. a web request route), and result (e.g. HTTP status code range, like “HTTP 2xx”). In addition to these, you can inspect the timeline of sample transactions that fit into a given response time bucket. Within a timeline you can visually identify which code paths are contributing the most to the response time.

APM UI

Major Changes

You can find the full list of changes since the beta in the 1.0.0 release notes. Read on for some of the more noteworthy reasons to upgrade.

Minimum Stack Version

Due to significant protocol changes, the Go agent now requires Elastic Stack version 6.5.0 or greater. See the Agent/Server Compatibility documentation for an outline of the compatibility between different versions of the APM agents and the APM Server.

Distributed Tracing

The biggest change for Elastic APM 6.5.0 is the introduction of support for distributed tracing, and Go agent 1.0.0 implements the necessary changes for this. You can read more about distributed tracing in the Elastic APM 6.5.0 release announcement.

The API for in-process context propagation has not changed. The built-in net/http and web framework instrumentation modules will take care of distributed trace header propagation as long as you are propagating the request context correctly.

You can read about context propagation in the instrumentation documentation.

V2 Intake Protocol

APM Server 6.5.0 introduces a new event intake protocol for agents, using NDJSON (newline-delimited JSON) and HTTP chunked encoding to enable streaming of events. The main impacts to the Go agent are slightly lower CPU and memory usage, and more immediate delivery of events to the server. Whereas with the previous (v1) protocol events were periodically flushed, with the new (v2) protocol, events are sent as soon as possible.

You can read more about the new intake protocol in “Increasing Memory Efficiency with an Improved Elastic APM Internal Intake Protocol”. We also previously covered some of the Go agent’s optimizations and other implementation details in “Inside the Elastic APM Go Agent”.

Integration of APM and OpenTracing spans

We previously announced support for the OpenTracing API in the Go agent in the form of module/apmot, which bridges the OpenTracing API to the Go agent’s native API.

In this release we have improved our OpenTracing implementation such that it supports distributed tracing, using the standard OpenTracing “carrier” APIs.

Our implementation now also correlates OpenTracing spans with transactions and spans created via the Go agent’s native API in the same process. When using the opentracing.StartSpanFromContext API, OpenTracing spans will be associated with the current APM transaction or span contained in the provided context. This means you can instrument your web framework with the Go agent’s native instrumentation modules, and any OpenTracing instrumentation within a request can then be included as spans within that request’s transaction timeline.

package main

import (
        "context"
        "database/sql"

        "github.com/labstack/echo"
        "github.com/opentracing/opentracing-go"

        "go.elastic.co/apm/module/apmecho"
        "go.elastic.co/apm/module/apmot"
        "go.elastic.co/apm/module/apmsql"
        _ "go.elastic.co/apm/module/apmsql/sqlite3"
)

var db *sql.DB

func myHandler(c echo.Context) error {
        span, ctx := opentracing.StartSpanFromContext(c.Request().Context(), "opentracing-span")
        defer span.Finish()
        return queryDatabase(ctx)
}

func queryDatabase(ctx context.Context) error {
        _, err := db.ExecContext(ctx, "SELECT * FROM foo")
        return err
}

func main() {
        opentracing.SetGlobalTracer(apmot.New())
        db, _ = apmsql.Open("sqlite3", ":memory:")

        e := echo.New()
        e.Use(apmecho.Middleware())
        e.GET("/", myHandler)
        e.Start("localhost:1234")
}

APM UI - Mixed APM/OpenTracing spans

You can read more about mixing the native Elastic APM and OpenTracing APIs in the OpenTracing bridge documentation.

Redis client (redigo) instrumentation module

We have implemented a new package, apmredigo, which provides a means of instrumenting Redigo so that Redis commands are reported as spans within the current transaction.

See the module/apmredigo documentation for usage.

go-restful instrumentation module

go-restful is a popular framework for writing REST-style web services in Go. We have implemented a new package, apmrestful, which provides a filter for tracing, and capturing panics in, go-restful requests.

See the module/apmrestful documentation for usage.

New import path

With this release, the Go agent’s import path has changed to

import "go.elastic.co/apm"

The top-level package name is now simply “apm”. No other package names have changed. The import path “github.com/elastic/apm-agent-go” will continue to work if you pin to version 0.5.x.

Onward

We welcome you to follow along on GitHub, or join us in the Discuss forum. We would also love it if you filled out the Go agent survey, to help shape its future.