You've already forked opentelemetry-go
							
							
				mirror of
				https://github.com/open-telemetry/opentelemetry-go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Change Options to accept type not pointer (#2558)
* Change trace options to accept type not pointer Add benchmark to show allocation improvement. * Update CONTRIBUTING.md guidelines * Update all Option iface * Fix grammar in CONTRIBUTING
This commit is contained in:
		| @@ -228,11 +228,11 @@ all options to create a configured `config`. | ||||
|  | ||||
| ```go | ||||
| // newConfig returns an appropriately configured config. | ||||
| func newConfig([]Option) config { | ||||
| func newConfig(options ...Option) config { | ||||
| 	// Set default values for config. | ||||
| 	config := config{/* […] */} | ||||
| 	for _, option := range options { | ||||
| 		option.apply(&config) | ||||
| 		config = option.apply(config) | ||||
| 	} | ||||
| 	// Preform any validation here. | ||||
| 	return config | ||||
| @@ -253,7 +253,7 @@ To set the value of the options a `config` contains, a corresponding | ||||
|  | ||||
| ```go | ||||
| type Option interface { | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
| ``` | ||||
|  | ||||
| @@ -261,6 +261,9 @@ Having `apply` unexported makes sure that it will not be used externally. | ||||
| Moreover, the interface becomes sealed so the user cannot easily implement | ||||
| the interface on its own. | ||||
|  | ||||
| The `apply` method should return a modified version of the passed config. | ||||
| This approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap. | ||||
|  | ||||
| The name of the interface should be prefixed in the same way the | ||||
| corresponding `config` is (if at all). | ||||
|  | ||||
| @@ -283,8 +286,9 @@ func With*(…) Option { … } | ||||
| ```go | ||||
| type defaultFalseOption bool | ||||
|  | ||||
| func (o defaultFalseOption) apply(c *config) { | ||||
| func (o defaultFalseOption) apply(c config) config { | ||||
| 	c.Bool = bool(o) | ||||
|     return c | ||||
| } | ||||
|  | ||||
| // WithOption sets a T to have an option included. | ||||
| @@ -296,8 +300,9 @@ func WithOption() Option { | ||||
| ```go | ||||
| type defaultTrueOption bool | ||||
|  | ||||
| func (o defaultTrueOption) apply(c *config) { | ||||
| func (o defaultTrueOption) apply(c config) config { | ||||
| 	c.Bool = bool(o) | ||||
|     return c | ||||
| } | ||||
|  | ||||
| // WithoutOption sets a T to have Bool option excluded. | ||||
| @@ -313,8 +318,9 @@ type myTypeOption struct { | ||||
| 	MyType MyType | ||||
| } | ||||
|  | ||||
| func (o myTypeOption) apply(c *config) { | ||||
| func (o myTypeOption) apply(c config) config { | ||||
| 	c.MyType = o.MyType | ||||
|     return c | ||||
| } | ||||
|  | ||||
| // WithMyType sets T to have include MyType. | ||||
| @@ -326,16 +332,17 @@ func WithMyType(t MyType) Option { | ||||
| ##### Functional Options | ||||
|  | ||||
| ```go | ||||
| type optionFunc func(*config) | ||||
| type optionFunc func(config) config | ||||
|  | ||||
| func (fn optionFunc) apply(c *config) { | ||||
| 	fn(c) | ||||
| func (fn optionFunc) apply(c config) config { | ||||
| 	return fn(c) | ||||
| } | ||||
|  | ||||
| // WithMyType sets t as MyType. | ||||
| func WithMyType(t MyType) Option { | ||||
| 	return optionFunc(func(c *config) { | ||||
| 	return optionFunc(func(c config) config { | ||||
| 		c.MyType = t | ||||
|         return c | ||||
| 	}) | ||||
| } | ||||
| ``` | ||||
| @@ -370,12 +377,12 @@ type config struct { | ||||
|  | ||||
| // DogOption apply Dog specific options. | ||||
| type DogOption interface { | ||||
| 	applyDog(*config) | ||||
| 	applyDog(config) config | ||||
| } | ||||
|  | ||||
| // BirdOption apply Bird specific options. | ||||
| type BirdOption interface { | ||||
| 	applyBird(*config) | ||||
| 	applyBird(config) config | ||||
| } | ||||
|  | ||||
| // Option apply options for all animals. | ||||
| @@ -385,17 +392,36 @@ type Option interface { | ||||
| } | ||||
|  | ||||
| type weightOption float64 | ||||
| func (o weightOption) applyDog(c *config)  { c.Weight = float64(o) } | ||||
| func (o weightOption) applyBird(c *config) { c.Weight = float64(o) } | ||||
| func WithWeight(w float64) Option          { return weightOption(w) } | ||||
|  | ||||
| func (o weightOption) applyDog(c config) config { | ||||
| 	c.Weight = float64(o) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func (o weightOption) applyBird(c config) config { | ||||
| 	c.Weight = float64(o) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func WithWeight(w float64) Option { return weightOption(w) } | ||||
|  | ||||
| type furColorOption string | ||||
| func (o furColorOption) applyDog(c *config) { c.Color = string(o) } | ||||
| func WithFurColor(c string) DogOption       { return furColorOption(c) } | ||||
|  | ||||
| func (o furColorOption) applyDog(c config) config { | ||||
| 	c.Color = string(o) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func WithFurColor(c string) DogOption { return furColorOption(c) } | ||||
|  | ||||
| type maxAltitudeOption float64 | ||||
| func (o maxAltitudeOption) applyBird(c *config) { c.MaxAltitude = float64(o) } | ||||
| func WithMaxAltitude(a float64) BirdOption      { return maxAltitudeOption(a) } | ||||
|  | ||||
| func (o maxAltitudeOption) applyBird(c config) config { | ||||
| 	c.MaxAltitude = float64(o) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) } | ||||
|  | ||||
| func NewDog(name string, o ...DogOption) Dog    {…} | ||||
| func NewBird(name string, o ...BirdOption) Bird {…} | ||||
|   | ||||
| @@ -55,7 +55,7 @@ func (fn endpointOptionFunc) newBatchUploader() (batchUploader, error) { | ||||
| // will be used if neither are provided. | ||||
| func WithAgentEndpoint(options ...AgentEndpointOption) EndpointOption { | ||||
| 	return endpointOptionFunc(func() (batchUploader, error) { | ||||
| 		cfg := &agentEndpointConfig{ | ||||
| 		cfg := agentEndpointConfig{ | ||||
| 			agentClientUDPParams{ | ||||
| 				AttemptReconnecting: true, | ||||
| 				Host:                envOr(envAgentHost, "localhost"), | ||||
| @@ -63,7 +63,7 @@ func WithAgentEndpoint(options ...AgentEndpointOption) EndpointOption { | ||||
| 			}, | ||||
| 		} | ||||
| 		for _, opt := range options { | ||||
| 			opt.apply(cfg) | ||||
| 			cfg = opt.apply(cfg) | ||||
| 		} | ||||
|  | ||||
| 		client, err := newAgentClientUDP(cfg.agentClientUDPParams) | ||||
| @@ -76,17 +76,17 @@ func WithAgentEndpoint(options ...AgentEndpointOption) EndpointOption { | ||||
| } | ||||
|  | ||||
| type AgentEndpointOption interface { | ||||
| 	apply(*agentEndpointConfig) | ||||
| 	apply(agentEndpointConfig) agentEndpointConfig | ||||
| } | ||||
|  | ||||
| type agentEndpointConfig struct { | ||||
| 	agentClientUDPParams | ||||
| } | ||||
|  | ||||
| type agentEndpointOptionFunc func(*agentEndpointConfig) | ||||
| type agentEndpointOptionFunc func(agentEndpointConfig) agentEndpointConfig | ||||
|  | ||||
| func (fn agentEndpointOptionFunc) apply(cfg *agentEndpointConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn agentEndpointOptionFunc) apply(cfg agentEndpointConfig) agentEndpointConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithAgentHost sets a host to be used in the agent client endpoint. | ||||
| @@ -94,8 +94,9 @@ func (fn agentEndpointOptionFunc) apply(cfg *agentEndpointConfig) { | ||||
| // OTEL_EXPORTER_JAEGER_AGENT_HOST environment variable. | ||||
| // If this option is not passed and the env var is not set, "localhost" will be used by default. | ||||
| func WithAgentHost(host string) AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.Host = host | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -104,36 +105,41 @@ func WithAgentHost(host string) AgentEndpointOption { | ||||
| // OTEL_EXPORTER_JAEGER_AGENT_PORT environment variable. | ||||
| // If this option is not passed and the env var is not set, "6831" will be used by default. | ||||
| func WithAgentPort(port string) AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.Port = port | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithLogger sets a logger to be used by agent client. | ||||
| func WithLogger(logger *log.Logger) AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.Logger = logger | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithDisableAttemptReconnecting sets option to disable reconnecting udp client. | ||||
| func WithDisableAttemptReconnecting() AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.AttemptReconnecting = false | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithAttemptReconnectingInterval sets the interval between attempts to re resolve agent endpoint. | ||||
| func WithAttemptReconnectingInterval(interval time.Duration) AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.AttemptReconnectInterval = interval | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithMaxPacketSize sets the maximum UDP packet size for transport to the Jaeger agent. | ||||
| func WithMaxPacketSize(size int) AgentEndpointOption { | ||||
| 	return agentEndpointOptionFunc(func(o *agentEndpointConfig) { | ||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { | ||||
| 		o.MaxPacketSize = size | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -149,7 +155,7 @@ func WithMaxPacketSize(size int) AgentEndpointOption { | ||||
| // If neither values are provided for the username or the password, they will not be set since there is no default. | ||||
| func WithCollectorEndpoint(options ...CollectorEndpointOption) EndpointOption { | ||||
| 	return endpointOptionFunc(func() (batchUploader, error) { | ||||
| 		cfg := &collectorEndpointConfig{ | ||||
| 		cfg := collectorEndpointConfig{ | ||||
| 			endpoint:   envOr(envEndpoint, "http://localhost:14268/api/traces"), | ||||
| 			username:   envOr(envUser, ""), | ||||
| 			password:   envOr(envPassword, ""), | ||||
| @@ -157,7 +163,7 @@ func WithCollectorEndpoint(options ...CollectorEndpointOption) EndpointOption { | ||||
| 		} | ||||
|  | ||||
| 		for _, opt := range options { | ||||
| 			opt.apply(cfg) | ||||
| 			cfg = opt.apply(cfg) | ||||
| 		} | ||||
|  | ||||
| 		return &collectorUploader{ | ||||
| @@ -170,7 +176,7 @@ func WithCollectorEndpoint(options ...CollectorEndpointOption) EndpointOption { | ||||
| } | ||||
|  | ||||
| type CollectorEndpointOption interface { | ||||
| 	apply(*collectorEndpointConfig) | ||||
| 	apply(collectorEndpointConfig) collectorEndpointConfig | ||||
| } | ||||
|  | ||||
| type collectorEndpointConfig struct { | ||||
| @@ -187,10 +193,10 @@ type collectorEndpointConfig struct { | ||||
| 	httpClient *http.Client | ||||
| } | ||||
|  | ||||
| type collectorEndpointOptionFunc func(*collectorEndpointConfig) | ||||
| type collectorEndpointOptionFunc func(collectorEndpointConfig) collectorEndpointConfig | ||||
|  | ||||
| func (fn collectorEndpointOptionFunc) apply(cfg *collectorEndpointConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn collectorEndpointOptionFunc) apply(cfg collectorEndpointConfig) collectorEndpointConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithEndpoint is the URL for the Jaeger collector that spans are sent to. | ||||
| @@ -199,8 +205,9 @@ func (fn collectorEndpointOptionFunc) apply(cfg *collectorEndpointConfig) { | ||||
| // If this option is not passed and the environment variable is not set, | ||||
| // "http://localhost:14268/api/traces" will be used by default. | ||||
| func WithEndpoint(endpoint string) CollectorEndpointOption { | ||||
| 	return collectorEndpointOptionFunc(func(o *collectorEndpointConfig) { | ||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { | ||||
| 		o.endpoint = endpoint | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -209,8 +216,9 @@ func WithEndpoint(endpoint string) CollectorEndpointOption { | ||||
| // OTEL_EXPORTER_JAEGER_USER environment variable. | ||||
| // If this option is not passed and the environment variable is not set, no username will be set. | ||||
| func WithUsername(username string) CollectorEndpointOption { | ||||
| 	return collectorEndpointOptionFunc(func(o *collectorEndpointConfig) { | ||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { | ||||
| 		o.username = username | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -219,15 +227,17 @@ func WithUsername(username string) CollectorEndpointOption { | ||||
| // OTEL_EXPORTER_JAEGER_PASSWORD environment variable. | ||||
| // If this option is not passed and the environment variable is not set, no password will be set. | ||||
| func WithPassword(password string) CollectorEndpointOption { | ||||
| 	return collectorEndpointOptionFunc(func(o *collectorEndpointConfig) { | ||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { | ||||
| 		o.password = password | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithHTTPClient sets the http client to be used to make request to the collector endpoint. | ||||
| func WithHTTPClient(client *http.Client) CollectorEndpointOption { | ||||
| 	return collectorEndpointOptionFunc(func(o *collectorEndpointConfig) { | ||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { | ||||
| 		o.httpClient = client | ||||
| 		return o | ||||
| 	}) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -120,7 +120,7 @@ func NewUnstarted(client Client, opts ...Option) *Exporter { | ||||
| 	} | ||||
|  | ||||
| 	for _, opt := range opts { | ||||
| 		opt.apply(&cfg) | ||||
| 		cfg = opt.apply(cfg) | ||||
| 	} | ||||
|  | ||||
| 	e := &Exporter{ | ||||
|   | ||||
| @@ -33,12 +33,12 @@ var DefaultEnvOptionsReader = EnvOptionsReader{ | ||||
| 	ReadFile: ioutil.ReadFile, | ||||
| } | ||||
|  | ||||
| func ApplyGRPCEnvConfigs(cfg *Config) { | ||||
| 	DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) | ||||
| func ApplyGRPCEnvConfigs(cfg Config) Config { | ||||
| 	return DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) | ||||
| } | ||||
|  | ||||
| func ApplyHTTPEnvConfigs(cfg *Config) { | ||||
| 	DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) | ||||
| func ApplyHTTPEnvConfigs(cfg Config) Config { | ||||
| 	return DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) | ||||
| } | ||||
|  | ||||
| type EnvOptionsReader struct { | ||||
| @@ -46,18 +46,20 @@ type EnvOptionsReader struct { | ||||
| 	ReadFile func(filename string) ([]byte, error) | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg *Config) { | ||||
| func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg Config) Config { | ||||
| 	opts := e.GetOptionsFromEnv() | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyHTTPOption(cfg) | ||||
| 		cfg = opt.ApplyHTTPOption(cfg) | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg *Config) { | ||||
| func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg Config) Config { | ||||
| 	opts := e.GetOptionsFromEnv() | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyGRPCOption(cfg) | ||||
| 		cfg = opt.ApplyGRPCOption(cfg) | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| @@ -74,7 +76,7 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 			} else { | ||||
| 				opts = append(opts, WithSecure()) | ||||
| 			} | ||||
| 			opts = append(opts, newSplitOption(func(cfg *Config) { | ||||
| 			opts = append(opts, newSplitOption(func(cfg Config) Config { | ||||
| 				cfg.Metrics.Endpoint = u.Host | ||||
| 				// For endpoint URLs for OTLP/HTTP per-signal variables, the | ||||
| 				// URL MUST be used as-is without any modification. The only | ||||
| @@ -85,10 +87,12 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 					path = "/" | ||||
| 				} | ||||
| 				cfg.Metrics.URLPath = path | ||||
| 			}, func(cfg *Config) { | ||||
| 				return cfg | ||||
| 			}, func(cfg Config) Config { | ||||
| 				// For OTLP/gRPC endpoints, this is the target to which the | ||||
| 				// exporter is going to send telemetry. | ||||
| 				cfg.Metrics.Endpoint = path.Join(u.Host, u.Path) | ||||
| 				return cfg | ||||
| 			})) | ||||
| 		} | ||||
| 	} else if v, ok = e.getEnvValue("ENDPOINT"); ok { | ||||
| @@ -101,16 +105,18 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 			} else { | ||||
| 				opts = append(opts, WithSecure()) | ||||
| 			} | ||||
| 			opts = append(opts, newSplitOption(func(cfg *Config) { | ||||
| 			opts = append(opts, newSplitOption(func(cfg Config) Config { | ||||
| 				cfg.Metrics.Endpoint = u.Host | ||||
| 				// For OTLP/HTTP endpoint URLs without a per-signal | ||||
| 				// configuration, the passed endpoint is used as a base URL | ||||
| 				// and the signals are sent to these paths relative to that. | ||||
| 				cfg.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) | ||||
| 			}, func(cfg *Config) { | ||||
| 				return cfg | ||||
| 			}, func(cfg Config) Config { | ||||
| 				// For OTLP/gRPC endpoints, this is the target to which the | ||||
| 				// exporter is going to send telemetry. | ||||
| 				cfg.Metrics.Endpoint = path.Join(u.Host, u.Path) | ||||
| 				return cfg | ||||
| 			})) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -90,9 +90,9 @@ func NewDefaultConfig() Config { | ||||
| // any unset setting using the default gRPC config values. | ||||
| func NewGRPCConfig(opts ...GRPCOption) Config { | ||||
| 	cfg := NewDefaultConfig() | ||||
| 	ApplyGRPCEnvConfigs(&cfg) | ||||
| 	cfg = ApplyGRPCEnvConfigs(cfg) | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyGRPCOption(&cfg) | ||||
| 		cfg = opt.ApplyGRPCOption(cfg) | ||||
| 	} | ||||
|  | ||||
| 	if cfg.ServiceConfig != "" { | ||||
| @@ -129,8 +129,8 @@ func NewGRPCConfig(opts ...GRPCOption) Config { | ||||
| type ( | ||||
| 	// GenericOption applies an option to the HTTP or gRPC driver. | ||||
| 	GenericOption interface { | ||||
| 		ApplyHTTPOption(*Config) | ||||
| 		ApplyGRPCOption(*Config) | ||||
| 		ApplyHTTPOption(Config) Config | ||||
| 		ApplyGRPCOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -140,7 +140,7 @@ type ( | ||||
|  | ||||
| 	// HTTPOption applies an option to the HTTP driver. | ||||
| 	HTTPOption interface { | ||||
| 		ApplyHTTPOption(*Config) | ||||
| 		ApplyHTTPOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -150,7 +150,7 @@ type ( | ||||
|  | ||||
| 	// GRPCOption applies an option to the gRPC driver. | ||||
| 	GRPCOption interface { | ||||
| 		ApplyGRPCOption(*Config) | ||||
| 		ApplyGRPCOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -162,128 +162,138 @@ type ( | ||||
| // genericOption is an option that applies the same logic | ||||
| // for both gRPC and HTTP. | ||||
| type genericOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (g *genericOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	g.fn(cfg) | ||||
| func (g *genericOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return g.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (g *genericOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	g.fn(cfg) | ||||
| func (g *genericOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return g.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (genericOption) private() {} | ||||
|  | ||||
| func newGenericOption(fn func(cfg *Config)) GenericOption { | ||||
| func newGenericOption(fn func(cfg Config) Config) GenericOption { | ||||
| 	return &genericOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // splitOption is an option that applies different logics | ||||
| // for gRPC and HTTP. | ||||
| type splitOption struct { | ||||
| 	httpFn func(*Config) | ||||
| 	grpcFn func(*Config) | ||||
| 	httpFn func(Config) Config | ||||
| 	grpcFn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (g *splitOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	g.grpcFn(cfg) | ||||
| func (g *splitOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return g.grpcFn(cfg) | ||||
| } | ||||
|  | ||||
| func (g *splitOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	g.httpFn(cfg) | ||||
| func (g *splitOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return g.httpFn(cfg) | ||||
| } | ||||
|  | ||||
| func (splitOption) private() {} | ||||
|  | ||||
| func newSplitOption(httpFn func(cfg *Config), grpcFn func(cfg *Config)) GenericOption { | ||||
| func newSplitOption(httpFn func(cfg Config) Config, grpcFn func(cfg Config) Config) GenericOption { | ||||
| 	return &splitOption{httpFn: httpFn, grpcFn: grpcFn} | ||||
| } | ||||
|  | ||||
| // httpOption is an option that is only applied to the HTTP driver. | ||||
| type httpOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (h *httpOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	h.fn(cfg) | ||||
| func (h *httpOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return h.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (httpOption) private() {} | ||||
|  | ||||
| func NewHTTPOption(fn func(cfg *Config)) HTTPOption { | ||||
| func NewHTTPOption(fn func(cfg Config) Config) HTTPOption { | ||||
| 	return &httpOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // grpcOption is an option that is only applied to the gRPC driver. | ||||
| type grpcOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (h *grpcOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	h.fn(cfg) | ||||
| func (h *grpcOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return h.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (grpcOption) private() {} | ||||
|  | ||||
| func NewGRPCOption(fn func(cfg *Config)) GRPCOption { | ||||
| func NewGRPCOption(fn func(cfg Config) Config) GRPCOption { | ||||
| 	return &grpcOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // Generic Options | ||||
|  | ||||
| func WithEndpoint(endpoint string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Endpoint = endpoint | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithCompression(compression Compression) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Compression = compression | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithURLPath(urlPath string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.URLPath = urlPath | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithRetry(rc retry.Config) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.RetryConfig = rc | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithTLSClientConfig(tlsCfg *tls.Config) GenericOption { | ||||
| 	return newSplitOption(func(cfg *Config) { | ||||
| 	return newSplitOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.TLSCfg = tlsCfg.Clone() | ||||
| 	}, func(cfg *Config) { | ||||
| 		return cfg | ||||
| 	}, func(cfg Config) Config { | ||||
| 		cfg.Metrics.GRPCCredentials = credentials.NewTLS(tlsCfg) | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithInsecure() GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Insecure = true | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithSecure() GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Insecure = false | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithHeaders(headers map[string]string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Headers = headers | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithTimeout(duration time.Duration) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Metrics.Timeout = duration | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -387,9 +387,9 @@ func TestConfigs(t *testing.T) { | ||||
|  | ||||
| 			// Tests Generic options as HTTP Options | ||||
| 			cfg := otlpconfig.NewDefaultConfig() | ||||
| 			otlpconfig.ApplyHTTPEnvConfigs(&cfg) | ||||
| 			cfg = otlpconfig.ApplyHTTPEnvConfigs(cfg) | ||||
| 			for _, opt := range tt.opts { | ||||
| 				opt.ApplyHTTPOption(&cfg) | ||||
| 				cfg = opt.ApplyHTTPOption(cfg) | ||||
| 			} | ||||
| 			tt.asserts(t, &cfg, false) | ||||
|  | ||||
|   | ||||
| @@ -18,13 +18,13 @@ import "go.opentelemetry.io/otel/sdk/metric/export/aggregation" | ||||
|  | ||||
| // Option are setting options passed to an Exporter on creation. | ||||
| type Option interface { | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| type exporterOptionFunc func(*config) | ||||
| type exporterOptionFunc func(config) config | ||||
|  | ||||
| func (fn exporterOptionFunc) apply(cfg *config) { | ||||
| 	fn(cfg) | ||||
| func (fn exporterOptionFunc) apply(cfg config) config { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| type config struct { | ||||
| @@ -36,7 +36,8 @@ type config struct { | ||||
| // aggregation). If not specified otherwise, exporter will use a | ||||
| // cumulative temporality selector. | ||||
| func WithMetricAggregationTemporalitySelector(selector aggregation.TemporalitySelector) Option { | ||||
| 	return exporterOptionFunc(func(cfg *config) { | ||||
| 	return exporterOptionFunc(func(cfg config) config { | ||||
| 		cfg.temporalitySelector = selector | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ import ( | ||||
|  | ||||
| // Option applies an option to the gRPC driver. | ||||
| type Option interface { | ||||
| 	applyGRPCOption(*otlpconfig.Config) | ||||
| 	applyGRPCOption(otlpconfig.Config) otlpconfig.Config | ||||
| } | ||||
|  | ||||
| func asGRPCOptions(opts []Option) []otlpconfig.GRPCOption { | ||||
| @@ -50,8 +50,8 @@ type wrappedOption struct { | ||||
| 	otlpconfig.GRPCOption | ||||
| } | ||||
|  | ||||
| func (w wrappedOption) applyGRPCOption(cfg *otlpconfig.Config) { | ||||
| 	w.ApplyGRPCOption(cfg) | ||||
| func (w wrappedOption) applyGRPCOption(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 	return w.ApplyGRPCOption(cfg) | ||||
| } | ||||
|  | ||||
| // WithInsecure disables client transport security for the exporter's gRPC | ||||
| @@ -77,8 +77,9 @@ func WithEndpoint(endpoint string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithReconnectionPeriod(rp time.Duration) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.ReconnectionPeriod = rp | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -117,8 +118,9 @@ func WithHeaders(headers map[string]string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithTLSCredentials(creds credentials.TransportCredentials) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.Metrics.GRPCCredentials = creds | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -126,8 +128,9 @@ func WithTLSCredentials(creds credentials.TransportCredentials) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithServiceConfig(serviceConfig string) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.ServiceConfig = serviceConfig | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -138,8 +141,9 @@ func WithServiceConfig(serviceConfig string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithDialOption(opts ...grpc.DialOption) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.DialOptions = opts | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -152,8 +156,9 @@ func WithDialOption(opts ...grpc.DialOption) Option { | ||||
| // It is the callers responsibility to close the passed conn. The client | ||||
| // Shutdown method will not close this connection. | ||||
| func WithGRPCConn(conn *grpc.ClientConn) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.GRPCConn = conn | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -78,9 +78,9 @@ type client struct { | ||||
| // NewClient creates a new HTTP metric client. | ||||
| func NewClient(opts ...Option) otlpmetric.Client { | ||||
| 	cfg := otlpconfig.NewDefaultConfig() | ||||
| 	otlpconfig.ApplyHTTPEnvConfigs(&cfg) | ||||
| 	cfg = otlpconfig.ApplyHTTPEnvConfigs(cfg) | ||||
| 	for _, opt := range opts { | ||||
| 		opt.applyHTTPOption(&cfg) | ||||
| 		cfg = opt.applyHTTPOption(cfg) | ||||
| 	} | ||||
|  | ||||
| 	for pathPtr, defaultPath := range map[*string]string{ | ||||
|   | ||||
| @@ -37,7 +37,7 @@ const ( | ||||
|  | ||||
| // Option applies an option to the HTTP client. | ||||
| type Option interface { | ||||
| 	applyHTTPOption(*otlpconfig.Config) | ||||
| 	applyHTTPOption(otlpconfig.Config) otlpconfig.Config | ||||
| } | ||||
|  | ||||
| // RetryConfig defines configuration for retrying batches in case of export | ||||
| @@ -48,8 +48,8 @@ type wrappedOption struct { | ||||
| 	otlpconfig.HTTPOption | ||||
| } | ||||
|  | ||||
| func (w wrappedOption) applyHTTPOption(cfg *otlpconfig.Config) { | ||||
| 	w.ApplyHTTPOption(cfg) | ||||
| func (w wrappedOption) applyHTTPOption(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 	return w.ApplyHTTPOption(cfg) | ||||
| } | ||||
|  | ||||
| // WithEndpoint allows one to set the address of the collector | ||||
| @@ -83,7 +83,7 @@ func WithMaxAttempts(maxAttempts int) Option { | ||||
| 		maxAttempts = 5 | ||||
| 	} | ||||
| 	return wrappedOption{ | ||||
| 		otlpconfig.NewHTTPOption(func(cfg *otlpconfig.Config) { | ||||
| 		otlpconfig.NewHTTPOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 			cfg.RetryConfig.Enabled = true | ||||
|  | ||||
| 			var ( | ||||
| @@ -104,7 +104,7 @@ func WithMaxAttempts(maxAttempts int) Option { | ||||
| 			attempts := int64(maxE+init) / int64(maxI) | ||||
|  | ||||
| 			if int64(maxAttempts) == attempts { | ||||
| 				return | ||||
| 				return cfg | ||||
| 			} | ||||
|  | ||||
| 			maxE = time.Duration(int64(maxAttempts)*int64(maxI)) - init | ||||
| @@ -112,6 +112,8 @@ func WithMaxAttempts(maxAttempts int) Option { | ||||
| 			cfg.RetryConfig.InitialInterval = init | ||||
| 			cfg.RetryConfig.MaxInterval = maxI | ||||
| 			cfg.RetryConfig.MaxElapsedTime = maxE | ||||
|  | ||||
| 			return cfg | ||||
| 		}), | ||||
| 	} | ||||
| } | ||||
| @@ -126,7 +128,7 @@ func WithBackoff(duration time.Duration) Option { | ||||
| 		duration = 300 * time.Millisecond | ||||
| 	} | ||||
| 	return wrappedOption{ | ||||
| 		otlpconfig.NewHTTPOption(func(cfg *otlpconfig.Config) { | ||||
| 		otlpconfig.NewHTTPOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 			cfg.RetryConfig.Enabled = true | ||||
| 			cfg.RetryConfig.MaxInterval = duration | ||||
| 			if cfg.RetryConfig.InitialInterval == 0 { | ||||
| @@ -135,6 +137,7 @@ func WithBackoff(duration time.Duration) Option { | ||||
| 			if cfg.RetryConfig.MaxElapsedTime == 0 { | ||||
| 				cfg.RetryConfig.MaxElapsedTime = retry.DefaultConfig.MaxElapsedTime | ||||
| 			} | ||||
| 			return cfg | ||||
| 		}), | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -33,12 +33,12 @@ var DefaultEnvOptionsReader = EnvOptionsReader{ | ||||
| 	ReadFile: ioutil.ReadFile, | ||||
| } | ||||
|  | ||||
| func ApplyGRPCEnvConfigs(cfg *Config) { | ||||
| 	DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) | ||||
| func ApplyGRPCEnvConfigs(cfg Config) Config { | ||||
| 	return DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) | ||||
| } | ||||
|  | ||||
| func ApplyHTTPEnvConfigs(cfg *Config) { | ||||
| 	DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) | ||||
| func ApplyHTTPEnvConfigs(cfg Config) Config { | ||||
| 	return DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) | ||||
| } | ||||
|  | ||||
| type EnvOptionsReader struct { | ||||
| @@ -46,18 +46,20 @@ type EnvOptionsReader struct { | ||||
| 	ReadFile func(filename string) ([]byte, error) | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg *Config) { | ||||
| func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg Config) Config { | ||||
| 	opts := e.GetOptionsFromEnv() | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyHTTPOption(cfg) | ||||
| 		cfg = opt.ApplyHTTPOption(cfg) | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg *Config) { | ||||
| func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg Config) Config { | ||||
| 	opts := e.GetOptionsFromEnv() | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyGRPCOption(cfg) | ||||
| 		cfg = opt.ApplyGRPCOption(cfg) | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| @@ -74,7 +76,7 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 			} else { | ||||
| 				opts = append(opts, WithSecure()) | ||||
| 			} | ||||
| 			opts = append(opts, newSplitOption(func(cfg *Config) { | ||||
| 			opts = append(opts, newSplitOption(func(cfg Config) Config { | ||||
| 				cfg.Traces.Endpoint = u.Host | ||||
| 				// For endpoint URLs for OTLP/HTTP per-signal variables, the | ||||
| 				// URL MUST be used as-is without any modification. The only | ||||
| @@ -85,10 +87,12 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 					path = "/" | ||||
| 				} | ||||
| 				cfg.Traces.URLPath = path | ||||
| 			}, func(cfg *Config) { | ||||
| 				return cfg | ||||
| 			}, func(cfg Config) Config { | ||||
| 				// For OTLP/gRPC endpoints, this is the target to which the | ||||
| 				// exporter is going to send telemetry. | ||||
| 				cfg.Traces.Endpoint = path.Join(u.Host, u.Path) | ||||
| 				return cfg | ||||
| 			})) | ||||
| 		} | ||||
| 	} else if v, ok = e.getEnvValue("ENDPOINT"); ok { | ||||
| @@ -101,16 +105,18 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { | ||||
| 			} else { | ||||
| 				opts = append(opts, WithSecure()) | ||||
| 			} | ||||
| 			opts = append(opts, newSplitOption(func(cfg *Config) { | ||||
| 			opts = append(opts, newSplitOption(func(cfg Config) Config { | ||||
| 				cfg.Traces.Endpoint = u.Host | ||||
| 				// For OTLP/HTTP endpoint URLs without a per-signal | ||||
| 				// configuration, the passed endpoint is used as a base URL | ||||
| 				// and the signals are sent to these paths relative to that. | ||||
| 				cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) | ||||
| 			}, func(cfg *Config) { | ||||
| 				return cfg | ||||
| 			}, func(cfg Config) Config { | ||||
| 				// For OTLP/gRPC endpoints, this is the target to which the | ||||
| 				// exporter is going to send telemetry. | ||||
| 				cfg.Traces.Endpoint = path.Join(u.Host, u.Path) | ||||
| 				return cfg | ||||
| 			})) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -83,9 +83,9 @@ func NewDefaultConfig() Config { | ||||
| // any unset setting using the default gRPC config values. | ||||
| func NewGRPCConfig(opts ...GRPCOption) Config { | ||||
| 	cfg := NewDefaultConfig() | ||||
| 	ApplyGRPCEnvConfigs(&cfg) | ||||
| 	cfg = ApplyGRPCEnvConfigs(cfg) | ||||
| 	for _, opt := range opts { | ||||
| 		opt.ApplyGRPCOption(&cfg) | ||||
| 		cfg = opt.ApplyGRPCOption(cfg) | ||||
| 	} | ||||
|  | ||||
| 	if cfg.ServiceConfig != "" { | ||||
| @@ -122,8 +122,8 @@ func NewGRPCConfig(opts ...GRPCOption) Config { | ||||
| type ( | ||||
| 	// GenericOption applies an option to the HTTP or gRPC driver. | ||||
| 	GenericOption interface { | ||||
| 		ApplyHTTPOption(*Config) | ||||
| 		ApplyGRPCOption(*Config) | ||||
| 		ApplyHTTPOption(Config) Config | ||||
| 		ApplyGRPCOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -133,7 +133,7 @@ type ( | ||||
|  | ||||
| 	// HTTPOption applies an option to the HTTP driver. | ||||
| 	HTTPOption interface { | ||||
| 		ApplyHTTPOption(*Config) | ||||
| 		ApplyHTTPOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -143,7 +143,7 @@ type ( | ||||
|  | ||||
| 	// GRPCOption applies an option to the gRPC driver. | ||||
| 	GRPCOption interface { | ||||
| 		ApplyGRPCOption(*Config) | ||||
| 		ApplyGRPCOption(Config) Config | ||||
|  | ||||
| 		// A private method to prevent users implementing the | ||||
| 		// interface and so future additions to it will not | ||||
| @@ -155,128 +155,138 @@ type ( | ||||
| // genericOption is an option that applies the same logic | ||||
| // for both gRPC and HTTP. | ||||
| type genericOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (g *genericOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	g.fn(cfg) | ||||
| func (g *genericOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return g.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (g *genericOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	g.fn(cfg) | ||||
| func (g *genericOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return g.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (genericOption) private() {} | ||||
|  | ||||
| func newGenericOption(fn func(cfg *Config)) GenericOption { | ||||
| func newGenericOption(fn func(cfg Config) Config) GenericOption { | ||||
| 	return &genericOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // splitOption is an option that applies different logics | ||||
| // for gRPC and HTTP. | ||||
| type splitOption struct { | ||||
| 	httpFn func(*Config) | ||||
| 	grpcFn func(*Config) | ||||
| 	httpFn func(Config) Config | ||||
| 	grpcFn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (g *splitOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	g.grpcFn(cfg) | ||||
| func (g *splitOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return g.grpcFn(cfg) | ||||
| } | ||||
|  | ||||
| func (g *splitOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	g.httpFn(cfg) | ||||
| func (g *splitOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return g.httpFn(cfg) | ||||
| } | ||||
|  | ||||
| func (splitOption) private() {} | ||||
|  | ||||
| func newSplitOption(httpFn func(cfg *Config), grpcFn func(cfg *Config)) GenericOption { | ||||
| func newSplitOption(httpFn func(cfg Config) Config, grpcFn func(cfg Config) Config) GenericOption { | ||||
| 	return &splitOption{httpFn: httpFn, grpcFn: grpcFn} | ||||
| } | ||||
|  | ||||
| // httpOption is an option that is only applied to the HTTP driver. | ||||
| type httpOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (h *httpOption) ApplyHTTPOption(cfg *Config) { | ||||
| 	h.fn(cfg) | ||||
| func (h *httpOption) ApplyHTTPOption(cfg Config) Config { | ||||
| 	return h.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (httpOption) private() {} | ||||
|  | ||||
| func NewHTTPOption(fn func(cfg *Config)) HTTPOption { | ||||
| func NewHTTPOption(fn func(cfg Config) Config) HTTPOption { | ||||
| 	return &httpOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // grpcOption is an option that is only applied to the gRPC driver. | ||||
| type grpcOption struct { | ||||
| 	fn func(*Config) | ||||
| 	fn func(Config) Config | ||||
| } | ||||
|  | ||||
| func (h *grpcOption) ApplyGRPCOption(cfg *Config) { | ||||
| 	h.fn(cfg) | ||||
| func (h *grpcOption) ApplyGRPCOption(cfg Config) Config { | ||||
| 	return h.fn(cfg) | ||||
| } | ||||
|  | ||||
| func (grpcOption) private() {} | ||||
|  | ||||
| func NewGRPCOption(fn func(cfg *Config)) GRPCOption { | ||||
| func NewGRPCOption(fn func(cfg Config) Config) GRPCOption { | ||||
| 	return &grpcOption{fn: fn} | ||||
| } | ||||
|  | ||||
| // Generic Options | ||||
|  | ||||
| func WithEndpoint(endpoint string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Endpoint = endpoint | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithCompression(compression Compression) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Compression = compression | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithURLPath(urlPath string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.URLPath = urlPath | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithRetry(rc retry.Config) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.RetryConfig = rc | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithTLSClientConfig(tlsCfg *tls.Config) GenericOption { | ||||
| 	return newSplitOption(func(cfg *Config) { | ||||
| 	return newSplitOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.TLSCfg = tlsCfg.Clone() | ||||
| 	}, func(cfg *Config) { | ||||
| 		return cfg | ||||
| 	}, func(cfg Config) Config { | ||||
| 		cfg.Traces.GRPCCredentials = credentials.NewTLS(tlsCfg) | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithInsecure() GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Insecure = true | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithSecure() GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Insecure = false | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithHeaders(headers map[string]string) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Headers = headers | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func WithTimeout(duration time.Duration) GenericOption { | ||||
| 	return newGenericOption(func(cfg *Config) { | ||||
| 	return newGenericOption(func(cfg Config) Config { | ||||
| 		cfg.Traces.Timeout = duration | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -385,9 +385,9 @@ func TestConfigs(t *testing.T) { | ||||
|  | ||||
| 			// Tests Generic options as HTTP Options | ||||
| 			cfg := otlpconfig.NewDefaultConfig() | ||||
| 			otlpconfig.ApplyHTTPEnvConfigs(&cfg) | ||||
| 			cfg = otlpconfig.ApplyHTTPEnvConfigs(cfg) | ||||
| 			for _, opt := range tt.opts { | ||||
| 				opt.ApplyHTTPOption(&cfg) | ||||
| 				cfg = opt.ApplyHTTPOption(cfg) | ||||
| 			} | ||||
| 			tt.asserts(t, &cfg, false) | ||||
|  | ||||
|   | ||||
| @@ -28,7 +28,7 @@ import ( | ||||
|  | ||||
| // Option applies an option to the gRPC driver. | ||||
| type Option interface { | ||||
| 	applyGRPCOption(*otlpconfig.Config) | ||||
| 	applyGRPCOption(otlpconfig.Config) otlpconfig.Config | ||||
| } | ||||
|  | ||||
| func asGRPCOptions(opts []Option) []otlpconfig.GRPCOption { | ||||
| @@ -50,8 +50,8 @@ type wrappedOption struct { | ||||
| 	otlpconfig.GRPCOption | ||||
| } | ||||
|  | ||||
| func (w wrappedOption) applyGRPCOption(cfg *otlpconfig.Config) { | ||||
| 	w.ApplyGRPCOption(cfg) | ||||
| func (w wrappedOption) applyGRPCOption(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 	return w.ApplyGRPCOption(cfg) | ||||
| } | ||||
|  | ||||
| // WithInsecure disables client transport security for the exporter's gRPC | ||||
| @@ -77,8 +77,9 @@ func WithEndpoint(endpoint string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithReconnectionPeriod(rp time.Duration) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.ReconnectionPeriod = rp | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -117,8 +118,9 @@ func WithHeaders(headers map[string]string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithTLSCredentials(creds credentials.TransportCredentials) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.Traces.GRPCCredentials = creds | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -126,8 +128,9 @@ func WithTLSCredentials(creds credentials.TransportCredentials) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithServiceConfig(serviceConfig string) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.ServiceConfig = serviceConfig | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -138,8 +141,9 @@ func WithServiceConfig(serviceConfig string) Option { | ||||
| // | ||||
| // This option has no effect if WithGRPCConn is used. | ||||
| func WithDialOption(opts ...grpc.DialOption) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.DialOptions = opts | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
| @@ -152,8 +156,9 @@ func WithDialOption(opts ...grpc.DialOption) Option { | ||||
| // It is the callers responsibility to close the passed conn. The client | ||||
| // Shutdown method will not close this connection. | ||||
| func WithGRPCConn(conn *grpc.ClientConn) Option { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { | ||||
| 	return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 		cfg.GRPCConn = conn | ||||
| 		return cfg | ||||
| 	})} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -80,9 +80,9 @@ var _ otlptrace.Client = (*client)(nil) | ||||
| // NewClient creates a new HTTP trace client. | ||||
| func NewClient(opts ...Option) otlptrace.Client { | ||||
| 	cfg := otlpconfig.NewDefaultConfig() | ||||
| 	otlpconfig.ApplyHTTPEnvConfigs(&cfg) | ||||
| 	cfg = otlpconfig.ApplyHTTPEnvConfigs(cfg) | ||||
| 	for _, opt := range opts { | ||||
| 		opt.applyHTTPOption(&cfg) | ||||
| 		cfg = opt.applyHTTPOption(cfg) | ||||
| 	} | ||||
|  | ||||
| 	for pathPtr, defaultPath := range map[*string]string{ | ||||
|   | ||||
| @@ -37,7 +37,7 @@ const ( | ||||
|  | ||||
| // Option applies an option to the HTTP client. | ||||
| type Option interface { | ||||
| 	applyHTTPOption(*otlpconfig.Config) | ||||
| 	applyHTTPOption(otlpconfig.Config) otlpconfig.Config | ||||
| } | ||||
|  | ||||
| // RetryConfig defines configuration for retrying batches in case of export | ||||
| @@ -48,8 +48,8 @@ type wrappedOption struct { | ||||
| 	otlpconfig.HTTPOption | ||||
| } | ||||
|  | ||||
| func (w wrappedOption) applyHTTPOption(cfg *otlpconfig.Config) { | ||||
| 	w.ApplyHTTPOption(cfg) | ||||
| func (w wrappedOption) applyHTTPOption(cfg otlpconfig.Config) otlpconfig.Config { | ||||
| 	return w.ApplyHTTPOption(cfg) | ||||
| } | ||||
|  | ||||
| // WithEndpoint allows one to set the address of the collector | ||||
|   | ||||
| @@ -54,7 +54,7 @@ func newConfig(options ...Option) (config, error) { | ||||
| 		LabelEncoder: defaultLabelEncoder, | ||||
| 	} | ||||
| 	for _, opt := range options { | ||||
| 		opt.apply(&cfg) | ||||
| 		cfg = opt.apply(cfg) | ||||
|  | ||||
| 	} | ||||
| 	return cfg, nil | ||||
| @@ -62,7 +62,7 @@ func newConfig(options ...Option) (config, error) { | ||||
|  | ||||
| // Option sets the value of an option for a Config. | ||||
| type Option interface { | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| // WithWriter sets the export stream destination. | ||||
| @@ -74,8 +74,9 @@ type writerOption struct { | ||||
| 	W io.Writer | ||||
| } | ||||
|  | ||||
| func (o writerOption) apply(cfg *config) { | ||||
| func (o writerOption) apply(cfg config) config { | ||||
| 	cfg.Writer = o.W | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithPrettyPrint sets the export stream format to use JSON. | ||||
| @@ -85,8 +86,9 @@ func WithPrettyPrint() Option { | ||||
|  | ||||
| type prettyPrintOption bool | ||||
|  | ||||
| func (o prettyPrintOption) apply(cfg *config) { | ||||
| func (o prettyPrintOption) apply(cfg config) config { | ||||
| 	cfg.PrettyPrint = bool(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithoutTimestamps sets the export stream to not include timestamps. | ||||
| @@ -96,8 +98,9 @@ func WithoutTimestamps() Option { | ||||
|  | ||||
| type timestampsOption bool | ||||
|  | ||||
| func (o timestampsOption) apply(cfg *config) { | ||||
| func (o timestampsOption) apply(cfg config) config { | ||||
| 	cfg.Timestamps = bool(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithLabelEncoder sets the label encoder used in export. | ||||
| @@ -109,6 +112,7 @@ type labelEncoderOption struct { | ||||
| 	LabelEncoder attribute.Encoder | ||||
| } | ||||
|  | ||||
| func (o labelEncoderOption) apply(cfg *config) { | ||||
| func (o labelEncoderOption) apply(cfg config) config { | ||||
| 	cfg.LabelEncoder = o.LabelEncoder | ||||
| 	return cfg | ||||
| } | ||||
|   | ||||
| @@ -47,7 +47,7 @@ func newConfig(options ...Option) (config, error) { | ||||
| 		Timestamps:  defaultTimestamps, | ||||
| 	} | ||||
| 	for _, opt := range options { | ||||
| 		opt.apply(&cfg) | ||||
| 		cfg = opt.apply(cfg) | ||||
|  | ||||
| 	} | ||||
| 	return cfg, nil | ||||
| @@ -55,7 +55,7 @@ func newConfig(options ...Option) (config, error) { | ||||
|  | ||||
| // Option sets the value of an option for a Config. | ||||
| type Option interface { | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| // WithWriter sets the export stream destination. | ||||
| @@ -67,8 +67,9 @@ type writerOption struct { | ||||
| 	W io.Writer | ||||
| } | ||||
|  | ||||
| func (o writerOption) apply(cfg *config) { | ||||
| func (o writerOption) apply(cfg config) config { | ||||
| 	cfg.Writer = o.W | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithPrettyPrint sets the export stream format to use JSON. | ||||
| @@ -78,8 +79,9 @@ func WithPrettyPrint() Option { | ||||
|  | ||||
| type prettyPrintOption bool | ||||
|  | ||||
| func (o prettyPrintOption) apply(cfg *config) { | ||||
| func (o prettyPrintOption) apply(cfg config) config { | ||||
| 	cfg.PrettyPrint = bool(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithoutTimestamps sets the export stream to not include timestamps. | ||||
| @@ -89,6 +91,7 @@ func WithoutTimestamps() Option { | ||||
|  | ||||
| type timestampsOption bool | ||||
|  | ||||
| func (o timestampsOption) apply(cfg *config) { | ||||
| func (o timestampsOption) apply(cfg config) config { | ||||
| 	cfg.Timestamps = bool(o) | ||||
| 	return cfg | ||||
| } | ||||
|   | ||||
| @@ -55,26 +55,28 @@ type config struct { | ||||
|  | ||||
| // Option defines a function that configures the exporter. | ||||
| type Option interface { | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| type optionFunc func(*config) | ||||
| type optionFunc func(config) config | ||||
|  | ||||
| func (fn optionFunc) apply(cfg *config) { | ||||
| 	fn(cfg) | ||||
| func (fn optionFunc) apply(cfg config) config { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithLogger configures the exporter to use the passed logger. | ||||
| func WithLogger(logger *log.Logger) Option { | ||||
| 	return optionFunc(func(cfg *config) { | ||||
| 	return optionFunc(func(cfg config) config { | ||||
| 		cfg.logger = logger | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithClient configures the exporter to use the passed HTTP client. | ||||
| func WithClient(client *http.Client) Option { | ||||
| 	return optionFunc(func(cfg *config) { | ||||
| 	return optionFunc(func(cfg config) config { | ||||
| 		cfg.client = client | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -94,7 +96,7 @@ func New(collectorURL string, opts ...Option) (*Exporter, error) { | ||||
|  | ||||
| 	cfg := config{} | ||||
| 	for _, opt := range opts { | ||||
| 		opt.apply(&cfg) | ||||
| 		cfg = opt.apply(cfg) | ||||
| 	} | ||||
|  | ||||
| 	if cfg.client == nil { | ||||
|   | ||||
| @@ -38,7 +38,7 @@ func (cfg *InstrumentConfig) Unit() unit.Unit { | ||||
| type InstrumentOption interface { | ||||
| 	// ApplyMeter is used to set a InstrumentOption value of a | ||||
| 	// InstrumentConfig. | ||||
| 	applyInstrument(*InstrumentConfig) | ||||
| 	applyInstrument(InstrumentConfig) InstrumentConfig | ||||
| } | ||||
|  | ||||
| // NewInstrumentConfig creates a new InstrumentConfig | ||||
| @@ -46,28 +46,30 @@ type InstrumentOption interface { | ||||
| func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig { | ||||
| 	var config InstrumentConfig | ||||
| 	for _, o := range opts { | ||||
| 		o.applyInstrument(&config) | ||||
| 		config = o.applyInstrument(config) | ||||
| 	} | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| type instrumentOptionFunc func(*InstrumentConfig) | ||||
| type instrumentOptionFunc func(InstrumentConfig) InstrumentConfig | ||||
|  | ||||
| func (fn instrumentOptionFunc) applyInstrument(cfg *InstrumentConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn instrumentOptionFunc) applyInstrument(cfg InstrumentConfig) InstrumentConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithDescription applies provided description. | ||||
| func WithDescription(desc string) InstrumentOption { | ||||
| 	return instrumentOptionFunc(func(cfg *InstrumentConfig) { | ||||
| 	return instrumentOptionFunc(func(cfg InstrumentConfig) InstrumentConfig { | ||||
| 		cfg.description = desc | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithUnit applies provided unit. | ||||
| func WithUnit(unit unit.Unit) InstrumentOption { | ||||
| 	return instrumentOptionFunc(func(cfg *InstrumentConfig) { | ||||
| 	return instrumentOptionFunc(func(cfg InstrumentConfig) InstrumentConfig { | ||||
| 		cfg.unit = unit | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -90,7 +92,7 @@ func (cfg *MeterConfig) SchemaURL() string { | ||||
| // MeterOption is an interface for applying Meter options. | ||||
| type MeterOption interface { | ||||
| 	// ApplyMeter is used to set a MeterOption value of a MeterConfig. | ||||
| 	applyMeter(*MeterConfig) | ||||
| 	applyMeter(MeterConfig) MeterConfig | ||||
| } | ||||
|  | ||||
| // NewMeterConfig creates a new MeterConfig and applies | ||||
| @@ -98,27 +100,29 @@ type MeterOption interface { | ||||
| func NewMeterConfig(opts ...MeterOption) MeterConfig { | ||||
| 	var config MeterConfig | ||||
| 	for _, o := range opts { | ||||
| 		o.applyMeter(&config) | ||||
| 		config = o.applyMeter(config) | ||||
| 	} | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| type meterOptionFunc func(*MeterConfig) | ||||
| type meterOptionFunc func(MeterConfig) MeterConfig | ||||
|  | ||||
| func (fn meterOptionFunc) applyMeter(cfg *MeterConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn meterOptionFunc) applyMeter(cfg MeterConfig) MeterConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithInstrumentationVersion sets the instrumentation version. | ||||
| func WithInstrumentationVersion(version string) MeterOption { | ||||
| 	return meterOptionFunc(func(config *MeterConfig) { | ||||
| 	return meterOptionFunc(func(config MeterConfig) MeterConfig { | ||||
| 		config.instrumentationVersion = version | ||||
| 		return config | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithSchemaURL sets the schema URL. | ||||
| func WithSchemaURL(schemaURL string) MeterOption { | ||||
| 	return meterOptionFunc(func(config *MeterConfig) { | ||||
| 	return meterOptionFunc(func(config MeterConfig) MeterConfig { | ||||
| 		config.schemaURL = schemaURL | ||||
| 		return config | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -62,7 +62,7 @@ type config struct { | ||||
| // Option is the interface that applies the value to a configuration option. | ||||
| type Option interface { | ||||
| 	// apply sets the Option value of a Config. | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| // WithResource sets the Resource configuration option of a Config by merging it | ||||
| @@ -73,12 +73,13 @@ func WithResource(r *resource.Resource) Option { | ||||
|  | ||||
| type resourceOption struct{ *resource.Resource } | ||||
|  | ||||
| func (o resourceOption) apply(cfg *config) { | ||||
| func (o resourceOption) apply(cfg config) config { | ||||
| 	res, err := resource.Merge(cfg.Resource, o.Resource) | ||||
| 	if err != nil { | ||||
| 		otel.Handle(err) | ||||
| 	} | ||||
| 	cfg.Resource = res | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithCollectPeriod sets the CollectPeriod configuration option of a Config. | ||||
| @@ -88,8 +89,9 @@ func WithCollectPeriod(period time.Duration) Option { | ||||
|  | ||||
| type collectPeriodOption time.Duration | ||||
|  | ||||
| func (o collectPeriodOption) apply(cfg *config) { | ||||
| func (o collectPeriodOption) apply(cfg config) config { | ||||
| 	cfg.CollectPeriod = time.Duration(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithCollectTimeout sets the CollectTimeout configuration option of a Config. | ||||
| @@ -99,8 +101,9 @@ func WithCollectTimeout(timeout time.Duration) Option { | ||||
|  | ||||
| type collectTimeoutOption time.Duration | ||||
|  | ||||
| func (o collectTimeoutOption) apply(cfg *config) { | ||||
| func (o collectTimeoutOption) apply(cfg config) config { | ||||
| 	cfg.CollectTimeout = time.Duration(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithExporter sets the exporter configuration option of a Config. | ||||
| @@ -110,8 +113,9 @@ func WithExporter(exporter export.Exporter) Option { | ||||
|  | ||||
| type exporterOption struct{ exporter export.Exporter } | ||||
|  | ||||
| func (o exporterOption) apply(cfg *config) { | ||||
| func (o exporterOption) apply(cfg config) config { | ||||
| 	cfg.Exporter = o.exporter | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithPushTimeout sets the PushTimeout configuration option of a Config. | ||||
| @@ -121,6 +125,7 @@ func WithPushTimeout(timeout time.Duration) Option { | ||||
|  | ||||
| type pushTimeoutOption time.Duration | ||||
|  | ||||
| func (o pushTimeoutOption) apply(cfg *config) { | ||||
| func (o pushTimeoutOption) apply(cfg config) config { | ||||
| 	cfg.PushTimeout = time.Duration(o) | ||||
| 	return cfg | ||||
| } | ||||
|   | ||||
| @@ -26,12 +26,12 @@ import ( | ||||
| func TestWithResource(t *testing.T) { | ||||
| 	r := resource.NewSchemaless(attribute.String("A", "a")) | ||||
|  | ||||
| 	c := &config{} | ||||
| 	WithResource(r).apply(c) | ||||
| 	c := config{} | ||||
| 	c = WithResource(r).apply(c) | ||||
| 	assert.Equal(t, r.Equivalent(), c.Resource.Equivalent()) | ||||
|  | ||||
| 	// Ensure overwriting works. | ||||
| 	c = &config{Resource: &resource.Resource{}} | ||||
| 	WithResource(r).apply(c) | ||||
| 	c = config{Resource: &resource.Resource{}} | ||||
| 	c = WithResource(r).apply(c) | ||||
| 	assert.Equal(t, r.Equivalent(), c.Resource.Equivalent()) | ||||
| } | ||||
|   | ||||
| @@ -112,13 +112,13 @@ type accumulatorCheckpointer struct { | ||||
| // and options (including optional exporter) to configure a metric | ||||
| // export pipeline. | ||||
| func New(checkpointerFactory export.CheckpointerFactory, opts ...Option) *Controller { | ||||
| 	c := &config{ | ||||
| 	c := config{ | ||||
| 		CollectPeriod:  DefaultPeriod, | ||||
| 		CollectTimeout: DefaultPeriod, | ||||
| 		PushTimeout:    DefaultPeriod, | ||||
| 	} | ||||
| 	for _, opt := range opts { | ||||
| 		opt.apply(c) | ||||
| 		c = opt.apply(c) | ||||
| 	} | ||||
| 	if c.Resource == nil { | ||||
| 		c.Resource = resource.Default() | ||||
|   | ||||
| @@ -132,7 +132,7 @@ type factory struct { | ||||
| func NewFactory(aselector export.AggregatorSelector, tselector aggregation.TemporalitySelector, opts ...Option) export.CheckpointerFactory { | ||||
| 	var config config | ||||
| 	for _, opt := range opts { | ||||
| 		opt.applyProcessor(&config) | ||||
| 		config = opt.applyProcessor(config) | ||||
| 	} | ||||
| 	return factory{ | ||||
| 		aselector: aselector, | ||||
|   | ||||
| @@ -24,7 +24,7 @@ type config struct { | ||||
| } | ||||
|  | ||||
| type Option interface { | ||||
| 	applyProcessor(*config) | ||||
| 	applyProcessor(config) config | ||||
| } | ||||
|  | ||||
| // WithMemory sets the memory behavior of a Processor.  If this is | ||||
| @@ -37,6 +37,7 @@ func WithMemory(memory bool) Option { | ||||
|  | ||||
| type memoryOption bool | ||||
|  | ||||
| func (m memoryOption) applyProcessor(cfg *config) { | ||||
| func (m memoryOption) applyProcessor(cfg config) config { | ||||
| 	cfg.Memory = bool(m) | ||||
| 	return cfg | ||||
| } | ||||
|   | ||||
| @@ -31,7 +31,7 @@ type config struct { | ||||
| // Option is the interface that applies a configuration option. | ||||
| type Option interface { | ||||
| 	// apply sets the Option value of a config. | ||||
| 	apply(*config) | ||||
| 	apply(config) config | ||||
| } | ||||
|  | ||||
| // WithAttributes adds attributes to the configured Resource. | ||||
| @@ -56,8 +56,9 @@ type detectorsOption struct { | ||||
| 	detectors []Detector | ||||
| } | ||||
|  | ||||
| func (o detectorsOption) apply(cfg *config) { | ||||
| func (o detectorsOption) apply(cfg config) config { | ||||
| 	cfg.detectors = append(cfg.detectors, o.detectors...) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithFromEnv adds attributes from environment variables to the configured resource. | ||||
| @@ -82,8 +83,9 @@ func WithSchemaURL(schemaURL string) Option { | ||||
|  | ||||
| type schemaURLOption string | ||||
|  | ||||
| func (o schemaURLOption) apply(cfg *config) { | ||||
| func (o schemaURLOption) apply(cfg config) config { | ||||
| 	cfg.schemaURL = string(o) | ||||
| 	return cfg | ||||
| } | ||||
|  | ||||
| // WithOS adds all the OS attributes to the configured Resource. | ||||
|   | ||||
| @@ -48,7 +48,7 @@ var errMergeConflictSchemaURL = errors.New("cannot merge resource due to conflic | ||||
| func New(ctx context.Context, opts ...Option) (*Resource, error) { | ||||
| 	cfg := config{} | ||||
| 	for _, opt := range opts { | ||||
| 		opt.apply(&cfg) | ||||
| 		cfg = opt.apply(cfg) | ||||
| 	} | ||||
|  | ||||
| 	resource, err := Detect(ctx, cfg.detectors...) | ||||
|   | ||||
| @@ -93,13 +93,13 @@ var _ trace.TracerProvider = &TracerProvider{} | ||||
| // The passed opts are used to override these default values and configure the | ||||
| // returned TracerProvider appropriately. | ||||
| func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { | ||||
| 	o := &tracerProviderConfig{} | ||||
| 	o := tracerProviderConfig{} | ||||
|  | ||||
| 	for _, opt := range opts { | ||||
| 		opt.apply(o) | ||||
| 		o = opt.apply(o) | ||||
| 	} | ||||
|  | ||||
| 	ensureValidTracerProviderConfig(o) | ||||
| 	o = ensureValidTracerProviderConfig(o) | ||||
|  | ||||
| 	tp := &TracerProvider{ | ||||
| 		namedTracer: make(map[instrumentation.Library]*tracer), | ||||
| @@ -256,13 +256,13 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error { | ||||
| } | ||||
|  | ||||
| type TracerProviderOption interface { | ||||
| 	apply(*tracerProviderConfig) | ||||
| 	apply(tracerProviderConfig) tracerProviderConfig | ||||
| } | ||||
|  | ||||
| type traceProviderOptionFunc func(*tracerProviderConfig) | ||||
| type traceProviderOptionFunc func(tracerProviderConfig) tracerProviderConfig | ||||
|  | ||||
| func (fn traceProviderOptionFunc) apply(cfg *tracerProviderConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn traceProviderOptionFunc) apply(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // WithSyncer registers the exporter with the TracerProvider using a | ||||
| @@ -285,8 +285,9 @@ func WithBatcher(e SpanExporter, opts ...BatchSpanProcessorOption) TracerProvide | ||||
|  | ||||
| // WithSpanProcessor registers the SpanProcessor with a TracerProvider. | ||||
| func WithSpanProcessor(sp SpanProcessor) TracerProviderOption { | ||||
| 	return traceProviderOptionFunc(func(cfg *tracerProviderConfig) { | ||||
| 	return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 		cfg.processors = append(cfg.processors, sp) | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -298,12 +299,13 @@ func WithSpanProcessor(sp SpanProcessor) TracerProviderOption { | ||||
| // If this option is not used, the TracerProvider will use the | ||||
| // resource.Default() Resource by default. | ||||
| func WithResource(r *resource.Resource) TracerProviderOption { | ||||
| 	return traceProviderOptionFunc(func(cfg *tracerProviderConfig) { | ||||
| 	return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 		var err error | ||||
| 		cfg.resource, err = resource.Merge(resource.Environment(), r) | ||||
| 		if err != nil { | ||||
| 			otel.Handle(err) | ||||
| 		} | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -315,10 +317,11 @@ func WithResource(r *resource.Resource) TracerProviderOption { | ||||
| // If this option is not used, the TracerProvider will use a random number | ||||
| // IDGenerator by default. | ||||
| func WithIDGenerator(g IDGenerator) TracerProviderOption { | ||||
| 	return traceProviderOptionFunc(func(cfg *tracerProviderConfig) { | ||||
| 	return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 		if g != nil { | ||||
| 			cfg.idGenerator = g | ||||
| 		} | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -330,10 +333,11 @@ func WithIDGenerator(g IDGenerator) TracerProviderOption { | ||||
| // If this option is not used, the TracerProvider will use a | ||||
| // ParentBased(AlwaysSample) Sampler by default. | ||||
| func WithSampler(s Sampler) TracerProviderOption { | ||||
| 	return traceProviderOptionFunc(func(cfg *tracerProviderConfig) { | ||||
| 	return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 		if s != nil { | ||||
| 			cfg.sampler = s | ||||
| 		} | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -345,13 +349,14 @@ func WithSampler(s Sampler) TracerProviderOption { | ||||
| // If this option is not used, the TracerProvider will use the default | ||||
| // SpanLimits. | ||||
| func WithSpanLimits(sl SpanLimits) TracerProviderOption { | ||||
| 	return traceProviderOptionFunc(func(cfg *tracerProviderConfig) { | ||||
| 	return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 		cfg.spanLimits = sl | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid. | ||||
| func ensureValidTracerProviderConfig(cfg *tracerProviderConfig) { | ||||
| func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig { | ||||
| 	if cfg.sampler == nil { | ||||
| 		cfg.sampler = ParentBased(AlwaysSample()) | ||||
| 	} | ||||
| @@ -362,4 +367,5 @@ func ensureValidTracerProviderConfig(cfg *tracerProviderConfig) { | ||||
| 	if cfg.resource == nil { | ||||
| 		cfg.resource = resource.Default() | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
|   | ||||
| @@ -187,7 +187,7 @@ func configureSamplersForParentBased(samplers []ParentBasedSamplerOption) sample | ||||
| 	} | ||||
|  | ||||
| 	for _, so := range samplers { | ||||
| 		so.apply(&c) | ||||
| 		c = so.apply(c) | ||||
| 	} | ||||
|  | ||||
| 	return c | ||||
| @@ -201,7 +201,7 @@ type samplerConfig struct { | ||||
|  | ||||
| // ParentBasedSamplerOption configures the sampler for a particular sampling case. | ||||
| type ParentBasedSamplerOption interface { | ||||
| 	apply(*samplerConfig) | ||||
| 	apply(samplerConfig) samplerConfig | ||||
| } | ||||
|  | ||||
| // WithRemoteParentSampled sets the sampler for the case of sampled remote parent. | ||||
| @@ -213,8 +213,9 @@ type remoteParentSampledOption struct { | ||||
| 	s Sampler | ||||
| } | ||||
|  | ||||
| func (o remoteParentSampledOption) apply(config *samplerConfig) { | ||||
| func (o remoteParentSampledOption) apply(config samplerConfig) samplerConfig { | ||||
| 	config.remoteParentSampled = o.s | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| // WithRemoteParentNotSampled sets the sampler for the case of remote parent | ||||
| @@ -227,8 +228,9 @@ type remoteParentNotSampledOption struct { | ||||
| 	s Sampler | ||||
| } | ||||
|  | ||||
| func (o remoteParentNotSampledOption) apply(config *samplerConfig) { | ||||
| func (o remoteParentNotSampledOption) apply(config samplerConfig) samplerConfig { | ||||
| 	config.remoteParentNotSampled = o.s | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| // WithLocalParentSampled sets the sampler for the case of sampled local parent. | ||||
| @@ -240,8 +242,9 @@ type localParentSampledOption struct { | ||||
| 	s Sampler | ||||
| } | ||||
|  | ||||
| func (o localParentSampledOption) apply(config *samplerConfig) { | ||||
| func (o localParentSampledOption) apply(config samplerConfig) samplerConfig { | ||||
| 	config.localParentSampled = o.s | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| // WithLocalParentNotSampled sets the sampler for the case of local parent | ||||
| @@ -254,8 +257,9 @@ type localParentNotSampledOption struct { | ||||
| 	s Sampler | ||||
| } | ||||
|  | ||||
| func (o localParentNotSampledOption) apply(config *samplerConfig) { | ||||
| func (o localParentNotSampledOption) apply(config samplerConfig) samplerConfig { | ||||
| 	config.localParentNotSampled = o.s | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| func (pb parentBased) ShouldSample(p SamplingParameters) SamplingResult { | ||||
|   | ||||
| @@ -41,20 +41,20 @@ func (t *TracerConfig) SchemaURL() string { | ||||
| func NewTracerConfig(options ...TracerOption) TracerConfig { | ||||
| 	var config TracerConfig | ||||
| 	for _, option := range options { | ||||
| 		option.apply(&config) | ||||
| 		config = option.apply(config) | ||||
| 	} | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| // TracerOption applies an option to a TracerConfig. | ||||
| type TracerOption interface { | ||||
| 	apply(*TracerConfig) | ||||
| 	apply(TracerConfig) TracerConfig | ||||
| } | ||||
|  | ||||
| type tracerOptionFunc func(*TracerConfig) | ||||
| type tracerOptionFunc func(TracerConfig) TracerConfig | ||||
|  | ||||
| func (fn tracerOptionFunc) apply(cfg *TracerConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // SpanConfig is a group of options for a Span. | ||||
| @@ -106,7 +106,7 @@ func (cfg *SpanConfig) SpanKind() SpanKind { | ||||
| func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { | ||||
| 	var c SpanConfig | ||||
| 	for _, option := range options { | ||||
| 		option.applySpanStart(&c) | ||||
| 		c = option.applySpanStart(c) | ||||
| 	} | ||||
| 	return c | ||||
| } | ||||
| @@ -118,7 +118,7 @@ func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { | ||||
| func NewSpanEndConfig(options ...SpanEndOption) SpanConfig { | ||||
| 	var c SpanConfig | ||||
| 	for _, option := range options { | ||||
| 		option.applySpanEnd(&c) | ||||
| 		c = option.applySpanEnd(c) | ||||
| 	} | ||||
| 	return c | ||||
| } | ||||
| @@ -126,19 +126,19 @@ func NewSpanEndConfig(options ...SpanEndOption) SpanConfig { | ||||
| // SpanStartOption applies an option to a SpanConfig. These options are applicable | ||||
| // only when the span is created | ||||
| type SpanStartOption interface { | ||||
| 	applySpanStart(*SpanConfig) | ||||
| 	applySpanStart(SpanConfig) SpanConfig | ||||
| } | ||||
|  | ||||
| type spanOptionFunc func(*SpanConfig) | ||||
| type spanOptionFunc func(SpanConfig) SpanConfig | ||||
|  | ||||
| func (fn spanOptionFunc) applySpanStart(cfg *SpanConfig) { | ||||
| 	fn(cfg) | ||||
| func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig { | ||||
| 	return fn(cfg) | ||||
| } | ||||
|  | ||||
| // SpanEndOption applies an option to a SpanConfig. These options are | ||||
| // applicable only when the span is ended. | ||||
| type SpanEndOption interface { | ||||
| 	applySpanEnd(*SpanConfig) | ||||
| 	applySpanEnd(SpanConfig) SpanConfig | ||||
| } | ||||
|  | ||||
| // EventConfig is a group of options for an Event. | ||||
| @@ -170,7 +170,7 @@ func (cfg *EventConfig) StackTrace() bool { | ||||
| func NewEventConfig(options ...EventOption) EventConfig { | ||||
| 	var c EventConfig | ||||
| 	for _, option := range options { | ||||
| 		option.applyEvent(&c) | ||||
| 		c = option.applyEvent(c) | ||||
| 	} | ||||
| 	if c.timestamp.IsZero() { | ||||
| 		c.timestamp = time.Now() | ||||
| @@ -180,7 +180,7 @@ func NewEventConfig(options ...EventOption) EventConfig { | ||||
|  | ||||
| // EventOption applies span event options to an EventConfig. | ||||
| type EventOption interface { | ||||
| 	applyEvent(*EventConfig) | ||||
| 	applyEvent(EventConfig) EventConfig | ||||
| } | ||||
|  | ||||
| // SpanOption are options that can be used at both the beginning and end of a span. | ||||
| @@ -203,12 +203,14 @@ type SpanEndEventOption interface { | ||||
|  | ||||
| type attributeOption []attribute.KeyValue | ||||
|  | ||||
| func (o attributeOption) applySpan(c *SpanConfig) { | ||||
| func (o attributeOption) applySpan(c SpanConfig) SpanConfig { | ||||
| 	c.attributes = append(c.attributes, []attribute.KeyValue(o)...) | ||||
| 	return c | ||||
| } | ||||
| func (o attributeOption) applySpanStart(c *SpanConfig) { o.applySpan(c) } | ||||
| func (o attributeOption) applyEvent(c *EventConfig) { | ||||
| func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } | ||||
| func (o attributeOption) applyEvent(c EventConfig) EventConfig { | ||||
| 	c.attributes = append(c.attributes, []attribute.KeyValue(o)...) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| var _ SpanStartEventOption = attributeOption{} | ||||
| @@ -234,10 +236,16 @@ type SpanEventOption interface { | ||||
|  | ||||
| type timestampOption time.Time | ||||
|  | ||||
| func (o timestampOption) applySpan(c *SpanConfig)      { c.timestamp = time.Time(o) } | ||||
| func (o timestampOption) applySpanStart(c *SpanConfig) { o.applySpan(c) } | ||||
| func (o timestampOption) applySpanEnd(c *SpanConfig)   { o.applySpan(c) } | ||||
| func (o timestampOption) applyEvent(c *EventConfig)    { c.timestamp = time.Time(o) } | ||||
| func (o timestampOption) applySpan(c SpanConfig) SpanConfig { | ||||
| 	c.timestamp = time.Time(o) | ||||
| 	return c | ||||
| } | ||||
| func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } | ||||
| func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig   { return o.applySpan(c) } | ||||
| func (o timestampOption) applyEvent(c EventConfig) EventConfig { | ||||
| 	c.timestamp = time.Time(o) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| var _ SpanEventOption = timestampOption{} | ||||
|  | ||||
| @@ -249,9 +257,15 @@ func WithTimestamp(t time.Time) SpanEventOption { | ||||
|  | ||||
| type stackTraceOption bool | ||||
|  | ||||
| func (o stackTraceOption) applyEvent(c *EventConfig)  { c.stackTrace = bool(o) } | ||||
| func (o stackTraceOption) applySpan(c *SpanConfig)    { c.stackTrace = bool(o) } | ||||
| func (o stackTraceOption) applySpanEnd(c *SpanConfig) { o.applySpan(c) } | ||||
| func (o stackTraceOption) applyEvent(c EventConfig) EventConfig { | ||||
| 	c.stackTrace = bool(o) | ||||
| 	return c | ||||
| } | ||||
| func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig { | ||||
| 	c.stackTrace = bool(o) | ||||
| 	return c | ||||
| } | ||||
| func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) } | ||||
|  | ||||
| // WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false). | ||||
| func WithStackTrace(b bool) SpanEndEventOption { | ||||
| @@ -261,8 +275,9 @@ func WithStackTrace(b bool) SpanEndEventOption { | ||||
| // WithLinks adds links to a Span. The links are added to the existing Span | ||||
| // links, i.e. this does not overwrite. Links with invalid span context are ignored. | ||||
| func WithLinks(links ...Link) SpanStartOption { | ||||
| 	return spanOptionFunc(func(cfg *SpanConfig) { | ||||
| 	return spanOptionFunc(func(cfg SpanConfig) SpanConfig { | ||||
| 		cfg.links = append(cfg.links, links...) | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -270,28 +285,32 @@ func WithLinks(links ...Link) SpanStartOption { | ||||
| // existing parent span context will be ignored when defining the Span's trace | ||||
| // identifiers. | ||||
| func WithNewRoot() SpanStartOption { | ||||
| 	return spanOptionFunc(func(cfg *SpanConfig) { | ||||
| 	return spanOptionFunc(func(cfg SpanConfig) SpanConfig { | ||||
| 		cfg.newRoot = true | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithSpanKind sets the SpanKind of a Span. | ||||
| func WithSpanKind(kind SpanKind) SpanStartOption { | ||||
| 	return spanOptionFunc(func(cfg *SpanConfig) { | ||||
| 	return spanOptionFunc(func(cfg SpanConfig) SpanConfig { | ||||
| 		cfg.spanKind = kind | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithInstrumentationVersion sets the instrumentation version. | ||||
| func WithInstrumentationVersion(version string) TracerOption { | ||||
| 	return tracerOptionFunc(func(cfg *TracerConfig) { | ||||
| 	return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { | ||||
| 		cfg.instrumentationVersion = version | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // WithSchemaURL sets the schema URL for the Tracer. | ||||
| func WithSchemaURL(schemaURL string) TracerOption { | ||||
| 	return tracerOptionFunc(func(cfg *TracerConfig) { | ||||
| 	return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { | ||||
| 		cfg.schemaURL = schemaURL | ||||
| 		return cfg | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -252,3 +252,71 @@ func TestTracerConfig(t *testing.T) { | ||||
| 		assert.Equal(t, test.expected, config) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Save benchmark results to a file level var to avoid the compiler optimizing | ||||
| // away the actual work. | ||||
| var ( | ||||
| 	tracerConfig TracerConfig | ||||
| 	spanConfig   SpanConfig | ||||
| 	eventConfig  EventConfig | ||||
| ) | ||||
|  | ||||
| func BenchmarkNewTracerConfig(b *testing.B) { | ||||
| 	opts := []TracerOption{ | ||||
| 		WithInstrumentationVersion("testing verion"), | ||||
| 		WithSchemaURL("testing URL"), | ||||
| 	} | ||||
|  | ||||
| 	b.ReportAllocs() | ||||
| 	b.ResetTimer() | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		tracerConfig = NewTracerConfig(opts...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func BenchmarkNewSpanStartConfig(b *testing.B) { | ||||
| 	opts := []SpanStartOption{ | ||||
| 		WithAttributes(attribute.Bool("key", true)), | ||||
| 		WithTimestamp(time.Now()), | ||||
| 		WithLinks(Link{}), | ||||
| 		WithNewRoot(), | ||||
| 		WithSpanKind(SpanKindClient), | ||||
| 	} | ||||
|  | ||||
| 	b.ReportAllocs() | ||||
| 	b.ResetTimer() | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		spanConfig = NewSpanStartConfig(opts...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func BenchmarkNewSpanEndConfig(b *testing.B) { | ||||
| 	opts := []SpanEndOption{ | ||||
| 		WithTimestamp(time.Now()), | ||||
| 		WithStackTrace(true), | ||||
| 	} | ||||
|  | ||||
| 	b.ReportAllocs() | ||||
| 	b.ResetTimer() | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		spanConfig = NewSpanEndConfig(opts...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func BenchmarkNewEventConfig(b *testing.B) { | ||||
| 	opts := []EventOption{ | ||||
| 		WithAttributes(attribute.Bool("key", true)), | ||||
| 		WithTimestamp(time.Now()), | ||||
| 		WithStackTrace(true), | ||||
| 	} | ||||
|  | ||||
| 	b.ReportAllocs() | ||||
| 	b.ResetTimer() | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		eventConfig = NewEventConfig(opts...) | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user