diff --git a/changelog/unreleased/kong/otel-sampling-panic-when-header-trace-id-enable.yml b/changelog/unreleased/kong/otel-sampling-panic-when-header-trace-id-enable.yml new file mode 100644 index 00000000000..5efdededa3b --- /dev/null +++ b/changelog/unreleased/kong/otel-sampling-panic-when-header-trace-id-enable.yml @@ -0,0 +1,3 @@ +message: "**Opentelemetry**: fix otel sampling mode lua panic bug when http_response_header_for_traceid option enable" +type: bugfix +scope: Plugin diff --git a/kong/plugins/opentelemetry/handler.lua b/kong/plugins/opentelemetry/handler.lua index b2f1f7e0db2..a265e57c21f 100644 --- a/kong/plugins/opentelemetry/handler.lua +++ b/kong/plugins/opentelemetry/handler.lua @@ -158,8 +158,10 @@ function OpenTelemetryHandler:header_filter(conf) local root_span = ngx.ctx.KONG_SPANS and ngx.ctx.KONG_SPANS[1] trace_id = root_span and root_span.trace_id end - trace_id = to_hex(trace_id) - kong.response.add_header(conf.http_response_header_for_traceid, trace_id) + if trace_id then + trace_id = to_hex(trace_id) + kong.response.add_header(conf.http_response_header_for_traceid, trace_id) + end end end diff --git a/spec/03-plugins/37-opentelemetry/05-otelcol_spec.lua b/spec/03-plugins/37-opentelemetry/05-otelcol_spec.lua index ca4fb585e38..5a96f3ffd3e 100644 --- a/spec/03-plugins/37-opentelemetry/05-otelcol_spec.lua +++ b/spec/03-plugins/37-opentelemetry/05-otelcol_spec.lua @@ -120,6 +120,34 @@ for _, strategy in helpers.each_strategy() do return #parts > 0 end, 10) end) + + it("send traces with config http_response_header_for_traceid enable and tracing_sampling_rate option", function() + assert(helpers.restart_kong { + database = strategy, + nginx_conf = "spec/fixtures/custom_nginx.template", + plugins = "opentelemetry", + tracing_instrumentations = "all", + tracing_sampling_rate = 0.00005, + }) + + proxy_url = fmt("http://%s:%s", helpers.get_proxy_ip(), helpers.get_proxy_port()) + proxy_url_enable_traceid = fmt("http://%s:%s/enable_response_header_traceid", helpers.get_proxy_ip(), helpers.get_proxy_port()) + + local httpc = http.new() + for i = 1, 100 do + local res, err = httpc:request_uri(proxy_url_enable_traceid) + assert.is_nil(err) + assert.same(200, res.status) + if res.headers["x-trace-id"] then + local trace_id = res.headers["x-trace-id"] + local trace_id_regex = [[^[a-f0-9]{32}$]] + local m = ngx.re.match(trace_id, trace_id_regex, "jo") + assert.True(m ~= nil, "trace_id does not match regex: " .. trace_id_regex) + end + end + httpc:close() + end) + end) end)