Skip to content
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2c9466a
add http middleware
krishankumar01 Dec 23, 2025
7ccca56
add http transport
krishankumar01 Dec 29, 2025
8df0782
optimise http telemetry package
krishankumar01 Dec 29, 2025
01ecf4b
add test cases for Telemetry middleware
krishankumar01 Dec 29, 2025
0d8fda5
add auto instrumentation configs
krishankumar01 Dec 29, 2025
b2c07d5
Merge branch 'master' into kkumar-gcc/#726-auto-instrumentation-2
krishankumar01 Jan 2, 2026
395f109
add config to enable Telemetry for http clients
krishankumar01 Jan 2, 2026
bb1f529
add docs for config facade
krishankumar01 Jan 2, 2026
441ba96
add ConfigFacade nil warning
krishankumar01 Jan 2, 2026
cb3cb89
Merge branch 'master' into kkumar-gcc/#726-auto-instrumentation-2
krishankumar01 Jan 4, 2026
7c59c97
disable default telemetry
krishankumar01 Jan 4, 2026
ab72e2a
optimise transport
krishankumar01 Jan 4, 2026
413bdd6
add kill switch for instrumentation
krishankumar01 Jan 4, 2026
f999029
update the stubs
krishankumar01 Jan 4, 2026
98ec1f7
remove unnecessary handler
krishankumar01 Jan 4, 2026
ad59c56
optimise log instrumentation
krishankumar01 Jan 4, 2026
1fea34b
move route registration in the end
krishankumar01 Jan 4, 2026
794ed71
lazily initialize middleware and transport to work with new applicati…
krishankumar01 Jan 4, 2026
76021c2
optimise channel test
krishankumar01 Jan 4, 2026
eb97e1b
optimise channel test
krishankumar01 Jan 4, 2026
c23884a
merge master
krishankumar01 Jan 18, 2026
e4faad6
accept telemetry facade as an input instead of using global instance
krishankumar01 Jan 18, 2026
5141d18
use a callback to resolve the telemetry facade instance
krishankumar01 Jan 18, 2026
5a26971
optimise grpc handler to remove usage of telemetry and config facade
krishankumar01 Jan 18, 2026
5a5d9fc
optimise the grpc handler
krishankumar01 Jan 18, 2026
75130b9
Merge branch 'master' into kkumar-gcc/#726-auto-instrumentation-2
krishankumar01 Jan 20, 2026
09f4745
use telemetry transport if enabled
krishankumar01 Jan 20, 2026
9793141
optimise http auto instrumentation
krishankumar01 Jan 20, 2026
bd0645b
optimize log test cases
krishankumar01 Jan 20, 2026
f7e34b8
optimise
krishankumar01 Jan 21, 2026
777ce25
optimise
krishankumar01 Jan 21, 2026
43a7d8f
optimise
krishankumar01 Jan 26, 2026
9d3460c
optimise
krishankumar01 Jan 26, 2026
4fcd103
Merge branch 'master' into kkumar-gcc/#726-auto-instrumentation-2
krishankumar01 Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions foundation/application_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ func (r *ApplicationBuilder) Create() foundation.Application {
}
}

// Register routes
for _, route := range r.routes {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving the route registration to the end, because if a user registers any gRPC stats handler or interceptors after calling routes.Grpc() (since in this file we usually call facades.Grpc().Server()), they will be ignored as the server is initialized only once in grpc/application.go.

route()
}

