Skip to content

Commit ca6ec64

Browse files
committed
Merge remote-tracking branch 'x-qdo/b3multi-headers-propagation' into b3-multi
2 parents 0bf4ec5 + 3fc6239 commit ca6ec64

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

instrumentation/nginx/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ be started. The default propagator is W3C.
169169
The same inheritance rules as [`proxy_set_header`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header) apply, which means this directive is applied at the current configuration level if and only if there are no `proxy_set_header` directives defined on a lower level.
170170

171171
- **required**: `false`
172-
- **syntax**: `opentelemetry_propagate` or `opentelemetry_propagate b3`
172+
- **syntax**: `opentelemetry_propagate` or `opentelemetry_propagate b3` or `opentelemetry_propagate b3multi`
173173
- **block**: `http`, `server`, `location`
174174

175175
### `opentelemetry_capture_headers`
@@ -255,6 +255,7 @@ The following nginx variables are set by the instrumentation:
255255

256256
- `opentelemetry_context_traceparent` - [W3C trace context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format), e.g.: `00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01`
257257
- `opentelemetry_context_b3` - Trace context in the [B3 format](https://github.com/openzipkin/b3-propagation#single-header). Only set when using `opentelemetry_propagate b3`.
258+
- `opentelemetry_sampled` - does current Span records information, "1" or "0"
258259
- `opentelemetry_trace_id` - Trace Id of the current span
259260
- `opentelemetry_span_id` - Span Id of the current span
260261

instrumentation/nginx/src/otel_ngx_module.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ OtelGetTraceId(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t
143143
static ngx_int_t
144144
OtelGetSpanId(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t data);
145145

146+
static ngx_int_t
147+
OtelGetSampled(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t data);
148+
146149
static ngx_http_variable_t otel_ngx_variables[] = {
147150
{
148151
ngx_string("otel_ctx"),
@@ -176,6 +179,14 @@ static ngx_http_variable_t otel_ngx_variables[] = {
176179
NGX_HTTP_VAR_NOCACHEABLE | NGX_HTTP_VAR_NOHASH,
177180
0,
178181
},
182+
{
183+
ngx_string("opentelemetry_sampled"),
184+
nullptr,
185+
OtelGetSampled,
186+
0,
187+
NGX_HTTP_VAR_NOCACHEABLE | NGX_HTTP_VAR_NOHASH,
188+
0,
189+
},
179190
ngx_http_null_variable,
180191
};
181192

@@ -224,6 +235,38 @@ nostd::string_view WithoutOtelVarPrefix(ngx_str_t value) {
224235
return {(const char*)value.data + prefixLength, value.len - prefixLength};
225236
}
226237

238+
static ngx_int_t
239+
OtelGetSampled(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t data) {
240+
TraceContext* traceContext = GetTraceContext(req);
241+
242+
if (traceContext == nullptr || !traceContext->request_span) {
243+
ngx_log_error(
244+
NGX_LOG_ERR, req->connection->log, 0,
245+
"Unable to get trace context when getting span id");
246+
return NGX_OK;
247+
}
248+
249+
trace::SpanContext spanContext = traceContext->request_span->GetContext();
250+
251+
if (spanContext.IsValid()) {
252+
u_char* isSampled = spanContext.trace_flags().IsSampled() ? (u_char*) "1" : (u_char*) "0";
253+
254+
v->len = strlen((const char*)isSampled);
255+
v->valid = 1;
256+
v->no_cacheable = 1;
257+
v->not_found = 0;
258+
v->data = isSampled;
259+
} else {
260+
v->len = 0;
261+
v->valid = 0;
262+
v->no_cacheable = 1;
263+
v->not_found = 1;
264+
v->data = nullptr;
265+
}
266+
267+
return NGX_OK;
268+
}
269+
227270
static ngx_int_t
228271
OtelGetTraceContextVar(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t data) {
229272
if (!IsOtelEnabled(req)) {
@@ -778,6 +821,17 @@ std::vector<HeaderPropagation> B3PropagationVars() {
778821
};
779822
}
780823

824+
std::vector<HeaderPropagation> B3MultiPropagationVars() {
825+
return {
826+
{"proxy_set_header", "x-b3-traceid", "$opentelemetry_trace_id"},
827+
{"proxy_set_header", "x-b3-spanid", "$opentelemetry_span_id"},
828+
{"proxy_set_header", "x-b3-sampled", "$opentelemetry_sampled"},
829+
{"fastcgi_param", "HTTP_B3_TRACEID", "$opentelemetry_trace_id"},
830+
{"fastcgi_param", "HTTP_B3_SPANID", "$opentelemetry_span_id"},
831+
{"fastcgi_param", "HTTP_B3_SAMPLED", "$opentelemetry_sampled"},
832+
};
833+
}
834+
781835
std::vector<HeaderPropagation> OtelPropagationVars() {
782836
return {
783837
{"proxy_set_header", "traceparent", "$opentelemetry_context_traceparent"},
@@ -798,6 +852,8 @@ char* OtelNgxSetPropagation(ngx_conf_t* conf, ngx_command_t*, void* locConf) {
798852

799853
if (propagationType == "b3") {
800854
locationConf->propagationType = TracePropagationB3;
855+
} else if (propagationType == "b3multi") {
856+
locationConf->propagationType = TracePropagationB3Multi;
801857
} else if (propagationType == "w3c") {
802858
locationConf->propagationType = TracePropagationW3C;
803859
} else {
@@ -811,6 +867,8 @@ char* OtelNgxSetPropagation(ngx_conf_t* conf, ngx_command_t*, void* locConf) {
811867
std::vector<HeaderPropagation> propagationVars;
812868
if (locationConf->propagationType == TracePropagationB3) {
813869
propagationVars = B3PropagationVars();
870+
} else if (locationConf->propagationType == TracePropagationB3Multi) {
871+
propagationVars = B3MultiPropagationVars();
814872
} else {
815873
propagationVars = OtelPropagationVars();
816874
}

instrumentation/nginx/src/propagate.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ opentelemetry::context::Context ExtractContext(OtelCarrier* carrier) {
7979
case TracePropagationW3C: {
8080
return OtelW3CPropagator().Extract(textMapCarrier, root);
8181
}
82+
case TracePropagationB3Multi: {
83+
return OtelB3MultiPropagator().Extract(textMapCarrier, root);
84+
}
8285
case TracePropagationB3: {
8386
if (HasHeader(carrier->req, "b3")) {
8487
return OtelB3Propagator().Extract(textMapCarrier, root);
@@ -104,6 +107,10 @@ void InjectContext(OtelCarrier* carrier, opentelemetry::context::Context context
104107
OtelB3Propagator().Inject(textMapCarrier, context);
105108
break;
106109
}
110+
case TracePropagationB3Multi: {
111+
OtelB3MultiPropagator().Inject(textMapCarrier, context);
112+
break;
113+
}
107114
default:
108115
break;
109116
}

instrumentation/nginx/src/trace_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum TracePropagationType {
1515
TracePropagationUnset,
1616
TracePropagationW3C,
1717
TracePropagationB3,
18+
TracePropagationB3Multi,
1819
};
1920

2021
struct TraceContext {

0 commit comments

Comments
 (0)