bzp2010 commented on code in PR #12686:
URL: https://github.com/apache/apisix/pull/12686#discussion_r2741788327
##########
apisix/plugins/opentelemetry.lua:
##########
@@ -376,49 +377,101 @@ function _M.rewrite(conf, api_ctx)
ngx_var.opentelemetry_span_id = span_context.span_id
end
+ if not ctx:span():is_recording() and ngx.ctx.tracing then
+ ngx.ctx.tracing.skip = true
+ end
+
api_ctx.otel_context_token = ctx:attach()
-- inject trace context into the headers of upstream HTTP request
trace_context_propagator:inject(ctx, ngx.req)
end
-function _M.delayed_body_filter(conf, api_ctx)
- if api_ctx.otel_context_token and ngx.arg[2] then
- local ctx = context:current()
- ctx:detach(api_ctx.otel_context_token)
- api_ctx.otel_context_token = nil
+local function create_child_span(tracer, parent_span_ctx, spans, span_idx)
+ local span = spans[span_idx]
+ if not span or span.finished then
+ return
+ end
+ span.finished = true
+ local new_span_ctx, new_span = tracer:start(parent_span_ctx, span.name,
+ {
+ kind = span.kind,
+ attributes = span.attributes,
+ })
+ new_span.start_time = span.start_time
+
+ for _, idx in ipairs(span.child_ids or {}) do
+ create_child_span(tracer, new_span_ctx, spans, idx)
+ end
+ if span.status then
+ new_span:set_status(span.status.code, span.status.message)
+ end
+ new_span:finish(span.end_time)
+end
- -- get span from current context
- local span = ctx:span()
- local upstream_status = core.response.get_upstream_status(api_ctx)
- if upstream_status and upstream_status >= 500 then
- span:set_status(span_status.ERROR,
- "upstream response status: " .. upstream_status)
- end
- span:set_attributes(attr.int("http.status_code", upstream_status))
+local function inject_core_spans(root_span_ctx, api_ctx, conf)
+ local tracing = api_ctx.ngx_ctx.tracing
+ if not tracing then
+ return
+ end
- span:finish()
+ local span = root_span_ctx:span()
+
+ local metadata = plugin.plugin_metadata(plugin_name)
+ local plugin_info = metadata.value
+ if span and not span:is_recording() then
+ return
+ end
+ local inject_conf = {
+ sampler = {
+ name = "always_on",
+ options = conf.sampler.options
+ },
+ additional_attributes = conf.additional_attributes,
+ additional_header_prefix_attributes =
conf.additional_header_prefix_attributes
+ }
+ local tracer, err = core.lrucache.plugin_ctx(lrucache, api_ctx, nil,
+ create_tracer_obj,
inject_conf, plugin_info)
+ if not tracer then
+ core.log.error("failed to fetch tracer object: ", err)
+ return
+ end
+
+ if #tracing.spans == 0 then
+ return
+ end
+ span.start_time = tracing.spans[1].start_time
+ for i, _ in ipairs(tracing.spans or {}) do
+ create_child_span(tracer, root_span_ctx, tracing.spans, i)
end
end
--- body_filter maybe not called because of empty http body response
--- so we need to check if the span has finished in log phase
function _M.log(conf, api_ctx)
if api_ctx.otel_context_token then
-- ctx:detach() is not necessary, because of ctx is stored in ngx.ctx
local upstream_status = core.response.get_upstream_status(api_ctx)
-- get span from current context
- local span = context:current():span()
+ local ctx = context:current()
+ local span = ctx:span()
if upstream_status and upstream_status >= 500 then
span:set_status(span_status.ERROR,
"upstream response status: " .. upstream_status)
end
+ inject_core_spans(ctx, api_ctx, conf)
+ span:set_attributes(attr.int("http.status_code", upstream_status))
Review Comment:
Pls use `http.response.status_code` to comply with the OTEL semantic
conventions.
https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]