Gin-gonic Instrumentation

Gin-gonic is a full featured web framework for Go.

Setup

To instrument your Go-gin application, you'll need to import the OpenTelemetry official instrumentation package:

shell
import "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"

The Go-gin instrumentation is packaged as a router middleware, as you can see in the example below, the tracer initialization is called before anything as described in more detail in the Go Configuration page. Adding otelgin.Middleware() to your app router is all that you need to get all your requests instrumented.

go
func main() { cleanup := initTracer() defer cleanup(context.Background()) router := gin.New() // This middleware must be added before any middlewares or routes router.Use(otelgin.Middleware("your-app-name")) // Your routes, app's logic, and server start up // ... }

Reporting request parameters

By default, the Gin instrumentation does not report any incoming request parameters, like query strings and JSON body contents.

To report these values to AppSignal, add a middleware to your Gorilla stack as follows:

go
import ( "bytes" "encoding/json" "io/ioutil" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func recordParameters(c *gin.Context) { span := trace.SpanFromContext(c.Request.Context()) parametersKey := attribute.Key("appsignal.request.parameters") queryParams := c.Request.URL.Query() bodyParams, err := ioutil.ReadAll(c.Request.Body) if err != nil { bodyParams = []byte("{}") } else { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyParams)) } params := make(map[string]any) json.Unmarshal(bodyParams, &params) for k, v := range queryParams { params[k] = v } if len(params) > 0 { serializedParams, err := json.Marshal(params) if err != nil { c.Next() return } span.SetAttributes(parametersKey.String(string(serializedParams))) } c.Next() } func main() { // Init OpenTelemetry cleanup := initTracer() defer cleanup(context.Background()) r := gin.New() r.Use(otelgin.Middleware("opentelemetry-go-gin")) // After the OpenTelemetry middleware, but before your other middlewares: r.Use(recordParameters) // Other middlewares and router handlers go here... }