diff --git a/instrumentation/otel-webserver-module/README.md b/instrumentation/otel-webserver-module/README.md index b1626c07a..fb09376be 100644 --- a/instrumentation/otel-webserver-module/README.md +++ b/instrumentation/otel-webserver-module/README.md @@ -60,6 +60,7 @@ Monitoring individual modules is crucial to the instrumentation of Apache web se |*ApacheModuleSegmentParameter* | | OPTIONAL: Specify the segment count or segment numbers that you want to display for Span Creation| |*ApacheModuleOtelExporterHeaders* | | OPTIONAL: OTEL Exporter header info or Metadata like API key for OTLP endpoint. a list of key value pairs, and these are expected to be represented in a format matching to the W3C Correlation-Context, except that additional semi-colon delimited metadata is not supported, i.e.: key1=value1,key2=value2. | + A sample configuration is mentioned in [opentelemetry_module.conf](https://github.com/cisco-open/otel-webserver-module/blob/main/opentelemetry_module.conf) ### Build and Installation @@ -176,6 +177,7 @@ Currently, Nginx Webserver module monitores some fixed set of modules, which get |*NginxModuleRequestHeaders* | | OPTIONAL: Specify the request headers to be captured in the span attributes. The headers are Case-Sensitive and should be comma-separated. e.g.```NginxModuleRequestHeaders Accept-Charset,Accept-Encoding,User-Agent;```| |*NginxModuleResponseHeaders* | | OPTIONAL: Specify the response headers to be captured in the span attributes. The headers are Case-Sensitive and should be comma-separated. e.g.```NginxModuleResponseHeaders Content-Length,Content-Type;```| |*NginxModuleOtelExporterOtlpHeaders* | | OPTIONAL: OTEL exporter headers like Meta data related exposrted end point. a list of key value pairs, and these are expected to be represented in a format matching to the W3C Correlation-Context, except that additional semi-colon delimited metadata is not supported, i.e.: key1=value1,key2=value2.| +|*NginxModuleTrustIncomingSpans* | | OPTIONAL: Enables or disables using spans from incoming requests as parent for created ones. (default: ON).| ### Build and Installation #### Prerequisites diff --git a/instrumentation/otel-webserver-module/conf/nginx/opentelemetry_module.conf b/instrumentation/otel-webserver-module/conf/nginx/opentelemetry_module.conf index e3eb6ed2d..3b8a837c0 100644 --- a/instrumentation/otel-webserver-module/conf/nginx/opentelemetry_module.conf +++ b/instrumentation/otel-webserver-module/conf/nginx/opentelemetry_module.conf @@ -19,4 +19,5 @@ NginxModuleResolveBackends ON; NginxModuleTraceAsError ON; #NginxModuleWebserverContext DemoService DemoServiceNamespace DemoInstanceId #NginxModuleSegmentType custom -#NginxModuleSegmentParameter 15,1,6,7 \ No newline at end of file +#NginxModuleSegmentParameter 15,1,6,7 +NginxModuleTrustIncomingSpans ON; \ No newline at end of file diff --git a/instrumentation/otel-webserver-module/include/core/sdkwrapper/SdkWrapper.h b/instrumentation/otel-webserver-module/include/core/sdkwrapper/SdkWrapper.h index a8f5d5dcf..2b51e2489 100644 --- a/instrumentation/otel-webserver-module/include/core/sdkwrapper/SdkWrapper.h +++ b/instrumentation/otel-webserver-module/include/core/sdkwrapper/SdkWrapper.h @@ -40,6 +40,7 @@ class SdkWrapper : public ISdkWrapper{ void PopulatePropagationHeaders( std::unordered_map& carrier) override; + //opentelemetry::trace::SpanContext GetCurrentSpan(opentelemetry::context::Context context); private: trace::SpanKind GetTraceSpanKind(const SpanKind& kind); diff --git a/instrumentation/otel-webserver-module/src/core/sdkwrapper/ScopedSpan.cpp b/instrumentation/otel-webserver-module/src/core/sdkwrapper/ScopedSpan.cpp index 399244d47..b0e7181fb 100644 --- a/instrumentation/otel-webserver-module/src/core/sdkwrapper/ScopedSpan.cpp +++ b/instrumentation/otel-webserver-module/src/core/sdkwrapper/ScopedSpan.cpp @@ -30,6 +30,7 @@ ScopedSpan::ScopedSpan( { trace::StartSpanOptions options{}; options.kind = kind; + //options.parent = GetCurrentSpan(incomingContext); mSpan = sdkHelperFactory->GetTracer()->StartSpan(name, attributes, options); mScope.reset(new trace::Scope(mSpan)); mSpanKind = kind; diff --git a/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkWrapper.cpp b/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkWrapper.cpp index 25ac06c27..d4921fcd3 100644 --- a/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkWrapper.cpp +++ b/instrumentation/otel-webserver-module/src/core/sdkwrapper/SdkWrapper.cpp @@ -67,6 +67,15 @@ std::shared_ptr SdkWrapper::CreateSpan( } } +/*opentelemetry::trace::SpanContext SdkWrapper::GetCurrentSpan(opentelemetry::context::Context context) { + opentelemetry::context::ContextValue span = context.GetValue(trace::kSpanKey); + if (nostd::holds_alternative>(span)) { + return nostd::get>(span).get()->GetContext(); + } + + return trace::SpanContext::GetInvalid(); +}*/ + void SdkWrapper::PopulatePropagationHeaders( std::unordered_map& carrier) { diff --git a/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.c b/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.c index 2ba03510b..52f9caf93 100644 --- a/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.c +++ b/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.c @@ -286,6 +286,13 @@ static ngx_command_t ngx_http_opentelemetry_commands[] = { offsetof(ngx_http_opentelemetry_loc_conf_t, nginxModuleTraceAsError), NULL}, + { ngx_string("NginxModuleTrustIncomingSpans"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_opentelemetry_loc_conf_t, nginxModuleTrustIncomingSpans), + NULL}, + { ngx_string("NginxModuleReportAllInstrumentedModules"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_flag_slot, @@ -437,6 +444,7 @@ static void* ngx_http_opentelemetry_create_loc_conf(ngx_conf_t *cf) conf->nginxModuleTraceAsError = NGX_CONF_UNSET; conf->nginxModuleOtelMaxQueueSize = NGX_CONF_UNSET; conf->nginxModuleOtelSslEnabled = NGX_CONF_UNSET; + conf->nginxModuleTrustIncomingSpans = NGX_CONF_UNSET; return conf; } @@ -453,6 +461,7 @@ static char* ngx_http_opentelemetry_merge_loc_conf(ngx_conf_t *cf, void *parent, ngx_conf_merge_value(conf->nginxModuleTraceAsError, prev->nginxModuleTraceAsError, 0); ngx_conf_merge_value(conf->nginxModuleMaskCookie, prev->nginxModuleMaskCookie, 0); ngx_conf_merge_value(conf->nginxModuleMaskSmUser, prev->nginxModuleMaskSmUser, 0); + ngx_conf_merge_value(conf->nginxModuleTrustIncomingSpans, prev->nginxModuleTrustIncomingSpans, 1); ngx_conf_merge_str_value(conf->nginxModuleOtelSpanExporter, prev->nginxModuleOtelSpanExporter, ""); ngx_conf_merge_str_value(conf->nginxModuleOtelExporterEndpoint, prev->nginxModuleOtelExporterEndpoint, ""); @@ -711,11 +720,13 @@ static OTEL_SDK_STATUS_CODE otel_startInteraction(ngx_http_request_t* r, const c if(ctx && ctx->otel_req_handle_key) { ngx_flag_t resolveBackends = false; + ngx_flag_t trustIncomingSpans = false; ngx_http_opentelemetry_loc_conf_t* conf; conf = ngx_http_get_module_loc_conf(r, ngx_http_opentelemetry_module); if(conf) { resolveBackends = conf->nginxModuleResolveBackends; + trustIncomingSpans = conf->nginxModuleTrustIncomingSpans; } OTEL_SDK_ENV_RECORD* propagationHeaders = ngx_pcalloc(r->pool, 5 * sizeof(OTEL_SDK_ENV_RECORD)); if (propagationHeaders == NULL) @@ -757,6 +768,7 @@ static void otel_payload_decorator(ngx_http_request_t* r, OTEL_SDK_ENV_RECORD* p ngx_http_core_main_conf_t *cmcf; ngx_uint_t nelts; + part = &r->headers_in.headers.part; header = (ngx_table_elt_t*)part->elts; nelts = part->nelts; @@ -1477,6 +1489,7 @@ static void traceConfig(ngx_http_request_t *r, ngx_http_opentelemetry_loc_conf_t "(ReportAllInstrumentedModules=\"%ld\")" "(MaskCookie=\"%ld\")" "(MaskSmUser=\"%ld\")" + "(TrustIncomingSpans=\"%ld\")" "(SegmentType=\"%s\")" "(SegmentParameter=\"%s\")" " }", @@ -1500,6 +1513,7 @@ static void traceConfig(ngx_http_request_t *r, ngx_http_opentelemetry_loc_conf_t conf->nginxModuleReportAllInstrumentedModules, conf->nginxModuleMaskCookie, conf->nginxModuleMaskSmUser, + conf->nginxModuleTrustIncomingSpans, (conf->nginxModuleSegmentType).data, (conf->nginxModuleSegmentParameter).data); } diff --git a/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.h b/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.h index 1d73d70eb..172d0f033 100644 --- a/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.h +++ b/instrumentation/otel-webserver-module/src/nginx/ngx_http_opentelemetry_module.h @@ -91,6 +91,7 @@ typedef struct { ngx_flag_t nginxModuleReportAllInstrumentedModules; ngx_flag_t nginxModuleResolveBackends; ngx_flag_t nginxModuleTraceAsError; + ngx_flag_t nginxModuleTrustIncomingSpans; ngx_flag_t nginxModuleMaskCookie; ngx_flag_t nginxModuleMaskSmUser; ngx_str_t nginxModuleCookieMatchPattern;