diff --git a/kong/plugins/zipkin/handler.lua b/kong/plugins/zipkin/handler.lua index a6c6ffa8cc2..96d570f1dd7 100644 --- a/kong/plugins/zipkin/handler.lua +++ b/kong/plugins/zipkin/handler.lua @@ -131,6 +131,14 @@ if subsystem == "http" then request_span:set_tag("http.method", method) request_span:set_tag("http.path", req.get_path()) + local static_tags = conf.static_tags + if type(static_tags) == "table" then + for i = 1, #static_tags do + local tag = static_tags[i] + request_span:set_tag(tag.name, tag.value) + end + end + ctx.zipkin = { request_span = request_span, header_type = header_type, @@ -205,6 +213,14 @@ elseif subsystem == "stream" then request_span:set_tag("lc", "kong") + local static_tags = conf.static_tags + if type(static_tags) == "table" then + for i = 1, #static_tags do + local tag = static_tags[i] + request_span:set_tag(tag.name, tag.value) + end + end + ctx.zipkin = { request_span = request_span, proxy_span = nil, diff --git a/kong/plugins/zipkin/schema.lua b/kong/plugins/zipkin/schema.lua index 22eb3d79347..8f76d8355c0 100644 --- a/kong/plugins/zipkin/schema.lua +++ b/kong/plugins/zipkin/schema.lua @@ -1,4 +1,44 @@ local typedefs = require "kong.db.schema.typedefs" +local Schema = require "kong.db.schema" + +local PROTECTED_TAGS = { + "error", + "http.method", + "http.path", + "http.status_code", + "kong.balancer.state", + "kong.balancer.try", + "kong.consumer", + "kong.credential", + "kong.node.id", + "kong.route", + "kong.service", + "lc", + "peer.hostname", +} + +local static_tag = Schema.define { + type = "record", + fields = { + { name = { type = "string", required = true, not_one_of = PROTECTED_TAGS } }, + { value = { type = "string", required = true } }, + }, +} + +local validate_static_tags = function(tags) + if type(tags) ~= "table" then + return true + end + local found = {} + for i = 1, #tags do + local name = tags[i].name + if found[name] then + return nil, "repeated tags are not allowed: " .. name + end + found[name] = true + end + return true +end return { name = "zipkin", @@ -15,6 +55,8 @@ return { { traceid_byte_count = { type = "integer", required = true, default = 16, one_of = { 8, 16 } } }, { header_type = { type = "string", required = true, default = "preserve", one_of = { "preserve", "b3", "b3-single", "w3c" } } }, + { static_tags = { type = "array", elements = static_tag, + custom_validator = validate_static_tags } } }, }, }, }, diff --git a/spec/schema_spec.lua b/spec/schema_spec.lua new file mode 100644 index 00000000000..df920cd48be --- /dev/null +++ b/spec/schema_spec.lua @@ -0,0 +1,22 @@ +local schema_def = require "kong.plugins.zipkin.schema" +local v = require("spec.helpers").validate_plugin_config_schema + +describe("Plugin: Zipkin (schema)", function() + it("rejects repeated tags", function() + local ok, err = v({ + http_endpoint = "http://example.dev", + static_tags = { + { name = "foo", value = "bar" }, + { name = "foo", value = "baz" }, + }, + }, schema_def) + + assert.is_falsy(ok) + assert.same({ + config = { + static_tags = "repeated tags are not allowed: foo" + } + }, err) + end) +end) + diff --git a/spec/zipkin_spec.lua b/spec/zipkin_spec.lua index 06cbbae5800..bad532dfd95 100644 --- a/spec/zipkin_spec.lua +++ b/spec/zipkin_spec.lua @@ -160,6 +160,9 @@ describe("http integration tests with zipkin server [#" sample_ratio = 1, http_endpoint = fmt("http://%s:%d/api/v2/spans", ZIPKIN_HOST, ZIPKIN_PORT), traceid_byte_count = traceid_byte_count, + static_tags = { + { name = "static", value = "ok" }, + } } }) @@ -239,7 +242,8 @@ describe("http integration tests with zipkin server [#" ["http.method"] = "GET", ["http.path"] = "/", ["http.status_code"] = "200", -- found (matches server status) - lc = "kong" + lc = "kong", + static = "ok", }, request_tags) local consumer_port = request_span.remoteEndpoint.port assert_is_integer(consumer_port) @@ -312,7 +316,8 @@ describe("http integration tests with zipkin server [#" ["http.method"] = "POST", ["http.path"] = "/hello.HelloService/SayHello", ["http.status_code"] = "200", -- found (matches server status) - lc = "kong" + lc = "kong", + static = "ok", }, request_tags) local consumer_port = request_span.remoteEndpoint.port assert_is_integer(consumer_port) @@ -393,7 +398,10 @@ describe("http integration tests with zipkin server [#" local request_tags = request_span.tags assert.truthy(request_tags["kong.node.id"]:match("^[%x-]+$")) request_tags["kong.node.id"] = nil - assert.same({ lc = "kong" }, request_tags) + assert.same({ + lc = "kong", + static = "ok", + }, request_tags) local consumer_port = request_span.remoteEndpoint.port assert_is_integer(consumer_port) assert.same({ @@ -484,7 +492,8 @@ describe("http integration tests with zipkin server [#" ["http.method"] = "GET", ["http.path"] = "/foobar", ["http.status_code"] = "404", -- note that this was "not found" - lc = "kong" + lc = "kong", + static = "ok", }, request_tags) local consumer_port = request_span.remoteEndpoint.port assert_is_integer(consumer_port)