먼저 exporter의 Factory를 살펴보자.
// Factory is factory interface for exporters.
//
// This interface cannot be directly implemented. Implementations must
// use the NewFactory to implement it.
// 해당 인터페이스를 직접 사용할 수 없고 반드시 NewFactory()를 이용해 생성해야한다.
type Factory interface {
component.Factory // 모든 컴포넌트 팩토리가 구현하는 인터페이스. Type()과 CreateDefaultConfig() 메서드 필요.
// CreateTracesExporter creates a TracesExporter based on this config.
// If the exporter type does not support tracing or if the config is not valid,
// an error will be returned instead.
CreateTracesExporter(ctx context.Context, set CreateSettings, cfg component.Config) (Traces, error)
// TracesExporterStability gets the stability level of the TracesExporter.
TracesExporterStability() component.StabilityLevel
// CreateMetricsExporter creates a MetricsExporter based on this config.
// If the exporter type does not support metrics or if the config is not valid,
// an error will be returned instead.
CreateMetricsExporter(ctx context.Context, set CreateSettings, cfg component.Config) (Metrics, error)
// MetricsExporterStability gets the stability level of the MetricsExporter.
MetricsExporterStability() component.StabilityLevel
// CreateLogsExporter creates a LogsExporter based on the config.
// If the exporter type does not support logs or if the config is not valid,
// an error will be returned instead.
CreateLogsExporter(ctx context.Context, set CreateSettings, cfg component.Config) (Logs, error)
// LogsExporterStability gets the stability level of the LogsExporter.
LogsExporterStability() component.StabilityLevel
unexportedFactoryFunc()
}
// FactoryOption apply changes to Factory.
type FactoryOption interface {
// applyExporterFactoryOption applies the option.
applyExporterFactoryOption(o *factory)
}
FactoryOption 인터페이스로 팩토리에 옵션을 적용한다.
NewFactory 함수. 이 함수를 이용해 Factory를 생성한다.
매개변수로는 생성되는 컴포터는의 Type, 컴포넌트의 default config를 생성하는 createDefaultConfig 함수, 그리고 팩토리에 적용할 FactoryOption들을 받는다.
// NewFactory returns a Factory.
func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory {
f := &factory{
cfgType: cfgType,
CreateDefaultConfigFunc: createDefaultConfig,
}
for _, opt := range options {
opt.applyExporterFactoryOption(f)
}
return f
}
options는 factoryOptionFunc 타입이다.
var _ FactoryOption = (*factoryOptionFunc)(nil)
// factoryOptionFunc is an ExporterFactoryOption created through a function.
type factoryOptionFunc func(*factory)
func (f factoryOptionFunc) applyExporterFactoryOption(o *factory) {
f(o)
}
먼저 첫 번째 라인은, factoryOptionFunc 타입이 FactoryOption 인터페이스를 만족하는지 확인하는 용도로 사용된다. 만약 구현되지 않았다면 빌드 과정에서 에러가 발생한다.
factoryOptionFunc은 factory를 반환하는 빌더라고 생각할 수 있다. factoryOptionFunc은 applyExporterFactoryOption을 구현했기 때문에 FactoryOption 인터페이스를 만족한다.
다시 아래 코드로 돌아와서...
NewFactory() 호출 시 매개변수로 받은 FactoryOption 인터페이스를 만족하는 함수들을 실행시킨다.
for _, opt := range options {
opt.applyExporterFactoryOption(f)
}
여기서 재밌는게, options로 넘겨주는 함수들을 보면 아래처럼 생겼다.
func WithTraces(createTraces CreateTracesFunc, sl component.StabilityLevel) FactoryOption {
return factoryOptionFunc(func(o *factory) {
o.tracesStabilityLevel = sl
o.CreateTracesFunc = createTraces
})
}
넘겨주는 타입(?) 함수들이 각각 applyExporterFactoryOption()을 구현하지 않고, factoryOptionFunc 타입을 사용해서 처리한다. 😮
NewFactory 함수가 반환하는 타입은 factory struct로,
- 컴포넌트 타입
- 컴포넌트 default config 생성 함수
- Trace Factory 생성 함수
- Metric Factory 생성 함수
- Log Factory 생성 함수
그리고 Trace, Metric, Log 컴포넌트의 Stability를 나타내는 필드를 갖는다.type factory struct { cfgType component.Type component.CreateDefaultConfigFunc CreateTracesFunc tracesStabilityLevel component.StabilityLevel CreateMetricsFunc metricsStabilityLevel component.StabilityLevel CreateLogsFunc logsStabilityLevel component.StabilityLevel }
그런데, 구현된 factory struct 메서드를 보면, CreateTracesExporter, CreateMetricsExporter, CreateLogsExporter가 없는 것을 볼 수 있다. 왜 그럴까? 이유는 코드 아래 나온다.
func (f *factory) Type() component.Type {
return f.cfgType
}
func (f *factory) unexportedFactoryFunc() {}
func (f *factory) TracesExporterStability() component.StabilityLevel {
return f.tracesStabilityLevel
}
func (f *factory) MetricsExporterStability() component.StabilityLevel {
return f.metricsStabilityLevel
}
func (f *factory) LogsExporterStability() component.StabilityLevel {
return f.logsStabilityLevel
}
아래 코드는 factory struct에 임베드된 CreateTracesFunc 타입이다. 이 함수의 메서드로 CreateTracesExporter가 구현되어 있다. factory가 CreateTracesFunc를 임베딩하고 있기 때문에 factory가 CreateTracesExporter메서드를 갖고 있는 것처럼 사용할 수 있는 것이다.
// CreateTracesFunc is the equivalent of Factory.CreateTraces.
type CreateTracesFunc func(context.Context, CreateSettings, component.Config) (Traces, error)
// CreateTracesExporter implements ExporterFactory.CreateTracesExporter().
func (f CreateTracesFunc) CreateTracesExporter(ctx context.Context, set CreateSettings, cfg component.Config) (Traces, error) {
if f == nil {
return nil, component.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg)
}