Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(request-id): add a request ID to logs and error templates #11308

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .requirements
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ OPENSSL=3.1.2
PCRE=8.45
LIBEXPAT=2.5.0

LUA_KONG_NGINX_MODULE=4d19e8d19c6dbc07eba5cf6f5ebacad95266f928 # 0.6.0
LUA_KONG_NGINX_MODULE=8296b70ee1256b2cd59f246137b727f049174787 # 0.7.1
LUA_RESTY_LMDB=951926f20b674a0622236a0e331b359df1c02d9b # 1.3.0
LUA_RESTY_EVENTS=8448a92cec36ac04ea522e78f6496ba03c9b1fd8 # 0.2.0
LUA_RESTY_WEBSOCKET=60eafc3d7153bceb16e6327074e0afc3d94b1316 # 0.4.0
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG/unreleased/kong/11308.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
message: Add a Request ID (which matches the trace_id or correlation_id when available) to error templates and logs.
samugi marked this conversation as resolved.
Show resolved Hide resolved
type: feature
scope: Core
prs:
- 11308
jiras:
- "KAG-2034"
1 change: 1 addition & 0 deletions kong-3.5.0-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -530,5 +530,6 @@ build = {

["kong.tracing.instrumentation"] = "kong/tracing/instrumentation.lua",
["kong.tracing.propagation"] = "kong/tracing/propagation.lua",
["kong.tracing.request_id"] = "kong/tracing/request_id.lua",
}
}
4 changes: 3 additions & 1 deletion kong/error_handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local kong = kong
local find = string.find
local fmt = string.format
local utils = require "kong.tools.utils"
local request_id = require "kong.tracing.request_id"


local CONTENT_TYPE = "Content-Type"
Expand Down Expand Up @@ -64,7 +65,8 @@ return function(ctx)

else
local mime_type = utils.get_response_type(accept_header)
message = fmt(utils.get_error_template(mime_type), message)
local rid = request_id.get() or ""
message = fmt(utils.get_error_template(mime_type), message, rid)
headers = { [CONTENT_TYPE] = mime_type }

end
Expand Down
3 changes: 3 additions & 0 deletions kong/pdk/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local inspect = require "inspect"
local ngx_ssl = require "ngx.ssl"
local phase_checker = require "kong.pdk.private.phases"
local utils = require "kong.tools.utils"
local request_id = require "kong.tracing.request_id"


local sub = string.sub
Expand Down Expand Up @@ -735,6 +736,7 @@ do
-- The following fields are included in the returned table:
-- * `client_ip` - client IP address in textual format.
-- * `latencies` - request/proxy latencies.
-- * `request.id` - request id.
-- * `request.headers` - request headers.
-- * `request.method` - request method.
-- * `request.querystring` - request query strings.
Expand Down Expand Up @@ -809,6 +811,7 @@ do

