This is an automated email from the ASF dual-hosted git repository.

baoyuan 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 8e5f240be feat(datadog): Improve Datadog plugin tag support (#11943)
8e5f240be is described below

commit 8e5f240be3188b016dcd6cae14f80fc98853ab4f
Author: Deiwin Sarjas <dei...@users.noreply.github.com>
AuthorDate: Mon Jul 28 12:53:27 2025 +0300

    feat(datadog): Improve Datadog plugin tag support (#11943)
---
 apisix/plugins/datadog.lua        |  83 ++++++++++++++----
 docs/en/latest/plugins/datadog.md |  14 +++-
 t/plugin/datadog.t                | 172 ++++++++++++++++++++++++++------------
 3 files changed, 193 insertions(+), 76 deletions(-)

diff --git a/apisix/plugins/datadog.lua b/apisix/plugins/datadog.lua
index 972c0a2c7..c720f4216 100644
--- a/apisix/plugins/datadog.lua
+++ b/apisix/plugins/datadog.lua
@@ -24,6 +24,9 @@ local udp = ngx.socket.udp
 local format = string.format
 local concat = table.concat
 local tostring = tostring
+local ipairs = ipairs
+local floor = math.floor
+local unpack = unpack
 
 local plugin_name = "datadog"
 local defaults = {
@@ -34,10 +37,33 @@ local defaults = {
 }
 
 local batch_processor_manager = bp_manager_mod.new(plugin_name)
+
+-- Shared schema for individual tag strings.
+local tag_schema = {
+    type = "string",
+    -- Tags must be between 1 and 200 characters.
+    minLength = 1,
+    maxLength = 200,
+    -- Tags must follow the Datadog tag format:
+    --   - `^[\p{L}]`: Must start with any kind of Unicode letter.
+    --   - `[\p{L}\p{N}_.:/-]*`: Followed by Unicode letters (\p{L}), numbers 
(\p{N}),
+    --     or the allowed special characters (underscore, hyphen, colon,
+    --     period, and slash).
+    --   - `(?<!:)$`: Must not end with a colon.
+    pattern = [[^[\p{L}][\p{L}\p{N}_.:/-]*(?<!:)$]]
+}
+
 local schema = {
     type = "object",
     properties = {
-        prefer_name = {type = "boolean", default = true}
+        prefer_name = {type = "boolean", default = true},
+        include_path = {type = "boolean", default = false},
+        include_method = {type = "boolean", default = false},
+        constant_tags = {
+            type = "array",
+            items = tag_schema,
+            default = {}
+        }
     }
 }
 
@@ -49,7 +75,7 @@ local metadata_schema = {
         namespace = {type = "string", default = defaults.namespace},
         constant_tags = {
             type = "array",
-            items = {type = "string"},
+            items = tag_schema,
             default = defaults.constant_tags
         }
     },
@@ -80,25 +106,32 @@ local function generate_tag(entry, const_tags)
         tags = {}
     end
 
-    if entry.route_id and entry.route_id ~= "" then
-        core.table.insert(tags, "route_name:" .. entry.route_id)
+    if entry.constant_tags and #entry.constant_tags > 0 then
+        for _, tag in ipairs(entry.constant_tags) do
+            core.table.insert(tags, tag)
+        end
     end
 
-    if entry.service_id and entry.service_id ~= "" then
-        core.table.insert(tags, "service_name:" .. entry.service_id)
-    end
+    local variable_tags = {
+        {"route_name", entry.route_id},
+        {"path", entry.path},
+        {"method", entry.method},
+        {"service_name", entry.service_id},
+        {"consumer", entry.consumer and entry.consumer.username},
+        {"balancer_ip", entry.balancer_ip},
+        {"response_status", entry.response.status},
+        {
+            "response_status_class",
+            entry.response.status and floor(entry.response.status / 100) .. 
"xx"
+        },
+        {"scheme", entry.scheme}
+    }
 
-    if entry.consumer and entry.consumer.username then
-        core.table.insert(tags, "consumer:" .. entry.consumer.username)
-    end
-    if entry.balancer_ip ~= "" then
-        core.table.insert(tags, "balancer_ip:" .. entry.balancer_ip)
-    end
-    if entry.response.status then
-        core.table.insert(tags, "response_status:" .. entry.response.status)
-    end
-    if entry.scheme ~= "" then
-        core.table.insert(tags, "scheme:" .. entry.scheme)
+    for _, tag in ipairs(variable_tags) do
+        local key, value = unpack(tag)
+        if value and value ~= "" then
+            core.table.insert(tags, key .. ":" .. value)
+        end
     end
 
     if #tags > 0 then
@@ -241,6 +274,20 @@ function _M.log(conf, ctx)
         end
     end
 
+    if conf.include_path then
+        if ctx.curr_req_matched and ctx.curr_req_matched._path then
+            entry.path = ctx.curr_req_matched._path
+        end
+    end
+
+    if conf.include_method then
+        entry.method = ctx.var.method
+    end
+
+    if conf.constant_tags and #conf.constant_tags > 0 then
+        entry.constant_tags = core.table.clone(conf.constant_tags)
+    end
+
     if batch_processor_manager:add_entry(conf, entry) then
         return
     end
diff --git a/docs/en/latest/plugins/datadog.md 
b/docs/en/latest/plugins/datadog.md
index 4b2d5b47c..5cf6c8cea 100644
--- a/docs/en/latest/plugins/datadog.md
+++ b/docs/en/latest/plugins/datadog.md
@@ -41,9 +41,12 @@ This Plugin provides the ability to push metrics as a batch 
to the external Data
 
 ## Attributes
 
-| Name        | Type    | Required | Default | Valid values | Description      
                                                                      |
-| ----------- | ------- | -------- | ------- | ------------ | 
--------------------------------------------------------------------------------------
 |
-| prefer_name | boolean | False    | true    | [true,false] | When set to 
`false`, uses Route/Service ID instead of name (default) with metric tags. |
+| Name           | Type    | Required | Default | Valid values | Description   
                                                                                
                   |
+| -------------- | ------- | -------- | ------- | ------------ | 
----------------------------------------------------------------------------------------------------------------
 |
+| prefer_name    | boolean | False    | true    | [true,false] | When set to 
`false`, uses Route/Service ID instead of name (default) with metric tags.      
                     |
+| include_path   | boolean | False    | false   | [true,false] | When set to 
`true`, includes the path pattern in metric tags.                               
                     |
+| include_method | boolean | False    | false   | [true,false] | When set to 
`true`, includes the HTTP method in metric tags.                                
                     |
+| constant_tags  | array   | False    | []      |              | Static tags 
to embed into all metrics generated by this route. Useful for grouping metrics 
over certain signals. |
 
 This Plugin supports using batch processors to aggregate and process entries 
(logs/data) in a batch. This avoids the need for frequently submitting the 
data. The batch processor submits data every `5` seconds or when the data in 
the queue reaches `1000`. See [Batch 
Processor](../batch-processor.md#configuration) for more information or setting 
your custom configuration.
 
@@ -113,8 +116,11 @@ The metrics will be sent to the DogStatsD agent with the 
following tags:
 - `service_name`: If a Route has been created with an abstracted Service, the 
Service name/ID based on the attribute `prefer_name`.
 - `consumer`: If the Route is linked to a Consumer, the username will be added 
as a tag.
 - `balancer_ip`: IP address of the Upstream balancer that processed the 
current request.
-- `response_status`: HTTP response status code.
+- `response_status`: HTTP response status code. E.g. "200", "404", "503".
+- `response_status_class`: HTTP response status code class. E.g. "2xx", "4xx", 
"5xx".
 - `scheme`: Request scheme such as HTTP, gRPC, and gRPCs.
+- `path`: The HTTP path pattern. Only available if the attribute 
`include_path` is set to true.
+- `method`: The HTTP method. Only available if the attribute `include_method` 
is set to true.
 
 :::note
 
diff --git a/t/plugin/datadog.t b/t/plugin/datadog.t
index 506abcc0f..a06b030df 100644
--- a/t/plugin/datadog.t
+++ b/t/plugin/datadog.t
@@ -147,12 +147,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -188,18 +188,18 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -242,12 +242,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: mycompany(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
mycompany\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
mycompany\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
mycompany\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
mycompany\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
mycompany\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
mycompany\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
mycompany\.request\.counter:1\|c\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
mycompany\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
mycompany\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
mycompany\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
mycompany\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
mycompany\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -293,12 +293,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:datadog,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -353,12 +353,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -432,12 +432,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:route-1,service_name:service-1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -491,12 +491,12 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,new_tag:must,route_name:1,service_name:1,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
 
 
@@ -528,10 +528,74 @@ opentracing
 --- grep_error_log eval
 qr/message received: apisix(.+?(?=, ))/
 --- grep_error_log_out eval
-qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
-message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,scheme:http
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_name:datadog,consumer:user0,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
 /
+
+
+
+=== TEST 11: testing behaviour with include_path, include_method, and route 
level constant_tags
+--- apisix_yaml
+routes:
+  - uri: /articles/*/comments
+    name: datadog
+    upstream:
+      nodes:
+        "127.0.0.1:1982": 1
+    plugins:
+      datadog:
+        batch_max_size: 1
+        max_retry_count: 0
+        include_path: true
+        include_method: true
+        constant_tags:
+          - route_tag1:foo
+          - route_tag2:bar
+      proxy-rewrite:
+        uri: /opentracing
+#END
+--- request
+GET /articles/12345/comments?foo=bar
+--- response_body
+opentracing
+--- wait: 0.5
+--- grep_error_log eval
+qr/message received: apisix(.+?(?=, ))/
+--- grep_error_log_out eval
+qr/message received: 
apisix\.request\.counter:1\|c\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.request\.latency:[\d.]+\|h\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.upstream\.latency:[\d.]+\|h\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.apisix\.latency:[\d.]+\|h\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.ingress\.size:[\d]+\|ms\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+message received: 
apisix\.egress\.size:[\d]+\|ms\|#source:apisix,route_tag1:foo,route_tag2:bar,route_name:datadog,path:\/articles\/\*\/comments,method:GET,balancer_ip:[\d.]+,response_status:200,response_status_class:2xx,scheme:http
+/
+
+
+
+=== TEST 12: fails on invalid constant_tags value
+--- apisix_yaml
+routes:
+  - uri: /articles/*/comments
+    name: datadog
+    upstream:
+      nodes:
+        "127.0.0.1:1982": 1
+    plugins:
+      datadog:
+        batch_max_size: 1
+        max_retry_count: 0
+        constant_tags:
+          - "1 invalid tag"
+      proxy-rewrite:
+        uri: /opentracing
+#END
+--- request
+GET /articles/12345/comments?foo=bar
+--- error_code: 404
+--- wait: 0.5
+--- error_log
+property "constant_tags" validation failed

Reply via email to