The IBM Instana Go Tracer is an SDK that collects traces, metrics, logs and provides profiling for Go applications. The tracer is part of the IBM Instana Observability tool set.
Tracer Version | Go version |
---|---|
v1.62.0 and higher | v1.21.0 and higher |
v1.47.0 to v1.61.0 | v1.13.0 and higher |
Less than v1.47.0 | v1.9.0 and higher |
Note
Make sure to always use the latest version of the tracer, as it provides new features, improvements, security updates and fixes.
Important
Since v1.53.0, the Go Tracer uses fsm v1.0.1 internally. Customers using fsm prior to v1 in their projects will need to update it to v1.
To add the tracer to your project, run:
go get -u github.com/instana/go-sensor@latest
Note
As a good practice, add this command to your CI pipeline or your automated tool before building the application to keep the tracer up to date.
Once the tracer is added to the project, import the package into the entrypoint file of your application:
import (
...
instana "github.com/instana/go-sensor"
)
Create a reference to the collector and initialize it with a service name:
var (
...
col instana.TracerLogger
)
func init() {
...
col = instana.InitCollector(&instana.Options{
Service: "My app",
})
}
Note
The tracer expects the Instana Agent to be up and running in the default port 42699. You can change the port with the environment variable INSTANA_AGENT_PORT
.
Note
For non default options, like the Agent host and port, the tracer can be configured either via SDK options, environment variables or Agent options.
Once the collector has been initialized with instana.InitCollector
, application metrics such as memory, CPU consumption, active goroutine count etc will be automatically collected and reported to the Agent without further actions or configurations to the SDK.
This data is then already available in the dashboard.
Let's collect traces of calls received by an HTTP server.
Before any changes, your code should look something like this:
// endpointHandler is the standard http.Handler function
http.HandleFunc("/endpoint", endpointHandler)
log.Fatal(http.ListenAndServe(":9090", nil))
Wrap the endpointHandler
function with instana.TracingHandlerFunc
. Now your code should look like this:
// endpointHandler is now wrapped by `instana.TracingHandlerFunc`
http.HandleFunc("/endpoint", instana.TracingHandlerFunc(col, "/endpoint", endpointHandler))
log.Fatal(http.ListenAndServe(":9090", nil))
When running the application, every time /endpoint
is called, the tracer will collect this data and send it to the Instana Agent.
You can monitor traces to this endpoint in the Instana UI.
Unlike metrics, profiling needs to be enabled with the EnableAutoProfile
option, as seen here:
col = instana.InitCollector(&instana.Options{
Service: "My app",
EnableAutoProfile: true,
})
You should be able to see your application profiling in the Instana UI under Analytics/Profiles.
In terms of logging, the SDK provides two distinct logging features:
- Traditional logging, that is, logs reported to the standard output, usually used for debugging purposes
- Instana logs, a feature that allows customers to report logs to the dashboard under Analytics/Logs
Many logs are provided by the SDK, usually prefixed with "INSTANA" and are useful to understand what the tracer is doing underneath. It can also be used for debugging and troubleshoot reasons.
Customers can also provide logs by calling one of the following: Collector.Info(), Collector.Warn(), Collector.Error(), Collector.Debug(). You can setup the log level via options or the INSTANA_LOG_LEVEL
environment variable.
You can find detailed information in the Instana documentation.
Instana Logs are spans of the type log.go
that are rendered in a special format in the dashboard.
You can create logs and report them to the agent or attach them as children of an existing span.
The code snippet below shows how to create logs and send them to the agent:
col := instana.InitCollector(&instana.Options{
Service: "My Go App",
})
col.StartSpan("log.go", []ot.StartSpanOption{
ot.Tags{
"log.level": "error", // available levels: info, warn, error, debug
"log.message": "error from log.go span",
},
}...).Finish() // make sure to "finish" the span, so it's sent to the agent
This log can then be visualized in the dashboard under Analytics/Logs. You can add a filter by service name. In our example, the service name is "My Go App".
Go tracer support the opt-in feature for the exit spans. When enabled, the collector can start capturing exit spans, even without an entry span. This capability is particularly useful for scenarios like cronjobs and other background tasks, enabling the users to tailor the tracing according to their specific requirements. By setting the INSTANA_ALLOW_ROOT_EXIT_SPAN
variable, users can choose whether the tracer should start a trace with an exit span or not. The environment variable can have 2 values. (1: Tracer should record exit spans for the outgoing calls, when it has no active entry span. 0 or any other values: Tracer should not start a trace with an exit span).
export INSTANA_ALLOW_ROOT_EXIT_SPAN=1
package main
import (
"log"
"net/http"
instana "github.com/instana/go-sensor"
)
func main() {
col := instana.InitCollector(&instana.Options{
Service: "Basic Usage",
EnableAutoProfile: true,
})
http.HandleFunc("/endpoint", instana.TracingHandlerFunc(col, "/endpoint", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
log.Fatal(http.ListenAndServe(":7070", nil))
}
Let's quickly summarize what we have seen so far:
- We learned how to install, import and initialize the Instana Go Tracer.
- Once the tracer is initialized, application metrics are collected out of the box.
- Application profiling can be enabled via the
EnableAutoProfile
option. - Tracing incoming HTTP requests by wrapping the Go standard library
http.Handler
withinstana.TracingHandlerFunc
.
With this knowledge it's already possible to make your Go application traceable by our SDK. But there is much more you can do to enhance tracing for your application.
The basic functionality covers tracing for the following standard Go features:
- HTTP incoming requests
- HTTP outgoing requests
- SQL drivers
As we already covered HTTP incoming requests, we suggest that you understand how to collect data from HTTP outgoing requests and SQL driver databases.
Another interesting feature is the usage of additional packages located under instrumentation. Each of these packages provide tracing for specific Go packages like the AWS SDK, Gorm and Fiber.