Skip to content

Commit 9de11d8

Browse files
committed
otelgin: Add a WithSpanStartOptions option
1 parent c1aeca6 commit 9de11d8

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2121
- Allow configuring samplers in `go.opentelemetry.io/contrib/otelconf`. (#7148)
2222
- Slog log bridge now sets `SeverityText` attribute using source value in `go.opentelemetry.io/contrib/bridges/otelslog`. (#7198)
2323
- Add `http.route` metric attribute in `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`. (#7275)
24+
- Add the `WithSpanStartOptions` option to add extra attributes, links, etc. to the spans it generates in `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`. (#7261)
2425

2526
### Changed
2627

instrumentation/github.com/gin-gonic/gin/otelgin/config.go

+9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
type config struct {
2222
TracerProvider oteltrace.TracerProvider
2323
Propagators propagation.TextMapPropagator
24+
SpanStartOptions []oteltrace.SpanStartOption
2425
Filters []Filter
2526
GinFilters []GinFilter
2627
SpanNameFormatter SpanNameFormatter
@@ -89,6 +90,14 @@ func WithPropagators(propagators propagation.TextMapPropagator) Option {
8990
})
9091
}
9192

93+
// WithSpanStartOptions configures an additional set of
94+
// trace.SpanStartOptions, which are applied to each new span.
95+
func WithSpanStartOptions(opts ...oteltrace.SpanStartOption) Option {
96+
return optionFunc(func(c *config) {
97+
c.SpanStartOptions = append(c.SpanStartOptions, opts...)
98+
})
99+
}
100+
92101
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
93102
// If none is specified, the global provider is used.
94103
func WithTracerProvider(provider oteltrace.TracerProvider) Option {

instrumentation/github.com/gin-gonic/gin/otelgin/gin.go

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
// server handling the request.
3232
func Middleware(service string, opts ...Option) gin.HandlerFunc {
3333
cfg := config{}
34+
3435
for _, opt := range opts {
3536
opt.apply(&cfg)
3637
}
@@ -95,6 +96,8 @@ func Middleware(service string, opts ...Option) gin.HandlerFunc {
9596
oteltrace.WithSpanKind(oteltrace.SpanKindServer),
9697
}
9798

99+
opts = append(opts, cfg.SpanStartOptions...)
100+
98101
spanName := cfg.SpanNameFormatter(c)
99102
if spanName == "" {
100103
spanName = fmt.Sprintf("HTTP %s route not found", c.Request.Method)

instrumentation/github.com/gin-gonic/gin/otelgin/test/gin_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,31 @@ func TestSpanStatus(t *testing.T) {
268268
})
269269
}
270270

271+
func TestWithSpanOptions_CustomAttributesAndSpanKind(t *testing.T) {
272+
sr := tracetest.NewSpanRecorder()
273+
provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))
274+
275+
customAttr := attribute.String("custom.key", "custom.value")
276+
277+
router := gin.New()
278+
router.Use(otelgin.Middleware("foobar",
279+
otelgin.WithTracerProvider(provider),
280+
otelgin.WithSpanStartOptions(trace.WithAttributes(customAttr)),
281+
))
282+
router.GET("/test", func(c *gin.Context) {})
283+
284+
r := httptest.NewRequest("GET", "/test", nil)
285+
w := httptest.NewRecorder()
286+
router.ServeHTTP(w, r)
287+
288+
spans := sr.Ended()
289+
require.Len(t, spans, 1)
290+
291+
span := spans[0]
292+
assert.Contains(t, span.Attributes(), customAttr)
293+
assert.Equal(t, trace.SpanKindServer, span.SpanKind())
294+
}
295+
271296
func TestSpanName(t *testing.T) {
272297
sr := tracetest.NewSpanRecorder()
273298
provider := sdktrace.NewTracerProvider(

0 commit comments

Comments
 (0)