Skip to content

Commit f52a34c

Browse files
samugichronolawdndx
authored
feat(src): request id (#65 + #70) (#73)
* feat(error_log): custom error handler (#65) * Defines a new error log handler and a directive lua_kong_error_log_request_id that enable configuring a Request ID from the value of an nginx variable, to append to the error log. * includes tests for the new directive * tests(*): fix github workflow Co-authored-by: Chrono <[email protected]> Co-authored-by: Datong Sun <[email protected]> * tests(stream): fix mockbin failing tests * feat(variables): add new variable `$kong_request_id` (#70) Similar to `$request_id`, but from pseudo-random number source instead of OpenSSL's `RAND_bytes` for better performance. KAG-2734 --------- Co-authored-by: Chrono <[email protected]> Co-authored-by: Datong Sun <[email protected]>
1 parent a2829b1 commit f52a34c

11 files changed

+704
-16
lines changed

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ Table of Contents
1111
* [Install](#install)
1212
* [Directives](#directives)
1313
* [lua_kong_load_var_index](#lua_kong_load_var_index)
14+
* [lua\_kong\_error\_log\_request\_id](#lua_kong_error_log_request_id)
1415
* [Methods](#methods)
1516
* [resty.kong.tls.request\_client\_certificate](#restykongtlsrequest_client_certificate)
17+
* [Variables](#variables)
18+
* [$kong\_request\_id](#kong_request_id)
1619
* [resty.kong.tls.disable\_session\_reuse](#restykongtlsdisable_session_reuse)
1720
* [resty.kong.tls.get\_full\_client\_certificate\_chain](#restykongtlsget_full_client_certificate_chain)
1821
* [resty.kong.tls.set\_upstream\_cert\_and\_key](#restykongtlsset_upstream_cert_and_key)
@@ -121,6 +124,25 @@ indexed variable access.
121124

122125
[Back to TOC](#table-of-contents)
123126

127+
lua\_kong\_error\_log\_request\_id
128+
-------------------------------------------
129+
**syntax:** *lua_kong_error_log_request_id $variable;*
130+
131+
**context:** *http* *server* *location*
132+
133+
Append a Request ID to the standard error log format, load the ID value from `$variable`. `$variable` must be previously defined.
134+
135+
For example, with this configuration:
136+
```
137+
lua_kong_error_log_request_id $request_id;
138+
```
139+
An error log line may look similar to the following:
140+
```
141+
2023/09/06 11:33:36 [error] 94085#0: *6 [lua] content_by_lua(nginx.conf:27):7: hello world, client: 127.0.0.1, server: , request: "GET /foo HTTP/1.1", host: "localhost:8080", request_id: "cd7706e903db672ac5fac333bc8db5ed"
142+
```
143+
144+
[Back to TOC](#table-of-contents)
145+
124146
Methods
125147
=======
126148

@@ -147,6 +169,16 @@ This function returns `true` when the call is successful. Otherwise it returns
147169

148170
[Back to TOC](#table-of-contents)
149171

172+
Variables
173+
=========
174+
175+
$kong\_request\_id
176+
------------------
177+
Unique request identifier generated from 16 pseudo-random bytes, in hexadecimal.
178+
This variable is indexed.
179+
180+
[Back to TOC](#table-of-contents)
181+
150182
resty.kong.tls.disable\_session\_reuse
151183
--------------------------------------
152184
**syntax:** *succ, err = resty.kong.tls.disable\_session\_reuse()*
@@ -398,7 +430,7 @@ License
398430
=======
399431

400432
```
401-
Copyright 2020 Kong Inc.
433+
Copyright 2020-2023 Kong Inc.
402434
403435
Licensed under the Apache License, Version 2.0 (the "License");
404436
you may not use this file except in compliance with the License.

config

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ ngx_module_srcs=" \
44
$ngx_addon_dir/src/ngx_http_lua_kong_apple_m1.c \
55
$ngx_addon_dir/src/ngx_http_lua_kong_grpc.c \
66
$ngx_addon_dir/src/ngx_http_lua_kong_ssl.c \
7-
$ngx_addon_dir/src/ngx_http_lua_kong_var.c \
7+
$ngx_addon_dir/src/ngx_http_lua_kong_var_index.c \
88
$ngx_addon_dir/src/ngx_http_lua_kong_module.c \
9+
$ngx_addon_dir/src/ngx_http_lua_kong_log_handler.c \
10+
$ngx_addon_dir/src/ngx_http_lua_kong_vars.c \
911
"
1012

1113
ngx_module_incs="$ngx_addon_dir/src"

src/ngx_http_lua_kong_common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ typedef struct {
3333
unsigned upstream_ssl_verify:1;
3434
unsigned upstream_ssl_verify_set:1;
3535
unsigned upstream_ssl_verify_depth_set:1;
36+
ngx_http_log_handler_pt orig_log_handler;
3637
} ngx_http_lua_kong_ctx_t;
3738

3839

40+
typedef struct {
41+
ngx_int_t request_id_var_index;
42+
} ngx_http_lua_kong_loc_conf_t;
43+
44+
3945
#ifdef NGX_LUA_USE_ASSERT
4046
#include <assert.h>
4147
# define ngx_http_lua_kong_assert(a) assert(a)
@@ -48,4 +54,10 @@ extern ngx_module_t ngx_http_lua_kong_module;
4854
ngx_http_lua_kong_ctx_t *ngx_http_lua_kong_get_module_ctx(
4955
ngx_http_request_t *r);
5056

57+
char *ngx_http_lua_kong_error_log_init(
58+
ngx_conf_t *cf);
59+
60+
ngx_int_t
61+
ngx_http_lua_kong_add_vars(ngx_conf_t *cf);
62+
5163
#endif /* _NGX_HTTP_LUA_KONG_COMMON_H_INCLUDED_ */

src/ngx_http_lua_kong_directive.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,8 @@ char *
2626
ngx_http_lua_kong_load_var_index(ngx_conf_t *cf, ngx_command_t *cmd,
2727
void *conf);
2828

29+
char *
30+
ngx_http_lua_kong_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd,
31+
void *conf);
32+
2933
#endif /* _NGX_HTTP_LUA_KONG_DIRECTIVE_H_INCLUDED_ */

src/ngx_http_lua_kong_log_handler.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/**
2+
* Copyright 2019-2023 Kong Inc.
3+
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "ngx_http_lua_kong_common.h"
18+
19+
20+
/*
21+
* This function contains the logic to append the Request ID to
22+
* the error log line when being called
23+
*/
24+
static u_char *
25+
ngx_http_lua_kong_error_log_handler(ngx_http_request_t *r, u_char *buf, size_t len)
26+
{
27+
ngx_http_variable_value_t *value;
28+
ngx_http_lua_kong_loc_conf_t *lcf;
29+
30+
lcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_kong_module);
31+
if (lcf->request_id_var_index == NGX_CONF_UNSET) {
32+
return buf;
33+
}
34+
35+
value = ngx_http_get_indexed_variable(r, lcf->request_id_var_index);
36+
if (value == NULL || value->not_found) {
37+
return buf;
38+
}
39+
40+
buf = ngx_snprintf(buf, len, ", request_id: \"%v\"", value);
41+
42+
return buf;
43+
}
44+
45+
46+
/*
47+
* This function replaces the original HTTP error
48+
* log handler (r->log_handler). It executes the original logic
49+
* and then our error log handler: ngx_http_lua_kong_error_log_handler
50+
*/
51+
static u_char *
52+
ngx_http_lua_kong_combined_error_log_handler(ngx_http_request_t *r,
53+
ngx_http_request_t *sr, u_char *buf, size_t len)
54+
{
55+
u_char *p;
56+
ngx_http_lua_kong_ctx_t *ctx;
57+
58+
ctx = ngx_http_lua_kong_get_module_ctx(r);
59+
if (ctx == NULL || ctx->orig_log_handler == NULL) {
60+
return buf;
61+
}
62+
63+
/* original log handler */
64+
p = ctx->orig_log_handler(r, sr, buf, len);
65+
len -= p - buf;
66+
buf = p;
67+
68+
/* Kong log handler */
69+
buf = ngx_http_lua_kong_error_log_handler(r, buf, len);
70+
71+
return buf;
72+
}
73+
74+
75+
static ngx_int_t
76+
ngx_http_lua_kong_replace_error_log_handler(ngx_http_request_t *r)
77+
{
78+
ngx_http_lua_kong_ctx_t *ctx;
79+
80+
ctx = ngx_http_lua_kong_get_module_ctx(r);
81+
if (ctx == NULL) {
82+
return NGX_ERROR;
83+
}
84+
85+
if (r->log_handler == NULL) {
86+
return NGX_DECLINED;
87+
}
88+
89+
/*
90+
* Store the original log handler in ctx->orig_log_handler, replace
91+
* it with the combined log handler, which will execute the original
92+
* handler's logic in addition to our own.
93+
*/
94+
ctx->orig_log_handler = r->log_handler;
95+
r->log_handler = ngx_http_lua_kong_combined_error_log_handler;
96+
97+
return NGX_DECLINED;
98+
}
99+
100+
101+
char *
102+
ngx_http_lua_kong_error_log_init(ngx_conf_t *cf)
103+
{
104+
ngx_http_handler_pt *h;
105+
ngx_http_core_main_conf_t *cmcf;
106+
107+
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
108+
109+
h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers);
110+
if (h == NULL) {
111+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
112+
"failed setting error log handler");
113+
return NGX_CONF_ERROR;
114+
}
115+
116+
*h = ngx_http_lua_kong_replace_error_log_handler;
117+
118+
return NGX_CONF_OK;
119+
}
120+
121+
122+
char *
123+
ngx_http_lua_kong_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
124+
{
125+
ngx_str_t *value;
126+
ngx_http_lua_kong_loc_conf_t *lcf = conf;
127+
128+
value = cf->args->elts;
129+
130+
if (value[1].data[0] != '$') {
131+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
132+
"invalid variable name \"%V\"", &value[1]);
133+
return NGX_CONF_ERROR;
134+
}
135+
136+
value[1].len--;
137+
value[1].data++;
138+
139+
lcf->request_id_var_index = ngx_http_get_variable_index(cf, &value[1]);
140+
if (lcf->request_id_var_index == NGX_ERROR) {
141+
return NGX_CONF_ERROR;
142+
}
143+
144+
return NGX_CONF_OK;
145+
}
146+
147+

src/ngx_http_lua_kong_module.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020

2121

2222
static ngx_int_t ngx_http_lua_kong_init(ngx_conf_t *cf);
23+
static void* ngx_http_lua_kong_create_loc_conf(ngx_conf_t* cf);
24+
static char* ngx_http_lua_kong_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
2325

2426

2527
static ngx_http_module_t ngx_http_lua_kong_module_ctx = {
26-
NULL, /* preconfiguration */
28+
ngx_http_lua_kong_add_vars, /* preconfiguration */
2729
ngx_http_lua_kong_init, /* postconfiguration */
2830

2931
NULL, /* create main configuration */
@@ -32,8 +34,8 @@ static ngx_http_module_t ngx_http_lua_kong_module_ctx = {
3234
NULL, /* create server configuration */
3335
NULL, /* merge server configuration */
3436

35-
NULL, /* create location configuration */
36-
NULL /* merge location configuration */
37+
ngx_http_lua_kong_create_loc_conf, /* create location configuration */
38+
ngx_http_lua_kong_merge_loc_conf /* merge location configuration */
3739
};
3840

3941
static ngx_command_t ngx_http_lua_kong_commands[] = {
@@ -45,6 +47,13 @@ static ngx_command_t ngx_http_lua_kong_commands[] = {
4547
0,
4648
NULL },
4749

50+
{ ngx_string("lua_kong_error_log_request_id"),
51+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
52+
ngx_http_lua_kong_error_log_request_id,
53+
NGX_HTTP_LOC_CONF_OFFSET,
54+
offsetof(ngx_http_lua_kong_loc_conf_t, request_id_var_index),
55+
NULL },
56+
4857
ngx_null_command
4958
};
5059

@@ -68,6 +77,10 @@ ngx_module_t ngx_http_lua_kong_module = {
6877
static ngx_int_t
6978
ngx_http_lua_kong_init(ngx_conf_t *cf)
7079
{
80+
if (ngx_http_lua_kong_error_log_init(cf) != NGX_CONF_OK) {
81+
return NGX_ERROR;
82+
}
83+
7184
return ngx_http_lua_kong_ssl_init(cf);
7285
}
7386

@@ -112,3 +125,32 @@ ngx_http_lua_kong_get_module_ctx(ngx_http_request_t *r)
112125
}
113126

114127

128+
static void *
129+
ngx_http_lua_kong_create_loc_conf(ngx_conf_t* cf)
130+
{
131+
ngx_http_lua_kong_loc_conf_t *conf;
132+
133+
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_kong_loc_conf_t));
134+
if (conf == NULL) {
135+
return NULL;
136+
}
137+
138+
conf->request_id_var_index = NGX_CONF_UNSET;
139+
140+
return conf;
141+
}
142+
143+
144+
static char*
145+
ngx_http_lua_kong_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
146+
{
147+
ngx_http_lua_kong_loc_conf_t *prev = parent;
148+
ngx_http_lua_kong_loc_conf_t *conf = child;
149+
150+
/* conf->tag is NGX_HTTP_LOC_CONF only */
151+
ngx_conf_merge_value(conf->request_id_var_index, prev->request_id_var_index, NGX_CONF_UNSET);
152+
153+
return NGX_CONF_OK;
154+
}
155+
156+

src/ngx_http_lua_kong_var.c renamed to src/ngx_http_lua_kong_var_index.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static ngx_str_t default_vars[] = {
7272
ngx_string("server_addr"),
7373
ngx_string("server_port"),
7474

75-
/* --with-http_ssl_module */
75+
/* --with-http_ssl_module */
7676
#if (NGX_SSL)
7777
ngx_string("ssl_cipher"),
7878
ngx_string("ssl_client_raw_cert"),
@@ -86,6 +86,9 @@ static ngx_str_t default_vars[] = {
8686
ngx_string("upstream_http_upgrade"),
8787
ngx_string("upstream_status"),
8888

89+
/* lua-kong-module vars */
90+
ngx_string("kong_request_id"),
91+
8992
ngx_null_string
9093
};
9194

0 commit comments

Comments
 (0)