-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unify Configuration and Initialization #536
Comments
There was discussion regarding whether type Option interface {
Apply(*Config)
}
type OptionFunc func(*Config)
func (o OptionFunc) Apply(c *Config) {
o(c)
} Then simple options can be implemented in functions and wrapped with func WithName(name string) Option {
return OptionFunc(func(c *Config) {
c.name = name
})
} |
One place where bare functions weren't enough was in metrics options for instruments. We used to have three kinds of instruments (counters, gauges and measures). They had some common options (like type Config struct {…}
// measure-specific options
type MeasureOption interface {
ApplyMeasure(*Config)
}
// gauge-specific options
type GaugeOption interface {…}
// counter-specific options
type CounterOption interface {…}
// general option (with unit, with description)
// this can be passed as an instrument-specific option too
type Option interface {
MeasureOption
GaugeOption
CounterOption
}
func WithDescription(n string) Option {…}
func WithAbsolute(a bool) MeasureOption {…}
func NewMeasure(n string, o ...MeasureOption) Measure {…}
func NewCounter(n string, o ...CounterOption) Counter {…} so So I'd amend the proposal above to what @Aneurysm9 proposed: type Option interface {
// this can be named differently in complex cases
Apply(*Config)
}
// this can be a struct in complex cases
type OptionFunc func(*Config)
func (o OptionFunc) Apply(c *Config) {
o(c)
}
type Config struct { ... }
// Not sure to standardize on those, though
func Configure(opts ...Option) Config {
config Config{}
for _, opt := range opts {
opt(&config)
}
return config
}
func NewT(config Config) *T { ... }
func ConfigureT(opts ...Option) *T {
t := NewT(Configure(opts…))
// ...
} |
Conform to API option design outlined in #536. Add tests to validate new TracerConfigure function Drop the `instrumentation` prefix.
* Update Tracer configuration. Conform to API option design outlined in #536. Add tests to validate new TracerConfigure function Drop the `instrumentation` prefix. * Stick with instrumentationVersion for now * Propagate changes * Add changes to Changelog
* Update Tracer configuration. Conform to API option design outlined in open-telemetry#536. Add tests to validate new TracerConfigure function Drop the `instrumentation` prefix. * Stick with instrumentationVersion for now * Propagate changes * Add changes to Changelog
Happy to take this one @MrAlias. |
Maybe one thing that needs to be looked at, is how to configure two same things within one object. So an example would be in otlp exporter, where we can configure (not in master yet) two connections separately (one for sending metrics, one for sending traces). So I don't have an ideal solution yet, but that's what I have done for now:
so the use is: cfg := Config{}.Apply(WithThis(…), WithThat(…))
cm := NewSingleConnectionManager(cfg)
// or
cfg := MultiConnectionConfig{}
cfg.Tracing.ApplyInPlace(WithThis(…), WithThat(…))
cfg.Metrics.ApplyInPlace(WithThis(…), WithSomethingElse(…))
cm := NewMultiConnectionManager(cfg) For |
Just to make sure what is left to be done: 1. Double-check documented refA little change proposal (by example, NOT in docs) can be found here: open-telemetry/opentelemetry-go-contrib#750 2. Apply the pattern in the whole OTel Go codebaseProbably a PR per config type would be the most effective approach. Please confirm. I plan to put my 👀 on this issue on Monday. Side note: This might be also seen as a related issue: open-telemetry/opentelemetry-go-contrib#746 |
@pellared I think we're in agreement on the overall strategy. I would add that we should update the docs before we update the codebase. I like the idea presented in open-telemetry/opentelemetry-go-contrib#750. We should updated the docs to match and proceed as you outlined. |
Question: should this be done in multiple PRs? Question: should we start in contrib or here? |
There is one deviation we must make. The API defines a number of configs I think it is still prudent to have the struct members unexported, configured via Options, and accessed via methods. Is there any reason why the |
Initially I wanted to implement it in the exact way you proposed. Unexport the fields and add exported getters. However I was not sure if this is the way to go. I would need more time to analyze how SDK uses it and experiment with some alternative design. |
Being consistent in how we configure and create things in the project means users can easily anticipate what they need to do. Currently this is not the case.
We should standardize on the approach outlined in this comment:
The text was updated successfully, but these errors were encountered: