Background:
The configuration_core library was created to separate the programmatic configuration interface from the YAML parsing components in completion of #4134.
It links to all SDK signal libraries (traces, logs, and metrics). Therefore, if a user of programmatic or yaml configuration desires to only configure one signal provider they must still link all SDK libraries.
This is driven by two things: SdkBuilder, which constructs all signal providers via direct Factory::Create calls in one TU, and ConfiguredSdk, whose header stores all three SDK provider types. This also limits what SDK component builders a user can register for configuration.
Goals:
This ticket has two goals:
- Allow linking just to the SDK components being configured and
- Support registering builders for every configurable SDK component, including the signal providers themselves.
Together these would allow linking and registering only the builders that an application supports, providing more control over configurable options, ability to customize the SDK components, and reduce binary size.
Some use cases enabled by this include:
- Registering a custom builder to replace a default SDK component builder
- A user may define their own implementation of a
TracerConfigurator, BatchSpanProcessor, and TracerProvider for example.
- Registering mock component builders for test scenarios
- Intentionally not registering a component's builder to prevent its use in the application
Example:
If the config components are decoupled from the SDK signal providers, the example below should only require the application to link the configuration library, the trace default builders, the gRPC span exporter, and users custom batch processor. No metrics or logs libraries would be linked and attempts to configure them would result in an error.
namespace cfg = opentelemetry::sdk::configuration;
auto otlp_grpc_exporter = std::make_unique<cfg::OtlpGrpcSpanExporterConfiguration>();
otlp_grpc_exporter->endpoint = "http://localhost:4317";
auto processor = std::make_unique<cfg::BatchSpanProcessorConfiguration>();
processor->exporter = std::move(otlp_grpc_exporter);
auto tp = std::make_unique<cfg::TracerProviderConfiguration>();
tp->processors.push_back(std::move(processor));
auto model = std::make_unique<cfg::Configuration>();
model->tracer_provider = std::move(tp);
// New Registry behavior:
// Constructing a registry creates an empty registry that brings no
// SDK dependencies outside of `configuration_core`. A config node
// with no registered builder is a error
auto registry = std::make_shared<cfg::Registry>();
// New SDK signal specific method to register all its component builders:
// Here the trace method registers its builders (provider, processors, samplers, configurator, ...)
// This is the one call that links opentelemetry_trace into the app.
cfg::RegisterTraceDefaults(registry.get());
opentelemetry::exporter::otlp::OtlpGrpcSpanBuilder::Register(registry.get());
// New registry slots for all configurable SDK components:
// Users may register their own builders for the standard SDK components
// Here their batch processor implementation takes the standard registry slot
my_library::MyBatchSpanProcessorBuilder::Register(registry.get());
// New SdkBuilder behavior:
// SdkBuilder brings in no signal SDK dependencies (traces/metrics/logs)
// it only reads the model, then looks up and calls builders from the
// registry.
auto sdk = cfg::ConfiguredSdk::Create(registry, model);
// New ConfiguredSdk behavior:
// ConfiguredSdk gains API-typed provider handles (Install
// uses only these) and keeps its SDK-typed members declared against
// forward declarations (set if the default SDK provider was built and null for a custom provider)
//
sdk->Install();
// Full SDK provider API still available in the default case
sdk->tracer_provider->ForceFlush(std::chrono::milliseconds(100));
Behavioral change:
Constructing a Registry today has some registered default builders and configuration relies on the SdkBuilder to directly create standard SDK components.
The new behavior would be to construct an empty Registry by default and require explicit registration of the builders needed.
Existing users (including all yaml users) may keep the current behavior (Registry is populated with default SDK component builders) through a new RegistryFactory library and Create method:
// Current approach to instantiate a Registry
// The registry holds mainly exporters, extensions, and propagator builders
// The SdkBuilder has the SDK component creators built-in
auto registry = std::make_shared<cfg::Registry>();
// New approach to instantiate a Registry with all SDK component builders
// The new RegistryFactory library links all signals and registers their default component builders
auto registry = cfg::RegistryFactory::Create();
Background:
The
configuration_corelibrary was created to separate the programmatic configuration interface from the YAML parsing components in completion of #4134.It links to all SDK signal libraries (traces, logs, and metrics). Therefore, if a user of programmatic or yaml configuration desires to only configure one signal provider they must still link all SDK libraries.
This is driven by two things:
SdkBuilder, which constructs all signal providers via directFactory::Createcalls in one TU, andConfiguredSdk, whose header stores all three SDK provider types. This also limits what SDK component builders a user can register for configuration.Goals:
This ticket has two goals:
Together these would allow linking and registering only the builders that an application supports, providing more control over configurable options, ability to customize the SDK components, and reduce binary size.
Some use cases enabled by this include:
TracerConfigurator,BatchSpanProcessor, andTracerProviderfor example.Example:
If the config components are decoupled from the SDK signal providers, the example below should only require the application to link the configuration library, the trace default builders, the gRPC span exporter, and users custom batch processor. No metrics or logs libraries would be linked and attempts to configure them would result in an error.
Behavioral change:
Constructing a
Registrytoday has some registered default builders and configuration relies on theSdkBuilderto directly create standard SDK components.The new behavior would be to construct an empty
Registryby default and require explicit registration of the builders needed.Existing users (including all yaml users) may keep the current behavior (Registry is populated with default SDK component builders) through a new
RegistryFactorylibrary andCreatemethod: