This is an automated email from the ASF dual-hosted git repository.
monkeydluffy 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 595672c8d feat(zipkin): add variable (#10361)
595672c8d is described below
commit 595672c8dfb4de188bfcd67af0892437270a35f3
Author: wizhuo <[email protected]>
AuthorDate: Fri Oct 27 12:23:03 2023 +0800
feat(zipkin): add variable (#10361)
---
apisix/cli/ngx_tpl.lua | 8 +++
apisix/cli/ops.lua | 9 ++-
apisix/plugins/zipkin.lua | 22 ++++++-
conf/config-default.yaml | 2 +
docs/en/latest/plugins/zipkin.md | 29 +++++++++
docs/zh/latest/plugins/zipkin.md | 29 +++++++++
t/cli/test_zipkin_set_ngx_var.sh | 48 +++++++++++++++
t/plugin/zipkin3.t | 129 +++++++++++++++++++++++++++++++++++++++
8 files changed, 274 insertions(+), 2 deletions(-)
diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index cd652a9b1..3e1aadd9b 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -643,6 +643,14 @@ http {
{% end %}
# opentelemetry_set_ngx_var ends
+ # zipkin_set_ngx_var starts
+ {% if zipkin_set_ngx_var then %}
+ set $zipkin_context_traceparent '';
+ set $zipkin_trace_id '';
+ set $zipkin_span_id '';
+ {% end %}
+ # zipkin_set_ngx_var ends
+
# http server configuration snippet starts
{% if http_server_configuration_snippet then %}
{* http_server_configuration_snippet *}
diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index a5a6975d8..0eaebae56 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -546,6 +546,12 @@ Please modify "admin_key" in conf/config.yaml .
if enabled_plugins["opentelemetry"] and
yaml_conf.plugin_attr["opentelemetry"] then
opentelemetry_set_ngx_var =
yaml_conf.plugin_attr["opentelemetry"].set_ngx_var
end
+
+ local zipkin_set_ngx_var
+ if enabled_plugins["zipkin"] and yaml_conf.plugin_attr["zipkin"] then
+ zipkin_set_ngx_var = yaml_conf.plugin_attr["zipkin"].set_ngx_var
+ end
+
-- Using template.render
local sys_conf = {
lua_path = env.pkg_path_org,
@@ -566,7 +572,8 @@ Please modify "admin_key" in conf/config.yaml .
control_server_addr = control_server_addr,
prometheus_server_addr = prometheus_server_addr,
proxy_mirror_timeouts = proxy_mirror_timeouts,
- opentelemetry_set_ngx_var = opentelemetry_set_ngx_var
+ opentelemetry_set_ngx_var = opentelemetry_set_ngx_var,
+ zipkin_set_ngx_var = zipkin_set_ngx_var
}
if not yaml_conf.apisix then
diff --git a/apisix/plugins/zipkin.lua b/apisix/plugins/zipkin.lua
index 0c0c4748d..efebd5115 100644
--- a/apisix/plugins/zipkin.lua
+++ b/apisix/plugins/zipkin.lua
@@ -20,13 +20,17 @@ local zipkin_codec = require("apisix.plugins.zipkin.codec")
local new_random_sampler = require("apisix.plugins.zipkin.random_sampler").new
local new_reporter = require("apisix.plugins.zipkin.reporter").new
local ngx = ngx
+local ngx_var = ngx.var
local ngx_re = require("ngx.re")
local pairs = pairs
local tonumber = tonumber
+local to_hex = require "resty.string".to_hex
local plugin_name = "zipkin"
local ZIPKIN_SPAN_VER_1 = 1
local ZIPKIN_SPAN_VER_2 = 2
+local plugin = require("apisix.plugin")
+local string_format = string.format
local lrucache = core.lrucache.new({
@@ -69,6 +73,8 @@ function _M.check_schema(conf)
return core.schema.check(schema, conf)
end
+local plugin_info = plugin.plugin_attr(plugin_name) or {}
+
local function create_tracer(conf,ctx)
conf.route_id = ctx.route_id
@@ -205,9 +211,23 @@ function _M.rewrite(plugin_conf, ctx)
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")
+ else
+ request_span:set_baggage_item("x-b3-sampled","1")
+ end
+
+ if plugin_info.set_ngx_var then
+ local span_context = request_span:context()
+ ngx_var.zipkin_context_traceparent = string_format("00-%s-%s-%02x",
+ to_hex(span_context.trace_id),
+ to_hex(span_context.span_id),
+
span_context:get_baggage_item("x-b3-sampled"))
+ ngx_var.zipkin_trace_id = span_context.trace_id
+ ngx_var.zipkin_span_id = span_context.span_id
+ end
+
+ if not ctx.opentracing_sample then
return
end
- request_span:set_baggage_item("x-b3-sampled","1")
local request_span = ctx.opentracing.request_span
if conf.span_version == ZIPKIN_SPAN_VER_1 then
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 3267480f0..38d67823e 100755
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -615,6 +615,8 @@ plugin_attr: # Plugin attributes
hooks_file: "/usr/local/apisix/plugin_inspect_hooks.lua" # Set the path
to the Lua file that defines
# hooks. Only
administrators should have
# write access
to this file for security.
+ zipkin: # Plugin: zipkin
+ set_ngx_var: false # export zipkin variables to nginx
variables
deployment: # Deployment configurations
role: traditional # Set deployment mode: traditional,
control_plane, or data_plane.
diff --git a/docs/en/latest/plugins/zipkin.md b/docs/en/latest/plugins/zipkin.md
index 2a772e608..16d89bec8 100644
--- a/docs/en/latest/plugins/zipkin.md
+++ b/docs/en/latest/plugins/zipkin.md
@@ -235,3 +235,32 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
}
}'
```
+
+## Variables
+
+The following nginx variables are set by zipkin:
+
+- `zipkin_context_traceparent` - [W3C trace
context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format),
e.g.: `00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01`
+- `zipkin_trace_id` - Trace Id of the current span
+- `zipkin_span_id` - Span Id of the current span
+
+How to use variables? you have to add it to your configuration file
(`conf/config.yaml`):
+
+```yaml title="./conf/config.yaml"
+http:
+ enable_access_log: true
+ access_log: "/dev/stdout"
+ access_log_format: '{"time": "$time_iso8601","zipkin_context_traceparent":
"$zipkin_context_traceparent","zipkin_trace_id":
"$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr":
"$remote_addr","uri": "$uri"}'
+ access_log_format_escape: json
+plugins:
+ - zipkin
+plugin_attr:
+ zipkin:
+ set_ngx_var: true
+```
+
+You can also include a trace_id when printing logs
+
+```print error log
+log.error(ngx.ERR,ngx_var.zipkin_trace_id,"error message")
+```
diff --git a/docs/zh/latest/plugins/zipkin.md b/docs/zh/latest/plugins/zipkin.md
index 6f6e0d2b8..c43321f5f 100644
--- a/docs/zh/latest/plugins/zipkin.md
+++ b/docs/zh/latest/plugins/zipkin.md
@@ -235,3 +235,32 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
}
}'
```
+
+## 如何使用变量
+
+以下`nginx`变量是由`zipkin` 设置的。
+
+- `zipkin_context_traceparent` - [W3C trace
context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format),
例如:`00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01`
+- `zipkin_trace_id` - 当前 span 的 trace_id
+- `zipkin_span_id` - 当前 span 的 span_id
+
+如何使用?你需要在配置文件(`./conf/config.yaml`)设置如下:
+
+```yaml title="./conf/config.yaml"
+http:
+ enable_access_log: true
+ access_log: "/dev/stdout"
+ access_log_format: '{"time": "$time_iso8601","zipkin_context_traceparent":
"$zipkin_context_traceparent","zipkin_trace_id":
"$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr":
"$remote_addr","uri": "$uri"}'
+ access_log_format_escape: json
+plugins:
+ - zipkin
+plugin_attr:
+ zipkin:
+ set_ngx_var: true
+```
+
+你也可以在打印日志的时候带上 `trace_id`
+
+```print error log
+log.error(ngx.ERR,ngx_var.zipkin_trace_id,"error message")
+```
diff --git a/t/cli/test_zipkin_set_ngx_var.sh b/t/cli/test_zipkin_set_ngx_var.sh
new file mode 100755
index 000000000..3ddd02155
--- /dev/null
+++ b/t/cli/test_zipkin_set_ngx_var.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+. ./t/cli/common.sh
+
+echo '
+plugins:
+ - zipkin
+plugin_attr:
+ zipkin:
+ set_ngx_var: true
+' > conf/config.yaml
+
+make init
+
+if ! grep "set \$zipkin_context_traceparent '';" conf/nginx.conf >
/dev/null; then
+ echo "failed: zipkin_context_traceparent not found in nginx.conf"
+ exit 1
+fi
+
+if ! grep "set \$zipkin_trace_id '';" conf/nginx.conf >
/dev/null; then
+ echo "failed: zipkin_trace_id not found in nginx.conf"
+ exit 1
+fi
+
+if ! grep "set \$zipkin_span_id '';" conf/nginx.conf >
/dev/null; then
+ echo "failed: zipkin_span_id not found in nginx.conf"
+ exit 1
+fi
+
+
+echo "passed: zipkin_set_ngx_var configuration is validated"
diff --git a/t/plugin/zipkin3.t b/t/plugin/zipkin3.t
new file mode 100644
index 000000000..f3aef6b5d
--- /dev/null
+++ b/t/plugin/zipkin3.t
@@ -0,0 +1,129 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+log_level("info");
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->extra_yaml_config) {
+ my $extra_yaml_config = <<_EOC_;
+plugins:
+ - zipkin
+plugin_attr:
+ zipkin:
+ set_ngx_var: true
+_EOC_
+ $block->set_value("extra_yaml_config", $extra_yaml_config);
+ }
+
+ my $upstream_server_config = $block->upstream_server_config // <<_EOC_;
+ set \$zipkin_context_traceparent "";
+ set \$zipkin_trace_id "";
+ set \$zipkin_span_id "";
+_EOC_
+
+ $block->set_value("upstream_server_config", $upstream_server_config);
+
+ my $extra_init_by_lua = <<_EOC_;
+ local zipkin = require("apisix.plugins.zipkin")
+ local orig_func = zipkin.access
+ zipkin.access = function (...)
+ local traceparent = ngx.var.zipkin_context_traceparent
+ if traceparent == nil or traceparent == '' then
+ ngx.log(ngx.ERR,"ngx_var.zipkin_context_traceparent is empty")
+ else
+
ngx.log(ngx.ERR,"ngx_var.zipkin_context_traceparent:",ngx.var.zipkin_context_traceparent)
+ end
+
+ local orig = orig_func(...)
+ return orig
+ end
+_EOC_
+
+ $block->set_value("extra_init_by_lua", $extra_init_by_lua);
+
+ if (!$block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+ $block;
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: add plugin metadata
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "zipkin": {
+ "endpoint":
"http://127.0.0.1:9999/mock_zipkin",
+ "sample_ratio": 1
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/echo"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 2: trigger zipkin with open set variables
+--- request
+GET /echo
+--- error_log eval
+qr/ngx_var.zipkin_context_traceparent:00-\w{32}-\w{16}-01*/
+
+
+
+=== TEST 3: trigger zipkin with disable set variables
+--- yaml_config
+plugin_attr:
+ zipkin:
+ set_ngx_var: false
+--- request
+GET /echo
+--- error_log
+ngx_var.zipkin_context_traceparent is empty