[PATCH] Log: Added "json" parameter which escapes backslashes in logs
Khramov Anton
anton at endocode.com
Thu May 26 08:38:38 UTC 2016
# HG changeset patch
# User Khramov Anton <anton at endocode.com>
# Date 1464194463 -7200
# Wed May 25 18:41:03 2016 +0200
# Node ID 2e8a8398f0e2e928bdc4088e5999b1ebf481fd7c
# Parent bc6fd7afeed6f7433c60634d9b0867ea3241b217
Log: Added "json" parameter which escapes backslashes in logs
This patch makes JSON log format not being broken when nginx
escapes special characters, i.e. "/?var=\x22hello, world\x22"
log entry with json parameter will look like:
"/?var=\\x22hello, world\\x22",
diff -r bc6fd7afeed6 -r 2e8a8398f0e2 src/http/modules/ngx_http_log_module.c
--- a/src/http/modules/ngx_http_log_module.c Tue May 24 21:54:32 2016 +0300
+++ b/src/http/modules/ngx_http_log_module.c Wed May 25 18:41:03 2016 +0200
@@ -20,13 +20,14 @@
ngx_http_log_op_t *op);
typedef size_t (*ngx_http_log_op_getlen_pt) (ngx_http_request_t *r,
- uintptr_t data);
+ uintptr_t data, ngx_uint_t json);
struct ngx_http_log_op_s {
size_t len;
ngx_http_log_op_getlen_pt getlen;
ngx_http_log_op_run_pt run;
+ ngx_uint_t json;
uintptr_t data;
};
@@ -69,6 +70,7 @@
ngx_syslog_peer_t *syslog_peer;
ngx_http_log_fmt_t *format;
ngx_http_complex_value_t *filter;
+ ngx_uint_t json;
} ngx_http_log_t;
@@ -128,10 +130,10 @@
static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf,
ngx_http_log_op_t *op, ngx_str_t *value);
static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r,
- uintptr_t data);
+ uintptr_t data, ngx_uint_t json);
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
+static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size, ngx_uint_t json);
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
@@ -288,8 +290,9 @@
len = 0;
op = log[l].format->ops->elts;
for (i = 0; i < log[l].format->ops->nelts; i++) {
+ op[i].json = log[l].json;
if (op[i].len == 0) {
- len += op[i].getlen(r, op[i].data);
+ len += op[i].getlen(r, op[i].data, log[l].json);
} else {
len += op[i].len;
@@ -928,7 +931,7 @@
static size_t
-ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
+ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data, ngx_uint_t json)
{
uintptr_t len;
ngx_http_variable_value_t *value;
@@ -939,10 +942,14 @@
return 1;
}
- len = ngx_http_log_escape(NULL, value->data, value->len);
+ len = ngx_http_log_escape(NULL, value->data, value->len, json);
value->escape = len ? 1 : 0;
+ if (json) {
+ return value->len + len * 4;
+ }
+
return value->len + len * 3;
}
@@ -963,13 +970,13 @@
return ngx_cpymem(buf, value->data, value->len);
} else {
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
+ return (u_char *) ngx_http_log_escape(buf, value->data, value->len, op->json);
}
}
static uintptr_t
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
+ngx_http_log_escape(u_char *dst, u_char *src, size_t size, ngx_uint_t json)
{
ngx_uint_t n;
static u_char hex[] = "0123456789ABCDEF";
@@ -1012,6 +1019,9 @@
while (size) {
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ if (json) {
+ *dst++ = '\\';
+ }
*dst++ = '\\';
*dst++ = 'x';
*dst++ = hex[*src >> 4];
@@ -1129,6 +1139,8 @@
return NGX_CONF_ERROR;
}
+ log->json = 0;
+
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
fmt = lmcf->formats.elts;
@@ -1147,6 +1159,7 @@
ssize_t size;
ngx_int_t gzip;
+ ngx_int_t json;
ngx_uint_t i, n;
ngx_msec_t flush;
ngx_str_t *value, name, s;
@@ -1270,6 +1283,7 @@
size = 0;
flush = 0;
gzip = 0;
+ json = 0;
for (i = 3; i < cf->args->nelts; i++) {
@@ -1359,6 +1373,12 @@
continue;
}
+ if (ngx_strncmp(value[i].data, "json", 4) == 0)
+ {
+ json = 1;
+ continue;
+ }
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
@@ -1371,6 +1391,10 @@
return NGX_CONF_ERROR;
}
+ if (json) {
+ log->json = 1;
+ }
+
if (size) {
if (log->script) {
More information about the nginx-devel
mailing list