From 49d9421a3ac205a33511e69c80d72cdd0ea406af Mon Sep 17 00:00:00 2001 From: "Peterson, Bruce (bp0438)" Date: Fri, 26 Jan 2024 12:32:27 -0500 Subject: [PATCH 1/2] implemented all samplers and added sampler ratio to conf file --- .../otel-webserver-module/README.md | 3 +- .../include/apache/ApacheConfig.h | 7 +++ .../include/core/api/OpentelemetrySdk.h | 1 + .../include/core/api/TenantConfig.h | 4 ++ .../opentelemetry_module.conf | 6 +- .../src/apache/ApacheConfig.cpp | 20 +++++++ .../src/apache/ApacheHooks.cpp | 5 ++ .../src/apache/mod_apache_otel.cpp | 6 ++ .../src/core/api/ApiUtils.cpp | 6 ++ .../src/core/sdkwrapper/SdkHelperFactory.cpp | 59 +++++++++++++------ 10 files changed, 96 insertions(+), 21 deletions(-) diff --git a/instrumentation/otel-webserver-module/README.md b/instrumentation/otel-webserver-module/README.md index 8e17c46c1..b93a7f247 100644 --- a/instrumentation/otel-webserver-module/README.md +++ b/instrumentation/otel-webserver-module/README.md @@ -46,7 +46,8 @@ Monitoring individual modules is crucial to the instrumentation of Apache web se |*ApacheModuleOtelSpanExporter* | otlp | OPTIONAL: Specify the span exporter to be used. Supported values are "otlp" and "ostream". All other supported values would be added in future. | |*ApacheModuleOtelExporterEndpoint:* | | REQUIRED: The endpoint otel exporter exports to. Example "docker.for.mac.localhost:4317" | |*ApacheModuleOtelSpanProcessor* | batch | OPTIONAL: Specify the processor to select to. Supported values are "simple" and "batch".| -|*ApacheModuleOtelSampler* | AlwaysOn | OPTIONAL: Supported values are "AlwaysOn" and "AlwaysOff" | +|*ApacheModuleOtelSampler* | always_on | OPTIONAL: Supported values are "always_on", "always_off", "traceidratio", "parentbased_always_on", parentbased_always_off", "parentbased_traceidratio | +|*ApacheModuleOtelSamplerRatio* | 0.0 | OPTIONAL: Supported values range from 0.0 to 1.0 and represent percent sampled| |*ApacheModuleOtelMaxQueueSize* | 2048 | OPTIONAL: The maximum queue size. After the size is reached spans are dropped| |*ApacheModuleOtelScheduledDelayMillis* | 5000 | OPTIONAL: The delay interval in milliseconds between two consecutive exports| |*ApacheModuleOtelExportTimeoutMillis* | 30000 | OPTIONAL: How long the export can run in milliseconds before it is cancelled| diff --git a/instrumentation/otel-webserver-module/include/apache/ApacheConfig.h b/instrumentation/otel-webserver-module/include/apache/ApacheConfig.h index ebef128e4..e78938bf7 100644 --- a/instrumentation/otel-webserver-module/include/apache/ApacheConfig.h +++ b/instrumentation/otel-webserver-module/include/apache/ApacheConfig.h @@ -54,6 +54,9 @@ class otel_cfg const char* getOtelSamplerType() { return otelSamplerType; } int getOtelSamplerTypeInitialized() { return otelSamplerType_initialized; } + const char* getOtelSamplerRatio() { return otelSamplerRatio; } + int getOtelSamplerRatioInitialized() { return otelSamplerRatio_initialized; } + const char* getServiceNamespace() { return serviceNamespace; } int getServiceNamespaceInitialized() { return serviceNamespace_initialized; } @@ -141,6 +144,9 @@ class otel_cfg const char *otelSamplerType; // OPTIONAL: Type of Otel Sampler int otelSamplerType_initialized; + const char *otelSamplerRatio; // OPTIONAL: Otel Sampler Ratio + int otelSamplerRatio_initialized; + const char *serviceNamespace; // REQUIRED: A namespace for the ServiceName; int serviceNamespace_initialized; @@ -235,6 +241,7 @@ class ApacheConfigHandlers static const char* otel_set_otelSslCertificatePath(cmd_parms *cmd, void *conf, const char *arg); static const char* otel_set_otelProcessorType(cmd_parms *cmd, void *conf, const char *arg); static const char* otel_set_otelSamplerType(cmd_parms *cmd, void *conf, const char *arg); + static const char* otel_set_otelSamplerRatio(cmd_parms *cmd, void *conf, const char *arg); static const char* otel_set_serviceNamespace(cmd_parms *cmd, void *conf, const char *arg); static const char* otel_set_serviceName(cmd_parms *cmd, void *conf, const char *arg); static const char* otel_set_serviceInstanceId(cmd_parms *cmd, void *conf, const char *arg); diff --git a/instrumentation/otel-webserver-module/include/core/api/OpentelemetrySdk.h b/instrumentation/otel-webserver-module/include/core/api/OpentelemetrySdk.h index b7dfec358..50ab195a8 100755 --- a/instrumentation/otel-webserver-module/include/core/api/OpentelemetrySdk.h +++ b/instrumentation/otel-webserver-module/include/core/api/OpentelemetrySdk.h @@ -32,6 +32,7 @@ #define OTEL_SDK_ENV_OTEL_SSL_CERTIFICATE_PATH "OTEL_SDK_ENV_OTEL_SSL_CERTIFICATE_PATH" /*optional*/ #define OTEL_SDK_ENV_OTEL_PROCESSOR_TYPE "OTEL_SDK_ENV_OTEL_PROCESSOR_TYPE" #define OTEL_SDK_ENV_OTEL_SAMPLER_TYPE "OTEL_SDK_ENV_OTEL_SAMPLER_TYPE" +#define OTEL_SDK_ENV_OTEL_SAMPLER_RATIO "OTEL_SDK_ENV_OTEL_SAMPLER_RATIO" #define OTEL_SDK_ENV_OTEL_LIBRARY_NAME "OTEL_SDK_ENV_OTEL_LIBRARY_NAME" /* {{{ For API user: optional, only if connection by aggregator is required */ #define OTEL_SDK_ENV_SERVICE_NAMESPACE "OTEL_SDK_ENV_SERVICE_NAMESPACE" diff --git a/instrumentation/otel-webserver-module/include/core/api/TenantConfig.h b/instrumentation/otel-webserver-module/include/core/api/TenantConfig.h index a32016e5e..49332b279 100644 --- a/instrumentation/otel-webserver-module/include/core/api/TenantConfig.h +++ b/instrumentation/otel-webserver-module/include/core/api/TenantConfig.h @@ -52,6 +52,7 @@ class TenantConfig const unsigned getOtelExportTimeoutMillis() const {return otelExportTimeoutMillis;} const unsigned getOtelMaxExportBatchSize() const {return otelMaxExportBatchSize;} const std::string& getOtelSamplerType() const {return otelSamplerType;} + const double getOtelSamplerRatio() const {return otelSamplerRatio;} const bool getOtelSslEnabled() const { return otelSslEnabled; } const std::string& getOtelSslCertPath() const { return otelSslCertPath; } @@ -69,6 +70,7 @@ class TenantConfig void setOtelExportTimeoutMillis(const unsigned int otelExportTimeoutMillis) { this->otelExportTimeoutMillis = otelExportTimeoutMillis; } void setOtelMaxExportBatchSize(const unsigned int otelMaxExportBatchSize) {this->otelMaxExportBatchSize = otelMaxExportBatchSize; } void setOtelSamplerType(const std::string& otelSamplerType) { this->otelSamplerType = otelSamplerType; } + void setOtelSamplerRatio( const std::string otelSamplerRatio) { this->otelSamplerRatio = stod(otelSamplerRatio); } void setOtelSslEnabled(const bool& otelSslEnabled) { this->otelSslEnabled = otelSslEnabled; } void setOtelSslCertPath(const std::string& otelSslCertPath) { this->otelSslCertPath = otelSslCertPath; } @@ -88,6 +90,8 @@ class TenantConfig std::string otelProcessorType; std::string otelSamplerType; + double otelSamplerRatio; + unsigned otelMaxQueueSize; unsigned otelScheduledDelayMillis; diff --git a/instrumentation/otel-webserver-module/opentelemetry_module.conf b/instrumentation/otel-webserver-module/opentelemetry_module.conf index b5b0a9194..1269d7f6b 100755 --- a/instrumentation/otel-webserver-module/opentelemetry_module.conf +++ b/instrumentation/otel-webserver-module/opentelemetry_module.conf @@ -20,8 +20,10 @@ ApacheModuleOtelExporterEndpoint collector:4317 #ApacheModuleOtelSslEnabled ON #ApacheModuleOtelSslCertificatePath -#ApacheModuleOtelSpanProcessor Batch -#ApacheModuleOtelSampler AlwaysOn +#ApacheModuleOtelSampler always_on +#ApacheModuleOtelSamplerRatio 0.1 + +#ApacheModuleOtelSpanProcessor batch #ApacheModuleOtelMaxQueueSize 1024 #ApacheModuleOtelScheduledDelayMillis 3000 #ApacheModuleOtelExportTimeoutMillis 30000 diff --git a/instrumentation/otel-webserver-module/src/apache/ApacheConfig.cpp b/instrumentation/otel-webserver-module/src/apache/ApacheConfig.cpp index 92c59e875..fbe4f4775 100644 --- a/instrumentation/otel-webserver-module/src/apache/ApacheConfig.cpp +++ b/instrumentation/otel-webserver-module/src/apache/ApacheConfig.cpp @@ -169,6 +169,14 @@ const char* ApacheConfigHandlers::otel_set_otelSamplerType(cmd_parms *cmd, void return helperChar(cmd, cfg, arg, cfg->otelSamplerType, cfg->otelSamplerType_initialized, "otel_set_otelSamplerType"); } +// char *otelSamplerRatio; +// int otelSamplerRatio_initialized; +const char* ApacheConfigHandlers::otel_set_otelSamplerRatio(cmd_parms *cmd, void *conf, const char *arg) +{ + otel_cfg* cfg = (otel_cfg*) conf; + return helperChar(cmd, cfg, arg, cfg->otelSamplerRatio, cfg->otelSamplerRatio_initialized, "otel_set_otelSamplerRatio"); +} + // char *serviceNamespace; // int serviceNamespace_initialized; const char* ApacheConfigHandlers::otel_set_serviceNamespace(cmd_parms *cmd, void *conf, const char *arg) @@ -464,6 +472,10 @@ void otel_cfg::init() otelSamplerType = "ALWAYSON"; otelSamplerType_initialized = 0; + // otelSamplerRatio OPTIONAL: Otel Sampler Ratio + otelSamplerRatio = "0.0"; + otelSamplerRatio_initialized = 0; + // serviceNamespace REQUIRED: A namespace for the ServiceName; serviceNamespace = ""; serviceNamespace_initialized = 0; @@ -672,6 +684,11 @@ void* ApacheConfigHandlers::otel_merge_dir_config(apr_pool_t* p, void* parent_co apr_pstrdup(p, nconf->otelSamplerType) : apr_pstrdup(p, pconf->otelSamplerType); merged_config->otelSamplerType_initialized = 1; + // otelSamplerRatio OPTIONAL: Otel Sampler Ratio + merged_config->otelSamplerRatio = nconf->otelSamplerRatio_initialized ? + apr_pstrdup(p, nconf->otelSamplerRatio) : apr_pstrdup(p, pconf->otelSamplerRatio); + merged_config->otelSamplerRatio_initialized = 1; + // serviceNamespace REQUIRED: A namespace for the ServiceName; merged_config->serviceNamespace = nconf->serviceNamespace_initialized ? apr_pstrdup(p, nconf->serviceNamespace) : apr_pstrdup(p, pconf->serviceNamespace); @@ -801,6 +818,9 @@ otel_cfg* ApacheConfigHandlers::getProcessConfig(const request_rec* r) process_cfg->otelSamplerType = apr_pstrdup(r->server->process->pool, our_config->otelSamplerType); process_cfg->otelSamplerType_initialized = our_config->otelSamplerType_initialized; + process_cfg->otelSamplerRatio = apr_pstrdup(r->server->process->pool, our_config->otelSamplerRatio); + process_cfg->otelSamplerRatio_initialized = our_config->otelSamplerRatio_initialized; + process_cfg->serviceNamespace = apr_pstrdup(r->server->process->pool, our_config->serviceNamespace); process_cfg->serviceNamespace_initialized = our_config->serviceNamespace_initialized; diff --git a/instrumentation/otel-webserver-module/src/apache/ApacheHooks.cpp b/instrumentation/otel-webserver-module/src/apache/ApacheHooks.cpp index 1bb575575..a3c260167 100644 --- a/instrumentation/otel-webserver-module/src/apache/ApacheHooks.cpp +++ b/instrumentation/otel-webserver-module/src/apache/ApacheHooks.cpp @@ -381,6 +381,11 @@ bool ApacheHooks::initialize_opentelemetry(const request_rec *r) env_config[ix].value = our_config->getOtelSamplerType(); ++ix; + // Otel Sampler Ratio + env_config[ix].name = OTEL_SDK_ENV_OTEL_SAMPLER_RATIO; + env_config[ix].value = our_config->getOtelSamplerRatio(); + ++ix; + // Service Namespace env_config[ix].name = OTEL_SDK_ENV_SERVICE_NAMESPACE; env_config[ix].value = our_config->getServiceNamespace(); diff --git a/instrumentation/otel-webserver-module/src/apache/mod_apache_otel.cpp b/instrumentation/otel-webserver-module/src/apache/mod_apache_otel.cpp index f01fdd550..e1fa78f24 100644 --- a/instrumentation/otel-webserver-module/src/apache/mod_apache_otel.cpp +++ b/instrumentation/otel-webserver-module/src/apache/mod_apache_otel.cpp @@ -94,6 +94,12 @@ static const command_rec otel_cmds[] = NULL, OR_ALL, "Type of Otel Sampler"), + AP_INIT_TAKE1( + "apacheModuleOtelSamplerRatio", + (CMD_HAND_TYPE)ApacheConfigHandlers::otel_set_otelSamplerRatio, + NULL, + OR_ALL, + "Otel Sampler Ratio for Ratio Base Sampler"), AP_INIT_TAKE1( "apacheModuleServiceName", (CMD_HAND_TYPE)ApacheConfigHandlers::otel_set_serviceName, diff --git a/instrumentation/otel-webserver-module/src/core/api/ApiUtils.cpp b/instrumentation/otel-webserver-module/src/core/api/ApiUtils.cpp index 1a2931e06..0e3918822 100755 --- a/instrumentation/otel-webserver-module/src/core/api/ApiUtils.cpp +++ b/instrumentation/otel-webserver-module/src/core/api/ApiUtils.cpp @@ -173,6 +173,8 @@ OTEL_SDK_STATUS_CODE ApiUtils::ReadSettingsFromReader( std::string otelLibraryName; std::string otelProcessorType; std::string otelSamplerType; + std::string otelSamplerRatio; + unsigned otelMaxQueueSize; unsigned otelScheduledDelayMillis; @@ -230,6 +232,9 @@ OTEL_SDK_STATUS_CODE ApiUtils::ReadSettingsFromReader( reader.ReadOptional( std::string(OTEL_SDK_ENV_OTEL_SAMPLER_TYPE), otelSamplerType); + reader.ReadOptional( + std::string(OTEL_SDK_ENV_OTEL_SAMPLER_RATIO), otelSamplerRatio); + status = ReadOptionalFromReader( reader, std::string(OTEL_SDK_ENV_MAX_QUEUE_SIZE), otelMaxQueueSize); if(OTEL_ISFAIL(status)) @@ -269,6 +274,7 @@ OTEL_SDK_STATUS_CODE ApiUtils::ReadSettingsFromReader( tenantConfig.setOtelLibraryName(otelLibraryName); tenantConfig.setOtelProcessorType(otelProcessorType); tenantConfig.setOtelSamplerType(otelSamplerType); + tenantConfig.setOtelSamplerRatio(otelSamplerRatio); tenantConfig.setOtelMaxQueueSize(otelMaxQueueSize); tenantConfig.setOtelScheduledDelayMillis(otelScheduledDelayMillis); tenantConfig.setOtelMaxExportBatchSize(otelMaxExportBatchSize); diff --git a/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkHelperFactory.cpp b/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkHelperFactory.cpp index 0082276c3..b65e5da42 100644 --- a/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkHelperFactory.cpp +++ b/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkHelperFactory.cpp @@ -38,6 +38,7 @@ namespace sdkwrapper { // NOTE : all the validation checks related to otel inputs are done in the helper factory. // So, these constants are not required outside of this execution unit + namespace { constexpr const char* OTLP_EXPORTER_TYPE = "otlp"; constexpr const char* OSSTREAM_EXPORTER_TYPE = "osstream"; @@ -45,10 +46,13 @@ namespace { constexpr const char* BATCH_PROCESSOR = "batch"; constexpr const char* ALWAYS_ON_SAMPLER = "always_on"; constexpr const char* ALWAYS_OFF_SAMPLER = "always_off"; - constexpr const char* PARENT_BASED_SAMPLER = "parent"; - constexpr const char* TRACE_ID_RATIO_BASED_SAMPLER = "trace_id_ratio"; + constexpr const char* TRACEID_RATIO_SAMPLER = "traceidratio"; + constexpr const char* PARENTBASED_ALWAYS_ON_SAMPLER = "parentbased_always_on"; + constexpr const char* PARENTBASED_ALWAYS_OFF_SAMPLER = "parentbased_always_off"; + constexpr const char* PARENTBASED_TRACEID_RATIO_SAMPLER = "parentbased_traceidratio"; } + SdkHelperFactory::SdkHelperFactory( std::shared_ptr config, const AgentLogger& logger) : @@ -192,29 +196,48 @@ OtelSpanProcessor SdkHelperFactory::GetSpanProcessor( return processor; } -OtelSampler SdkHelperFactory::GetSampler( +std::unique_ptr SdkHelperFactory::GetSampler( std::shared_ptr config) { - auto sampler = OtelSampler{}; + auto type = config->getOtelSamplerType(); + auto ratio = config->getOtelSamplerRatio(); - if (type == ALWAYS_OFF_SAMPLER) { - sampler.reset(new sdk::trace::AlwaysOffSampler); - } else if (type == TRACE_ID_RATIO_BASED_SAMPLER) { // TODO - ; - } else if (type == PARENT_BASED_SAMPLER) { // TODO - ; - } else { - if (type != ALWAYS_ON_SAMPLER) { - // default is always_on sampler - LOG4CXX_WARN(mLogger, "Received unknown sampler type: " << type << ". Will create default(always_on) sampler"); - type = ALWAYS_ON_SAMPLER; + // Parent Based Samplers + if(type == PARENTBASED_ALWAYS_ON_SAMPLER || type == PARENTBASED_ALWAYS_OFF_SAMPLER || type == PARENTBASED_TRACEID_RATIO_SAMPLER){ + + std::shared_ptr sampler; + + if(type == PARENTBASED_ALWAYS_ON_SAMPLER){ + sampler = std::make_shared(); + } + else if(type == PARENTBASED_TRACEID_RATIO_SAMPLER){ + sampler = std::make_shared(ratio); + } + else if(type == PARENTBASED_ALWAYS_OFF_SAMPLER){ + sampler = std::make_shared(); } - sampler.reset(new sdk::trace::AlwaysOnSampler); + + LOG4CXX_INFO(mLogger, "Sampler created with SamplerType : " << type); + return std::unique_ptr(new sdk::trace::ParentBasedSampler(sampler)); + } + + // Non-Parent Based Samplers + std::unique_ptr sampler; + + if(type == ALWAYS_OFF_SAMPLER) { + sampler.reset(new sdk::trace::AlwaysOffSampler()); + } + else if(type == TRACEID_RATIO_SAMPLER) { + sampler.reset(new sdk::trace::TraceIdRatioBasedSampler(ratio)); + } + // DEFAULT - ALWAYS ON + else{ + type = ALWAYS_ON_SAMPLER; + sampler.reset(new sdk::trace::AlwaysOnSampler()); } - LOG4CXX_INFO(mLogger, "Sampler created with SamplerType : " << - type); + LOG4CXX_INFO(mLogger, "Sampler created with SamplerType : " << type); return sampler; } From f6d868a8c102eec215aee6c12fee842a52420f9e Mon Sep 17 00:00:00 2001 From: "Peterson, Bruce (bp0438)" Date: Fri, 26 Jan 2024 14:09:48 -0500 Subject: [PATCH 2/2] fixed format of README --- instrumentation/otel-webserver-module/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/otel-webserver-module/README.md b/instrumentation/otel-webserver-module/README.md index b93a7f247..06cee7c69 100644 --- a/instrumentation/otel-webserver-module/README.md +++ b/instrumentation/otel-webserver-module/README.md @@ -46,7 +46,7 @@ Monitoring individual modules is crucial to the instrumentation of Apache web se |*ApacheModuleOtelSpanExporter* | otlp | OPTIONAL: Specify the span exporter to be used. Supported values are "otlp" and "ostream". All other supported values would be added in future. | |*ApacheModuleOtelExporterEndpoint:* | | REQUIRED: The endpoint otel exporter exports to. Example "docker.for.mac.localhost:4317" | |*ApacheModuleOtelSpanProcessor* | batch | OPTIONAL: Specify the processor to select to. Supported values are "simple" and "batch".| -|*ApacheModuleOtelSampler* | always_on | OPTIONAL: Supported values are "always_on", "always_off", "traceidratio", "parentbased_always_on", parentbased_always_off", "parentbased_traceidratio | +|*ApacheModuleOtelSampler* | always_on | OPTIONAL: Supported values are "always_on","always_off","traceidratio","parentbased_always_on","parentbased_always_off","parentbased_traceidratio"| |*ApacheModuleOtelSamplerRatio* | 0.0 | OPTIONAL: Supported values range from 0.0 to 1.0 and represent percent sampled| |*ApacheModuleOtelMaxQueueSize* | 2048 | OPTIONAL: The maximum queue size. After the size is reached spans are dropped| |*ApacheModuleOtelScheduledDelayMillis* | 5000 | OPTIONAL: The delay interval in milliseconds between two consecutive exports|