Learn about the Wavefront Go Integration.

Go Integration

This Wavefront Go integration explains how to send Go application metrics to Wavefront.

Wavefront provides several Go SDKs for different purposes on Github:

  • wavefront-sdk-go: Core SDK for sending different telemetry data to Wavefront. Data include metrics, delta counters, distributions, and spans.
  • go-metrics-wavefront: Provides reporters and constructs such as counters, meters and histograms to periodically report application metrics and distributions to Wavefront.
  • wavefront-lambda-go: Wavefront Go wrapper for AWS Lambda to enable reporting of standard lambda metrics and custom app metrics directly to Wavefront.
  • wavefront-opentracing-sdk-go: Wavefront OpenTracing Go SDK. See our tracing documentation for background.

In the Setup tab, the integration includes sample code based on go-metrics-wavefront for sending metrics to a Wavefront proxy or using direct ingestion. The Setup tab includes both a simple example and an extended example for adding metric-level tags.

The steps in the Setup tab explain how to collect Go runtime metrics. This integration provides a dashboard based on the collected Go runtime metrics.

Go Setup

The Wavefront plugin for go-metrics adds Wavefront reporters and an abstraction that supports tagging at the reporter and metric levels. The reporters support sending metrics to Wavefront using the Wavefront proxy or using direct ingestion.

Option 1. Create a Wavefront Proxy Reporter

Follow these steps for sending metrics to a Wavefront proxy. See Option 2 for sending metrics directly to a Wavefront service.

Step 1. Set up Wavefront Proxy

If you do not have a Wavefront proxy installed on your network and reachable from your Go application, install a proxy. You configure the Wavefront proxy hostname and port (by default 2878) when you invoke the reporter.

Step 2. Create the Wavefront Proxy Reporter

import (
  "net"

  "github.com/wavefronthq/wavefront-sdk-go/senders"
  "github.com/wavefronthq/go-metrics-wavefront"
  "github.com/rcrowley/go-metrics"
)

func main() {
  proxyCfg := &senders.ProxyConfiguration {
        // The proxy hostname or address
        Host : "proxyHostname or proxyIPAddress",

        // Set the proxy port to send metrics to. Default: 2878
        MetricsPort : 2878,

        // Set a proxy port to send histograms to. Recommended: 2878
        DistributionPort: 2878,
  }

  // Create the proxy sender
  sender, err := senders.NewProxySender(proxyCfg)
  if err != nil {
      panic(err)
  }

  reporter := reporting.NewReporter(
    sender,
    application.New("test-app", "test-service"),
    reporting.Source("go-metrics-test"),
    reporting.Prefix("test.prefix"),
    reporting.LogErrors(true),
  )
}

Option 2. Create a Wavefront Direct Reporter

You can send metrics directly to a Wavefront service, discussed next. Option 1 above explains how to send metrics to a Wavefront proxy.

import (
  "github.com/wavefronthq/wavefront-sdk-go/senders"
  "github.com/wavefronthq/go-metrics-wavefront"
  "github.com/rcrowley/go-metrics"
)

func main() {
  directCfg := &senders.DirectConfiguration{
    Server: "https://YOUR_CLUSTER.wavefront.com",
    Token:  "YOUR_API_TOKEN",
  }

  sender, err := senders.NewDirectSender(directCfg)
  if err != nil {
    panic(err)
  }

  reporter := reporting.NewReporter(
    sender,
    application.New("test-app", "test-service"),
    reporting.Source("go-metrics-test"),
    reporting.Prefix("test.prefix"),
    reporting.LogErrors(true),
  )
}

Adding Metric-level Tags

You can add tags to individual metrics.

import (
  "github.com/rcrowley/go-metrics"
  "github.com/wavefronthq/go-metrics-wavefront"
)

func main() {
  // create a reporter using steps above

  // create tags you wish to add on the metrics
  tags := map[string]string{
    "key1": "val1",
    "key2": "val2",
  }
  counter := metrics.NewCounter() // Create a counter
  reporter.RegisterMetric("foo", counter, tags) // will create a 'test.prefix.foo.count' metric with tags
  counter.Inc(47)
}

Collecting Go Runtime Metrics

You can enable the runtime metric flag in the reporter to collect Go runtime metrics:

func main() {
  // set reporting.RuntimeMetric(true) when creating a reporter using the steps mentioned above
  reporter := reporting.NewReporter(
    sender,
    application.New("test-app", "test-service"),
    reporting.Source("go-metrics-test"),
    reporting.Prefix("test.prefix"),
    reporting.LogErrors(true),
    reporting.RuntimeMetric(true),
  )
}

Extended Example

package main

import (
	"fmt"
	"math/rand"
	"os"
	"time"

	metrics "github.com/rcrowley/go-metrics"
	"github.com/wavefronthq/go-metrics-wavefront/reporting"
	"github.com/wavefronthq/wavefront-sdk-go/application"
	"github.com/wavefronthq/wavefront-sdk-go/senders"
)

func main() {

	// Tags we'll add to the metric
	tags := map[string]string{
		"key2": "val2",
		"key1": "val1",
		"key0": "val0",
		"key4": "val4",
		"key3": "val3",
	}

	// Create a direct sender
	directCfg := &senders.DirectConfiguration{
    Server:               "https://YOUR_CLUSTER.wavefront.com",
    Token:                "YOUR_API_TOKEN",
		BatchSize:            10000,
		MaxBufferSize:        50000,
		FlushIntervalSeconds: 1,
	}

	sender, err := senders.NewDirectSender(directCfg)
	if err != nil {
		panic(err)
	}

	reporter := reporting.NewReporter(
		sender,
		application.New("test-app", "test-service"),
		reporting.Source("go-metrics-test"),
		reporting.Prefix("test.prefix"),
		reporting.LogErrors(true),
	)

	// Create a counter metric and register with tags
	counter := metrics.NewCounter()                
	reporter.RegisterMetric("foo", counter, tags)
	counter.Inc(47)

	// Create a histogram and register with tags
	histogram := reporting.NewHistogram()
	reporter.RegisterMetric("duration", histogram, tags)

	// Create a histogram and register without tags
	histogram2 := reporting.NewHistogram()
	reporter.Register("duration2", histogram2)

	deltaCounter := metrics.NewCounter()
	reporter.RegisterMetric(reporting.DeltaCounterName("delta.metric"), deltaCounter, tags)
	deltaCounter.Inc(10)

	fmt.Println("Search wavefront: ts(\"test.prefix.foo.count\")")
	fmt.Println("Entering loop to simulate metrics flushing. Hit ctrl+c to cancel")

	for {
		counter.Inc(rand.Int63())
		histogram.Update(rand.Int63())
		histogram2.Update(rand.Int63())
		deltaCounter.Inc(10)
		time.Sleep(time.Second * 10)
	}
}