Instana / OpenTelemetry Integration for Go Applications
Tags: apm, opentelemetry, go, observability
Published: 2023-07-03 06:05:13


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sg1avvdlph6ac0qko683.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdsy4b6gnmxa0aipqtin.png)
IBM's Instana application resource monitoring (ARM) tool leverages automation and artificial intelligence to deliver the visibility and actionable information DevOps teams need to manage dynamic applications. Instana can start monitoring a platform in a few seconds as soon as the agent for the target platform is deployed and voilà... that's it.

But what if a customer has already built several microservices applications, which are deployed on top of non-observed infrastructures by Instana and are already generating [OpenTelemetry](https://opentelemetry.io/) spans?

> **OpenTelemetry is a collection of APIs, SDKs, and tools. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.**

This is something that was asked by a customer who just wanted to know whether this is feasible or not. To try and prove this to the customer I went to the official documentation and tried to try out with example in Go programming language.

> **Instana can seamlessly integrate with [OpenTelemetry](https://www.ibm.com/docs/en/instana-observability/current?topic=apis-opentelemetry#sending-otlp-data-to-instana-backend) and can also enhance the data from OpenTelemetry. This integration further enhances data acquisition capabilities.**

The official documentation is here: [OpenTelemetry Integration for Go Application](https://www.ibm.com/docs/en/instana-observability/current?topic=go-opentelemetry-integration) which also points to a [public GitHub repository](https://github.com/instana/go-otel-exporter).

Obviously, the first thing to do is to clone the repository.

```shell
git clone https://github.com/instana/go-otel-exporter.git
```

> I had an old version of Go on my laptop, I updated it to Go 20 in order to make this work.

Once in the folder where the code is cloned to the following (as mentioned on the GitHub page)

```go
 go get github.com/instana/go-otel-exporter
```

With the cloned repository, the main.go app is in the **examples** subfolder. Depending on how you want to work it, you might need to create the following **go.work** file.

```go
// go.work

go 1.20

use ./example
```

The provided **main.go** file as provided on the GitHub repo is the following;

```go
package main

import (
	"context"
	"time"

	instana "github.com/instana/go-otel-exporter"
	"go.opentelemetry.io/otel"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/trace"
)

// This example application demonstrates how to use the Instana OTel Exporter.
// Make sure to provide the required environment variables before run the application:
// * INSTANA_ENDPOINT_URL
// * INSTANA_AGENT_KEY
func main() {
	ch := make(chan bool)
	// Acquire an instance of the Instana OTel Exporter
	exporter := instana.New()

	// Setup and bootstrap the tracer provider
	tracerProvider := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)

	otel.SetTracerProvider(tracerProvider)

	ctx := context.Background()

	// Instrument something with OTel
	tracer := otel.Tracer("my-traced-tech")
	_, span := tracer.Start(ctx, "my_span", trace.WithSpanKind(trace.SpanKindServer))

	// This simulates the time that a span takes to be completed
	time.Sleep(time.Millisecond * 400)
	span.End()

	<-ch
}
```

## Required elements to enable tracing in Instana

The elements which are **required** to make all this work are;

- the **INSTANA_AGENT_KEY** which could be retrieved from the Instana instance/tenant you want to work with. Follow this link to find the information: [Preparing endpoints and keys](https://www.ibm.com/docs/en/instana-observability/current?topic=planning-preparing-endpoints-keys#monitoring-ingress-endpoints).

- the **INSTANA_ENDPOINT_URL**: follow this link to find the information: [Preparing endpoints and keys](https://www.ibm.com/docs/en/instana-observability/current?topic=planning-preparing-endpoints-keys#monitoring-ingress-endpoints).

- you would surely like to have a service name **INSTANA_SERVICE_NAME**

- last but not least, you should have **spans** in various parts of your application so that it could be traced precisel

  > **[Spans](https://www.ibm.com/docs/en/instana-observability/current?topic=monitoring-traces) **represent the timing of code executions**; in other words, an action with a start and end time. It also contains a set of data that consists of both a timestamp and a duration.**

As I wanted a real **"quick and dirty"** version, I made some changes and made what follows;

```go
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	instana "github.com/instana/go-otel-exporter"
	"go.opentelemetry.io/otel"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/trace"
)

// This example application demonstrates how to use the Instana OTel Exporter.
// Make sure to provide the required environment variables before run the application:
// * INSTANA_ENDPOINT_URL
// * INSTANA_AGENT_KEY
// You can also use the INSTANA_LOG_LEVEL environment variable to set the log level. Available options are:
// * debug
// * info
// * warn
// * error
func main() {

	os.Setenv("INSTANA_AGENT_KEY", "XXXXXXXX ---- MY INSTANA SERVER AGENT KEY ------")
	os.Setenv("INSTANA_ENDPOINT_URL", "https://serverless-orange-saas.instana.io")
	os.Setenv("INSTANA_SERVICE_NAME", "AAM-SERVICE")

	fmt.Println("INSTANA_AGENT_KEY:", os.Getenv("INSTANA_AGENT_KEY"))
	fmt.Println("INSTANA_ENDPOINT_URL:", os.Getenv("INSTANA_ENDPOINT_URL"))
	fmt.Println("INSTANA_SERVICE_NAME:", os.Getenv("INSTANA_SERVICE_NAME"))

	//ch := make(chan struct{})
	// Acquire an instance of the Instana OTel Exporter
	exporter := instana.New()

	// Setup and bootstrap the tracer provider
	tracerProvider := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)

	otel.SetTracerProvider(tracerProvider)

	ctx := context.Background()

	// Instrument something with OTel
	tracer := otel.Tracer("AAM-my-traced-tech")
	_, span := tracer.Start(ctx, "my_span", trace.WithSpanKind(trace.SpanKindServer))
	time.Sleep(time.Millisecond * 400)
	span.End()

	
	for i := 0; i < 300; i++ {
		time.Sleep(time.Millisecond * 500)
		fmt.Println("i:", i)
	}

}
```

Once you've executed your application, go to the Instana dashboard and make a search filter for your service.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8w3x6b1lsped2tcz14z.png)

This example is more than basic. It just shows that application code written in any language which sends tracing metrics to **OpenTelemetry** could be easily modified to work with **Instana**.

My next step is to do the same sample showcase with **Python**.

Thanks for reading and stay tuned!

**Links**

Concepts of Tracing: https://www.ibm.com/docs/en/instana-observability/current?topic=monitoring-traces

Monitoring Go: https://www.ibm.com/docs/en/instana-observability/current?topic=technologies-monitoring-go#tracing