Gin Telemetry is a middleware to exporting traces based on the open-telemetry project
To install execute the command below:
go get -u github.com/bancodobrasil/gin-telemetry
Below are the environment variables that affect the behavior of the middleware:
Variable | Description | Default |
---|---|---|
TELEMETRY_EXPORTER_JAEGER_AGENT_HOST | Agent Host for the collector that spans are sent to | localhost |
TELEMETRY_EXPORTER_JAEGER_AGENT_PORT | Agent Port URL for the collector that spans are sent to | 6831 |
TELEMETRY_HTTPCLIENT_TLS | Custom http client for passthrough TLS enabled | true |
TELEMETRY_DISABLED | Disable middleware to export span for collectors | false |
TELEMETRY_ENVIRONMENT | Environment to export span for collectors | test |
You must register the tracing middleware to enable export traces
Example for all routes:
import (
"github.com/gin-gonic/gin"
telemetry "github.com/bancodobrasil/gin-telemetry"
)
func main() {
// ... extra code
router := gin.Default()
router.Use(telemtry.Middleware("service_name"))
// ... extra code
}
Example for specific route:
import (
"github.com/gin-gonic/gin"
telemetry "github.com/bancodobrasil/gin-telemetry"
)
func main() {
// ... extra code
router := gin.Default()
router.GET("/user/:name", telemetry.Middleware(serviceName), handlerImpl)
// ... extra code
}
func handlerImpl(c *gin.Context) {
// handler implementation
}
Context propagation example through custom http client
import (
"net/http"
"github.com/gin-gonic/gin"
telemetry "github.com/bancodobrasil/gin-telemetry"
)
func main() {
// ... extra code
router := gin.Default()
router.GET("/user/:name", telemetry.Middleware(serviceName), handlerImpl)
// ... extra code
}
func handlerImple(c *gin.Context) {
// recover context
ctx := c.Request.Context()
// create a request with context
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/user/%s", externalServiceURL, name), nil)
// ... extra code
// do request with httpclient telemetry ** MUST **
res, err := telemetry.HTTPClient.Do(req)
// ... extra code
}
This instrumentation records logrus log messages as events on the existing span that is passed via a context.Context.
It does not record anything if a context does not contain a span.
Example:
import (
"github.com/uptrace/opentelemetry-go-extra/otellogrus"
"github.com/sirupsen/logrus"
)
// ...extra code
// Use ctx to pass the active span.
logrus.WithContext(ctx).
WithError(errors.New("hello world")).
WithField("foo", "bar").
Error("something failed")
// ...extra code
in the example
folder we have a docker-compose for testing traceability between 3 services and a active Jaeger as an exporter.
To start docker-compose executes:
~example$ docker-compose up --build -d
The services are published with the address below:
http://localhost:7001/user/:name
http://localhost:7002/user/:name
http://localhost:7003/user/:name
The jaeger is published with the address below:
http://localhost:16686
Open the browser and execute request according to addresses above and check jaeger panel. Thx!