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

Reply via email to