This is an automated email from the ASF dual-hosted git repository.
shreemaan-abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new bb70ec008 perf(zipkin): skip span tag construction for unsampled
requests (#13656)
bb70ec008 is described below
commit bb70ec008158a85cd0235fc64e1b8ad9e300c2ad
Author: Shreemaan Abhishek <[email protected]>
AuthorDate: Mon Jul 6 19:07:32 2026 +0800
perf(zipkin): skip span tag construction for unsampled requests (#13656)
---
apisix/plugins/zipkin.lua | 46 ++++++++++++++++++++----------------
docs/en/latest/plugins/skywalking.md | 6 +++++
docs/en/latest/plugins/zipkin.md | 6 +++++
t/plugin/zipkin3.t | 10 ++++++++
4 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/apisix/plugins/zipkin.lua b/apisix/plugins/zipkin.lua
index 615828bc5..fd46d0ede 100644
--- a/apisix/plugins/zipkin.lua
+++ b/apisix/plugins/zipkin.lua
@@ -182,19 +182,34 @@ function _M.rewrite(plugin_conf, ctx)
local wire_context = tracer:extract("http_headers", ctx)
- local start_timestamp = ngx.req.start_time()
- local request_span = tracer:start_span("apisix.request", {
- child_of = wire_context,
- start_timestamp = start_timestamp,
+ -- Decide sampling before building the span. The reporter drops unsampled
+ -- spans, so skip tag construction and remote-addr lookups for them.
+ if sampled == "1" or sampled == "true" then
+ per_req_sample_ratio = 1
+ elseif sampled == "0" or sampled == "false" then
+ per_req_sample_ratio = 0
+ end
+ local sample = tracer.sampler:sample(per_req_sample_ratio or
conf.sample_ratio)
+ ctx.opentracing_sample = sample
+
+ local tags
+ if sample then
tags = {
component = "apisix",
["span.kind"] = "server",
["http.method"] = ctx.var.request_method,
["http.url"] = ctx.var.request_uri,
- -- TODO: support ipv6
+ -- TODO: support ipv6
["peer.ipv4"] = core.request.get_remote_client_ip(ctx),
["peer.port"] = core.request.get_remote_client_port(ctx),
}
+ end
+
+ local start_timestamp = ngx.req.start_time()
+ local request_span = tracer:start_span("apisix.request", {
+ child_of = wire_context,
+ start_timestamp = start_timestamp,
+ tags = tags,
})
ctx.opentracing = {
@@ -203,18 +218,10 @@ function _M.rewrite(plugin_conf, ctx)
request_span = request_span,
}
- -- Process sampled
- if sampled == "1" or sampled == "true" then
- per_req_sample_ratio = 1
- elseif sampled == "0" or sampled == "false" then
- per_req_sample_ratio = 0
- end
-
- ctx.opentracing_sample = tracer.sampler:sample(per_req_sample_ratio or
conf.sample_ratio)
- if not ctx.opentracing_sample then
- request_span:set_baggage_item("x-b3-sampled","0")
+ if not sample then
+ request_span:set_baggage_item("x-b3-sampled", "0")
else
- request_span:set_baggage_item("x-b3-sampled","1")
+ request_span:set_baggage_item("x-b3-sampled", "1")
end
if plugin_info.set_ngx_var then
@@ -227,11 +234,10 @@ function _M.rewrite(plugin_conf, ctx)
ngx_var.zipkin_span_id = to_hex(span_context.span_id)
end
- if not ctx.opentracing_sample then
+ if not sample then
return
end
- local request_span = ctx.opentracing.request_span
if conf.span_version == ZIPKIN_SPAN_VER_1 then
ctx.opentracing.rewrite_span =
request_span:start_child_span("apisix.rewrite",
start_timestamp)
@@ -245,9 +251,9 @@ end
function _M.access(conf, ctx)
local opentracing = ctx.opentracing
- local tracer = opentracing.tracer
- if conf.span_version == ZIPKIN_SPAN_VER_1 then
+ if ctx.opentracing_sample and conf.span_version == ZIPKIN_SPAN_VER_1 then
+ local tracer = opentracing.tracer
opentracing.access_span = opentracing.request_span:start_child_span(
"apisix.access", ctx.REWRITE_END_TIME)
diff --git a/docs/en/latest/plugins/skywalking.md
b/docs/en/latest/plugins/skywalking.md
index d54c0d6f5..d664295c8 100644
--- a/docs/en/latest/plugins/skywalking.md
+++ b/docs/en/latest/plugins/skywalking.md
@@ -63,6 +63,12 @@ Reload APISIX for changes to take effect.
|--------------|--------|----------|---------|--------------|----------------------------------------------------------------------------|
| sample_ratio | number | False | 1 | [0.00001, 1] | Frequency of
request sampling. Setting the sample ratio to `1` means to sample all requests.
|
+:::tip Performance
+
+The plugin hooks several request phases and builds a trace per sampled
request, so tracing adds per-request overhead. Sampling is the primary lever to
control it: unsampled requests skip trace creation entirely. Lower
`sample_ratio` on high-throughput routes to reduce overhead while keeping
representative traces.
+
+:::
+
## Example
To follow along the example, start a storage, OAP and Booster UI with Docker
Compose, following [Skywalking's
documentation](https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-docker/).
Once set up, the OAP server should be listening on `12800` and you should be
able to access the UI at [http://localhost:8080](http://localhost:8080).
diff --git a/docs/en/latest/plugins/zipkin.md b/docs/en/latest/plugins/zipkin.md
index 78063a482..dccb10516 100644
--- a/docs/en/latest/plugins/zipkin.md
+++ b/docs/en/latest/plugins/zipkin.md
@@ -63,6 +63,12 @@ See the configuration file for configuration options
available to all Plugins.
|server_addr | string | False |the value of `$server_addr` | IPv4 address
| IPv4 address for the Zipkin reporter. For example, you can set this to your
external IP address. |
|span_version | integer | False | 2 | [1, 2] | Version of
the span type. |
+:::tip Performance
+
+The plugin hooks several request phases and builds a span per sampled request,
so tracing adds per-request overhead. Sampling is the primary lever to control
it: `sample_ratio` is the fraction of requests traced, and unsampled requests
skip span tag construction entirely. Lower `sample_ratio` on high-throughput
routes to reduce overhead while keeping representative traces.
+
+:::
+
## Examples
The examples below show different use cases of the `zipkin` Plugin.
diff --git a/t/plugin/zipkin3.t b/t/plugin/zipkin3.t
index d4bcd721c..d0c783523 100644
--- a/t/plugin/zipkin3.t
+++ b/t/plugin/zipkin3.t
@@ -159,3 +159,13 @@ plugin_attr:
GET /echo
--- error_log
ngx_var.zipkin_context_traceparent is empty
+
+
+
+=== TEST 6: unsampled request still builds span context for set_ngx_var
+--- request
+GET /echo
+--- more_headers
+x-b3-sampled: 0
+--- error_log eval
+qr/ngx_var.zipkin_context_traceparent:00-\w{32}-\w{16}-00/