Skip to content
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

Otel webserver samplers #368

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion instrumentation/otel-webserver-module/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand All @@ -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; }

Expand All @@ -88,6 +90,8 @@ class TenantConfig

std::string otelProcessorType;
std::string otelSamplerType;
double otelSamplerRatio;


unsigned otelMaxQueueSize;
unsigned otelScheduledDelayMillis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,21 @@ 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";
constexpr const char* SIMPLE_PROCESSOR = "simple";
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<TenantConfig> config,
const AgentLogger& logger) :
Expand Down Expand Up @@ -192,29 +196,48 @@ OtelSpanProcessor SdkHelperFactory::GetSpanProcessor(
return processor;
}

OtelSampler SdkHelperFactory::GetSampler(
std::unique_ptr<sdk::trace::Sampler> SdkHelperFactory::GetSampler(
std::shared_ptr<TenantConfig> 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<sdk::trace::Sampler> sampler;

if(type == PARENTBASED_ALWAYS_ON_SAMPLER){
sampler = std::make_shared<sdk::trace::AlwaysOnSampler>();
}
else if(type == PARENTBASED_TRACEID_RATIO_SAMPLER){
sampler = std::make_shared<sdk::trace::TraceIdRatioBasedSampler>(ratio);
}
else if(type == PARENTBASED_ALWAYS_OFF_SAMPLER){
sampler = std::make_shared<sdk::trace::AlwaysOffSampler>();
}
sampler.reset(new sdk::trace::AlwaysOnSampler);

LOG4CXX_INFO(mLogger, "Sampler created with SamplerType : " << type);
return std::unique_ptr<sdk::trace::ParentBasedSampler>(new sdk::trace::ParentBasedSampler(sampler));
}

// Non-Parent Based Samplers
std::unique_ptr<sdk::trace::Sampler> 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;
}

Expand Down
Loading