local root = {
request = {
id = request_id.get() or "",
uri = request_uri,
url = var.scheme .. "://" .. var.host .. ":" .. host_port .. request_uri,
querystring = okong.request.get_query(), -- parameters, as a table
Expand Down
4 changes: 3 additions & 1 deletion kong/pdk/response.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local cjson = require "cjson.safe"
local checks = require "kong.pdk.private.checks"
local phase_checker = require "kong.pdk.private.phases"
local utils = require "kong.tools.utils"
local request_id = require "kong.tracing.request_id"


local ngx = ngx
Expand Down Expand Up @@ -1170,7 +1171,8 @@ local function new(self, major_version)
local body
if content_type ~= CONTENT_TYPE_GRPC then
local actual_message = message or get_http_error_message(status)
body = fmt(utils.get_error_template(content_type), actual_message)
local rid = request_id.get() or ""
body = fmt(utils.get_error_template(content_type), actual_message, rid)
end

local ctx = ngx.ctx
Expand Down
8 changes: 8 additions & 0 deletions kong/plugins/correlation-id/handler.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-- Copyright (C) Kong Inc.
local uuid = require "kong.tools.utils".uuid
local kong_meta = require "kong.meta"
local request_id = require "kong.tracing.request_id"


local kong = kong
Expand Down Expand Up @@ -63,6 +64,13 @@ function CorrelationIdHandler:access(conf)
end
end

if correlation_id then
local _, err = request_id.set(correlation_id, request_id.TYPES.CORR)
if err then
kong.log.notice(err)
end
end

if conf.echo_downstream then
-- For later use, to echo it back downstream
kong.ctx.plugin.correlation_id = correlation_id
Expand Down
2 changes: 2 additions & 0 deletions kong/runloop/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local meta = require "kong.meta"
local utils = require "kong.tools.utils"
local request_id = require "kong.tracing.request_id"
local Router = require "kong.router"
local balancer = require "kong.runloop.balancer"
local events = require "kong.runloop.events"
Expand Down Expand Up @@ -1118,6 +1119,7 @@ return {
local server_port = var.server_port
ctx.host_port = HOST_PORTS[server_port] or server_port
instrumentation.request(ctx)
request_id.rewrite()
end,
},
access = {
Expand Down
10 changes: 9 additions & 1 deletion kong/templates/nginx_kong.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ exit_worker_by_lua_block {
}

> if (role == "traditional" or role == "data_plane") and #proxy_listeners > 0 then
log_format request_id_access_log_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'request_id: "$kong_request_id"';

# Load variable indexes
lua_kong_load_var_index default;

Expand All @@ -76,7 +81,10 @@ server {
error_page 400 404 405 408 411 412 413 414 417 494 /kong_error_handler;
error_page 500 502 503 504 /kong_error_handler;

access_log ${{PROXY_ACCESS_LOG}};
set $kong_request_id $request_id;
lua_kong_error_log_request_id $kong_request_id;

access_log ${{PROXY_ACCESS_LOG}} request_id_access_log_format;
error_log ${{PROXY_ERROR_LOG}} ${{LOG_LEVEL}};

> if proxy_ssl_enabled then
Expand Down
7 changes: 5 additions & 2 deletions kong/tools/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1427,18 +1427,21 @@ do
<body>
<h1>Error</h1>
<p>%s.</p>
<p>request_id: %s</p>
</body>
</html>
]],
[CONTENT_TYPE_JSON] = [[
{
"message":"%s"
"message":"%s",
"request_id":"%s"
}]],
[CONTENT_TYPE_PLAIN] = "%s\n",
[CONTENT_TYPE_PLAIN] = "%s\nrequest_id: %s\n",
[CONTENT_TYPE_XML] = [[
<?xml version="1.0" encoding="UTF-8"?>
<error>
<message>%s</message>
<requestid>%s</requestid>
</error>
]],
}
Expand Down
35 changes: 26 additions & 9 deletions kong/tracing/propagation.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local to_hex = require "resty.string".to_hex
local openssl_bignum = require "resty.openssl.bn"
local request_id = require "kong.tracing.request_id"
local table_merge = require "kong.tools.utils".table_merge
local split = require "kong.tools.utils".split
local strip = require "kong.tools.utils".strip
Expand Down Expand Up @@ -589,9 +590,12 @@ local function set(conf_header_type, found_header_type, proxy_span, conf_default

found_header_type = found_header_type or conf_default_header_type or "b3"

local request_trace_id

if conf_header_type == "b3" or found_header_type == "b3"
then
set_header("x-b3-traceid", to_hex(proxy_span.trace_id))
request_trace_id = to_hex(proxy_span.trace_id)
set_header("x-b3-traceid", request_trace_id)
set_header("x-b3-spanid", to_hex(proxy_span.span_id))
if proxy_span.parent_id then
set_header("x-b3-parentspanid", to_hex(proxy_span.parent_id))
Expand All @@ -605,31 +609,35 @@ local function set(conf_header_type, found_header_type, proxy_span, conf_default
end

if conf_header_type == "b3-single" or found_header_type == "b3-single" then
set_header("b3", to_hex(proxy_span.trace_id) ..
request_trace_id = to_hex(proxy_span.trace_id)
set_header("b3", request_trace_id ..
"-" .. to_hex(proxy_span.span_id) ..
"-" .. (proxy_span.should_sample and "1" or "0") ..
(proxy_span.parent_id and "-" .. to_hex(proxy_span.parent_id) or ""))
end

if conf_header_type == "w3c" or found_header_type == "w3c" then
-- OTEL uses w3c trace context format so to_ot_trace_id works here
request_trace_id = to_hex(to_w3c_trace_id(proxy_span.trace_id))
set_header("traceparent", fmt("00-%s-%s-%s",
to_hex(to_w3c_trace_id(proxy_span.trace_id)),
request_trace_id,
to_hex(proxy_span.span_id),
proxy_span.should_sample and "01" or "00"))
end

if conf_header_type == "jaeger" or found_header_type == "jaeger" then
request_trace_id = to_hex(proxy_span.trace_id)
set_header("uber-trace-id", fmt("%s:%s:%s:%s",
to_hex(proxy_span.trace_id),
request_trace_id,
to_hex(proxy_span.span_id),
proxy_span.parent_id and to_hex(proxy_span.parent_id) or "0",
proxy_span.should_sample and "01" or "00"))
end

if conf_header_type == "ot" or found_header_type == "ot" then
to_ot_trace_id = to_ot_trace_id or require "kong.plugins.opentelemetry.otlp".to_ot_trace_id
set_header("ot-tracer-traceid", to_hex(to_ot_trace_id(proxy_span.trace_id)))
request_trace_id = to_hex(to_ot_trace_id(proxy_span.trace_id))
set_header("ot-tracer-traceid", request_trace_id)
set_header("ot-tracer-spanid", to_hex(proxy_span.span_id))
set_header("ot-tracer-sampled", proxy_span.should_sample and "1" or "0")

Expand All @@ -644,21 +652,30 @@ local function set(conf_header_type, found_header_type, proxy_span, conf_default
end

if conf_header_type == "aws" or found_header_type == "aws" then
local trace_id = to_hex(proxy_span.trace_id)
request_trace_id = to_hex(proxy_span.trace_id)

set_header("x-amzn-trace-id", "Root=" .. AWS_TRACE_ID_VERSION .. "-" ..
sub(trace_id, 1, AWS_TRACE_ID_TIMESTAMP_LEN) .. "-" ..
sub(trace_id, AWS_TRACE_ID_TIMESTAMP_LEN + 1, #trace_id) ..
sub(request_trace_id, 1, AWS_TRACE_ID_TIMESTAMP_LEN) .. "-" ..
sub(request_trace_id, AWS_TRACE_ID_TIMESTAMP_LEN + 1, #request_trace_id) ..
";Parent=" .. to_hex(proxy_span.span_id) .. ";Sampled=" ..
(proxy_span.should_sample and "1" or "0")
)
end

if conf_header_type == "gcp" or found_header_type == "gcp" then
set_header("x-cloud-trace-context", to_gcp_trace_id(to_hex(proxy_span.trace_id)) ..
request_trace_id = to_gcp_trace_id(to_hex(proxy_span.trace_id))
set_header("x-cloud-trace-context", request_trace_id ..
"/" .. openssl_bignum.from_binary(proxy_span.span_id):to_dec() ..
";o=" .. (proxy_span.should_sample and "1" or "0")
)
end

if request_trace_id then
local _, err = request_id.set(request_trace_id, request_id.TYPES.TRACE)
if err then
kong.log.notice(err)
end
end
end


Expand Down
Loading