// Register event listeners
if len(r.eventToListeners) > 0 {
eventFacade := r.app.MakeEvent()
Expand Down Expand Up @@ -203,6 +198,11 @@ func (r *ApplicationBuilder) Create() foundation.Application {
r.callback()
}

// Register routes
for _, route := range r.routes {
route()
}

// Boot service providers after all settings
r.app.BootServiceProviders()

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ require (
github.com/stretchr/testify v1.11.1
github.com/urfave/cli/v3 v3.6.1
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0
go.opentelemetry.io/contrib/propagators/b3 v1.39.0
go.opentelemetry.io/otel v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0
Expand Down Expand Up @@ -62,6 +63,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chigopher/pathlib v0.19.1 // indirect
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/go-cmp v0.7.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
Expand Down Expand Up @@ -274,6 +276,8 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ=
go.opentelemetry.io/contrib/propagators/b3 v1.39.0 h1:PI7pt9pkSnimWcp5sQhUA9OzLbc3Ba4sL+VEUTNsxrk=
go.opentelemetry.io/contrib/propagators/b3 v1.39.0/go.mod h1:5gV/EzPnfYIwjzj+6y8tbGW2PKWhcsz5e/7twptRVQY=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
Expand Down
3 changes: 3 additions & 0 deletions http/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ type Config struct {
// IdleConnTimeout is the maximum amount of time an idle (keep-alive) connection
// will remain idle before closing itself.
IdleConnTimeout time.Duration `json:"idle_conn_timeout"`

// EnableTelemetry determines if OpenTelemetry tracing/metrics are enabled for this client.
EnableTelemetry bool `json:"enable_telemetry"`
}
15 changes: 10 additions & 5 deletions http/client/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/goravel/framework/contracts/foundation"
"github.com/goravel/framework/contracts/http/client"
httperrors "github.com/goravel/framework/errors"
telemetryhttp "github.com/goravel/framework/telemetry/instrumentation/http"
)

var _ client.Factory = (*Factory)(nil)
Expand Down Expand Up @@ -105,13 +106,17 @@ func (f *Factory) resolveClient(name string) (*http.Client, error) {
func (f *Factory) createHTTPClient(cfg *Config) *http.Client {
// Clone the default transport to ensure strict isolation between clients.
// This prevents shared state (like global timeouts) from leaking between instances.
transport := http.DefaultTransport.(*http.Transport).Clone()
baseTransport := http.DefaultTransport.(*http.Transport).Clone()

transport.MaxIdleConns = cfg.MaxIdleConns
transport.MaxIdleConnsPerHost = cfg.MaxIdleConnsPerHost
transport.MaxConnsPerHost = cfg.MaxConnsPerHost
transport.IdleConnTimeout = cfg.IdleConnTimeout
baseTransport.MaxIdleConns = cfg.MaxIdleConns
baseTransport.MaxIdleConnsPerHost = cfg.MaxIdleConnsPerHost
baseTransport.MaxConnsPerHost = cfg.MaxConnsPerHost
baseTransport.IdleConnTimeout = cfg.IdleConnTimeout

var transport http.RoundTripper = baseTransport
if cfg.EnableTelemetry {
transport = telemetryhttp.NewTransport(transport)
}
return &http.Client{
Timeout: cfg.Timeout,
Transport: transport,
Expand Down
2 changes: 1 addition & 1 deletion log/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func getHandlers(config config.Config, json foundation.Json, channel string) ([]
handlers = append(handlers, HandlerToSlogHandler(logger.NewConsoleHandler(config, json, level, formatter)))
}
case log.DriverOtel:
logLogger := telemetrylog.NewTelemetryChannel()
logLogger := telemetrylog.NewTelemetryChannel(config)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won’t work if we call the otel driver logger inside providers or from the application builder callbacks, or any callback that runs before provider bootstrap, because telemetry.TelemetryFacade won’t be initialized and therefore won’t be able to lazily initialize the logger. This is expected, as telemetry is typically available only within the request lifecycle context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about passing TelemetryFacade here instead of using telemetry.TelemetryFacade directly? telemetry/instrumentation/* should not use the global telemetry.TelemetryFacade and telemetry.ConfigFacade. They should be passed into.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then how do we ensure that a telemetry log channel can accept a telemetry facade instance? When we initialize the telemetry channel in NewApplication, the telemetry facade won’t be available yet. This would require making telemetry a dependency of the log facade.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we initialize the telemetry channel in NewApplication, the telemetry facade won’t be available yet.

It should be impossible if the telemetry facade is registered, the telemetry channel should not be initialized during registering service providers but during booting. Return an error here if the telemetry facade is nil during booting.

Copy link
Member Author

@krishankumar01 krishankumar01 Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if the user sets the OTEL driver as the default or includes it in the stack, then log.NewApplication will try to resolve the telemetry channel instance, which depends on the telemetry facade. Since telemetry depends on log facade it will register and boot after it.

Copy link
Member Author

@krishankumar01 krishankumar01 Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, facades.* should be used inside a callback function if users want to use them in bootstrap.go.

Can we also add an annotation here explaining the different scenarios in which this(WithCallback) should be used? Since this is called before bootstrapping the service providers, it would be helpful to clarify that. Could you please add that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optimization is a bit complex, I need about two or three days. Please continue other parts for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem, In mean time I will work on #1339.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

handler, err := logLogger.Handle(channelPath)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions telemetry/instrumentation/grpc/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (

// NewServerStatsHandler creates an OTel stats handler for the server.
func NewServerStatsHandler(opts ...Option) stats.Handler {
if telemetry.ConfigFacade == nil || !telemetry.ConfigFacade.GetBool("telemetry.instrumentation.grpc_server", true) {
return nil
}

if telemetry.TelemetryFacade == nil {
color.Warningln("[Telemetry] Facade not initialized. gRPC server stats instrumentation is disabled.")
return nil
Expand All @@ -22,6 +26,10 @@ func NewServerStatsHandler(opts ...Option) stats.Handler {

// NewClientStatsHandler creates an OTel stats handler for the client.
func NewClientStatsHandler(opts ...Option) stats.Handler {
if telemetry.ConfigFacade == nil || !telemetry.ConfigFacade.GetBool("telemetry.instrumentation.grpc_client", true) {
return nil
}

if telemetry.TelemetryFacade == nil {
color.Warningln("[Telemetry] Facade not initialized. gRPC client stats instrumentation is disabled.")
return nil
Expand Down
91 changes: 68 additions & 23 deletions telemetry/instrumentation/grpc/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@ import (
tracenoop "go.opentelemetry.io/otel/trace/noop"
"google.golang.org/grpc/stats"

contractsconfig "github.com/goravel/framework/contracts/config"
contractstelemetry "github.com/goravel/framework/contracts/telemetry"
mocksconfig "github.com/goravel/framework/mocks/config"
mockstelemetry "github.com/goravel/framework/mocks/telemetry"
"github.com/goravel/framework/support/color"
"github.com/goravel/framework/telemetry"
)

type HandlerTestSuite struct {
suite.Suite
originalFacade contractstelemetry.Telemetry
originalTelemetryFacade contractstelemetry.Telemetry
originalConfigFacade contractsconfig.Config
}

func (s *HandlerTestSuite) SetupTest() {
s.originalFacade = telemetry.TelemetryFacade
s.originalTelemetryFacade = telemetry.TelemetryFacade
s.originalConfigFacade = telemetry.ConfigFacade
}

func (s *HandlerTestSuite) TearDownTest() {
telemetry.TelemetryFacade = s.originalFacade
telemetry.TelemetryFacade = s.originalTelemetryFacade
telemetry.ConfigFacade = s.originalConfigFacade
}

func TestHandlerTestSuite(t *testing.T) {
Expand All @@ -36,13 +41,26 @@ func TestHandlerTestSuite(t *testing.T) {
func (s *HandlerTestSuite) TestServerStatsHandler() {
tests := []struct {
name string
setup func(*mockstelemetry.Telemetry)
setup func(*mockstelemetry.Telemetry, *mocksconfig.Config)
assert func()
}{
{
name: "returns nil and logs warning when telemetry facade is nil",
setup: func(_ *mockstelemetry.Telemetry) {
name: "returns nil immediately if config is disabled",
setup: func(_ *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_server", true).Return(false).Once()
},
assert: func() {
s.Nil(NewServerStatsHandler())
},
},
{
name: "returns nil and logs warning when config enabled but telemetry facade is nil",
setup: func(_ *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = nil

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_server", true).Return(true).Once()
},
assert: func() {
var handler stats.Handler
Expand All @@ -55,26 +73,32 @@ func (s *HandlerTestSuite) TestServerStatsHandler() {
},
},
{
name: "returns handler when telemetry facade is set",
setup: func(mockTelemetry *mockstelemetry.Telemetry) {
name: "returns handler when enabled and facade is set",
setup: func(mockTelemetry *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = mockTelemetry

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_server", true).Return(true).Once()

mockTelemetry.EXPECT().TracerProvider().Return(tracenoop.NewTracerProvider()).Once()
mockTelemetry.EXPECT().MeterProvider().Return(metricnoop.NewMeterProvider()).Once()
mockTelemetry.EXPECT().Propagator().Return(propagation.NewCompositeTextMapPropagator()).Once()

telemetry.TelemetryFacade = mockTelemetry
},
assert: func() {
s.NotNil(NewServerStatsHandler())
},
},
{
name: "accepts options",
setup: func(mockTelemetry *mockstelemetry.Telemetry) {
setup: func(mockTelemetry *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = mockTelemetry

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_server", true).Return(true).Once()

mockTelemetry.EXPECT().TracerProvider().Return(tracenoop.NewTracerProvider()).Once()
mockTelemetry.EXPECT().MeterProvider().Return(metricnoop.NewMeterProvider()).Once()
mockTelemetry.EXPECT().Propagator().Return(propagation.NewCompositeTextMapPropagator()).Once()

telemetry.TelemetryFacade = mockTelemetry
},
assert: func() {
handler := NewServerStatsHandler(
Expand All @@ -90,8 +114,9 @@ func (s *HandlerTestSuite) TestServerStatsHandler() {
for _, test := range tests {
s.Run(test.name, func() {
mockTelemetry := mockstelemetry.NewTelemetry(s.T())
mockConfig := mocksconfig.NewConfig(s.T())

test.setup(mockTelemetry)
test.setup(mockTelemetry, mockConfig)
test.assert()
})
}
Expand All @@ -100,13 +125,26 @@ func (s *HandlerTestSuite) TestServerStatsHandler() {
func (s *HandlerTestSuite) TestClientStatsHandler() {
tests := []struct {
name string
setup func(*mockstelemetry.Telemetry)
setup func(*mockstelemetry.Telemetry, *mocksconfig.Config)
assert func()
}{
{
name: "returns nil immediately if config is disabled",
setup: func(_ *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_client", true).Return(false).Once()
},
assert: func() {
s.Nil(NewClientStatsHandler())
},
},
{
name: "returns nil and logs warning when telemetry facade is nil",
setup: func(_ *mockstelemetry.Telemetry) {
setup: func(_ *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = nil

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_client", true).Return(true).Once()
},
assert: func() {
var handler stats.Handler
Expand All @@ -120,25 +158,31 @@ func (s *HandlerTestSuite) TestClientStatsHandler() {
},
{
name: "returns handler when telemetry facade is set",
setup: func(mockTelemetry *mockstelemetry.Telemetry) {
setup: func(mockTelemetry *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = mockTelemetry

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_client", true).Return(true).Once()

mockTelemetry.EXPECT().TracerProvider().Return(tracenoop.NewTracerProvider()).Once()
mockTelemetry.EXPECT().MeterProvider().Return(metricnoop.NewMeterProvider()).Once()
mockTelemetry.EXPECT().Propagator().Return(propagation.NewCompositeTextMapPropagator()).Once()

telemetry.TelemetryFacade = mockTelemetry
},
assert: func() {
s.NotNil(NewClientStatsHandler())
},
},
{
name: "accepts options",
setup: func(mockTelemetry *mockstelemetry.Telemetry) {
setup: func(mockTelemetry *mockstelemetry.Telemetry, mockConfig *mocksconfig.Config) {
telemetry.ConfigFacade = mockConfig
telemetry.TelemetryFacade = mockTelemetry

mockConfig.EXPECT().GetBool("telemetry.instrumentation.grpc_client", true).Return(true).Once()

mockTelemetry.EXPECT().TracerProvider().Return(tracenoop.NewTracerProvider()).Once()
mockTelemetry.EXPECT().MeterProvider().Return(metricnoop.NewMeterProvider()).Once()
mockTelemetry.EXPECT().Propagator().Return(propagation.NewCompositeTextMapPropagator()).Once()

telemetry.TelemetryFacade = mockTelemetry
},
assert: func() {
handler := NewClientStatsHandler(
Expand All @@ -153,8 +197,9 @@ func (s *HandlerTestSuite) TestClientStatsHandler() {
for _, test := range tests {
s.Run(test.name, func() {
mockTelemetry := mockstelemetry.NewTelemetry(s.T())
mockConfig := mocksconfig.NewConfig(s.T())

test.setup(mockTelemetry)
test.setup(mockTelemetry, mockConfig)
test.assert()
})
}
Expand Down
50 changes: 50 additions & 0 deletions telemetry/instrumentation/http/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package http

import (
"fmt"

"go.opentelemetry.io/otel/attribute"

"github.com/goravel/framework/contracts/http"
)

// Filter allows excluding specific requests from being traced.
type Filter func(ctx http.Context) bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the code, the specific requests won't be traced when the filter returns false. I think it's a bit confusing here. The specific requests should be traced when the filter returns false based on the annotation.

Image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the annotation


// SpanNameFormatter allows customizing the span name.
type SpanNameFormatter func(route string, ctx http.Context) string

// Option applies configuration to the server instrumentation.
type Option func(*ServerConfig)

// ServerConfig maps to "telemetry.instrumentation.http_server".
type ServerConfig struct {
Enabled bool `mapstructure:"enabled"`
ExcludedPaths []string `mapstructure:"excluded_paths"`
ExcludedMethods []string `mapstructure:"excluded_methods"`
Filters []Filter `mapstructure:"-"`
SpanNameFormatter SpanNameFormatter `mapstructure:"-"`
MetricAttributes []attribute.KeyValue `mapstructure:"-"`
}

func WithFilter(f Filter) Option {
return func(c *ServerConfig) {
c.Filters = append(c.Filters, f)
}
}

func WithSpanNameFormatter(f SpanNameFormatter) Option {
return func(c *ServerConfig) {
c.SpanNameFormatter = f
}
}

func WithMetricAttributes(attrs ...attribute.KeyValue) Option {
return func(c *ServerConfig) {
c.MetricAttributes = append(c.MetricAttributes, attrs...)
}
}

func defaultSpanNameFormatter(route string, ctx http.Context) string {
return fmt.Sprintf("%s %s", ctx.Request().Method(), route)
}
Loading
Loading