-
-
Save erikcw/e999e1fb438dbbb91533 to your computer and use it in GitHub Desktop.
# Dependencies | |
# nginx_lua | |
# lua uuid module (luarocks install uuid) | |
http { | |
# this will be the request id | |
map $host $request_uuid { | |
default ''; | |
} | |
log_format log_with_request_id '$remote_addr - $remote_user [$time_local] "$request" ' | |
'$status $body_bytes_sent "$http_referer" ' | |
'"$http_user_agent" "$http_x_forwarded_for" ' | |
'request_id: $request_uuid'; | |
server { | |
# your server block here ... | |
access_log /var/log/nginx.log log_with_request_id; | |
set_by_lua $request_uuid ' | |
if ngx.var.http_x_request_id == nil then | |
return uuid() | |
else | |
return ngx.var.http_x_request_id | |
end | |
'; | |
} | |
} |
Beware that $request_id generated by nginx is not a real UUID (it is not the same format).
That should not make a difference. UUID4 has 122 random bits (the remaining 6 are used to record the UUID version and variant, at least for the variant that LUA produces). The dashes between the hex digits are a convention, not a requirement for UUIDs; they simply delimit the 16 bytes into a groups of lengths 4, 2, 2, 2 and 6. You can 'transform' a $random_id
value into a UUID with simple text transformations (replace the 13th hex digit with 4
, update the 17th hex digit (0
, 4
, C
-> 8
; 1
, 5
, D
-> 9
; 2
, 6
, E
-> A
; 3
, 7
, F
-> B
), insert the dashes).
If all you need is a unique identifier for a request, $random_id
is going to be way faster, don't get too hung up on the difference.
Beware that $request_id generated by nginx is not a real UUID (it is not the same format).
That should not make a difference. UUID4 has 122 random bits (the remaining 6 are used to record the UUID version and variant, at least for the variant that LUA produces). The dashes between the hex digits are a convention, not a requirement for UUIDs; they simply delimit the 16 bytes into a groups of lengths 4, 2, 2, 2 and 6. You can 'transform' a
$random_id
value into a UUID with simple text transformations (replace the 13th hex digit with4
, update the 17th hex digit (0
,4
,C
->8
;1
,5
,D
->9
;2
,6
,E
->A
;3
,7
,F
->B
), insert the dashes).If all you need is a unique identifier for a request,
$random_id
is going to be way faster, don't get too hung up on the difference.
Looks like it could be implemented just with plain nginx's if
and set
statements:
# Sets $uuid variable as UUIDv4 (variant 1) converted from $request_id
set $uuid_m 4;
if ($request_id ~ '^(?<uuid_g1>[0-9a-f]{8})(?<uuid_g2>[0-9a-f]{4})(?<uuid_g3>[0-9a-f]{3})(?<uuid_n>[0-9a-f]{1})(?<uuid_g4>[0-9a-f]{3})(?<uuid_g5>[0-9a-f]{12})') {
}
if ($uuid_n = 0) {
set $uuid_n 8;
}
if ($uuid_n = 4) {
set $uuid_n 8;
}
if ($uuid_n = c) {
set $uuid_n 8;
}
if ($uuid_n = 1) {
set $uuid_n 9;
}
if ($uuid_n = 5) {
set $uuid_n 9;
}
if ($uuid_n = d) {
set $uuid_n 9;
}
if ($uuid_n = 2) {
set $uuid_n a;
}
if ($uuid_n = 6) {
set $uuid_n a;
}
if ($uuid_n = e) {
set $uuid_n a;
}
if ($uuid_n = 3) {
set $uuid_n b;
}
if ($uuid_n = 7) {
set $uuid_n b;
}
if ($uuid_n = f) {
set $uuid_n b;
}
set $uuid $uuid_g1-$uuid_g2-$uuid_m$uuid_g3-$uuid_n$uuid_g4-$uuid_g5;
map would be nice for previous answer
map $uuid_n $uuid_n {
0 8;
1 9;
2 a;
3 b;
4 8;
5 9;
6 a;
7 b;
c 8;
d 9;
e a;
f b;
}
Looks like it could be implemented just with plain nginx's if and set statements:
Your regex doesn't replace hex digit 13, you shifted digit 13-31 to positions 14-32, dropping off the 32nd hex digit. Probably not a big deal if your random values are properly random.
You can use a single map to do all the work with 4 regexes (one for each group of digit 17 values):
# map $request_id, a 32 (lowercase) hex digit random value, to a valid UUID4 value, formatted in 8h-4h-4h-4h-12h format.
# replaces hex digit 13 with '4', and the upper two bits of hex digit 17 with binary '10'
map $request_id $request_uuid4 {
# <8h><4h><ignored h><3h><h digit for 0b??00><3h><12h>
"~^(?<uuid_g1>[0-9a-f]{8})(?<uuid_g2>[0-9a-f]{4})[0-9a-f](?<uuid_g3>[0-9a-f]{3})[048c](?<uuid_g4>[0-9a-f]{3})(?<uuid_g5>[0-9a-f]{12})$" "${uuid_g1}-${uuid_g2}-4${uuid_g3}-8${uuid_g4}-${uuid_g5}";
# <8h><4h><ignored h><3h><h digit for 0b??01><3h><12h>
"~^(?<uuid_g1>[0-9a-f]{8})(?<uuid_g2>[0-9a-f]{4})[0-9a-f](?<uuid_g3>[0-9a-f]{3})[159d](?<uuid_g4>[0-9a-f]{3})(?<uuid_g5>[0-9a-f]{12})$" "${uuid_g1}-${uuid_g2}-4${uuid_g3}-9${uuid_g4}-${uuid_g5}";
# <8h><4h><ignored h><3h><h digit for 0b??10><3h><12h>
"~^(?<uuid_g1>[0-9a-f]{8})(?<uuid_g2>[0-9a-f]{4})[0-9a-f](?<uuid_g3>[0-9a-f]{3})[26ae](?<uuid_g4>[0-9a-f]{3})(?<uuid_g5>[0-9a-f]{12})$" "${uuid_g1}-${uuid_g2}-4${uuid_g3}-a${uuid_g4}-${uuid_g5}";
# <8h><4h><ignored h><3h><h digit for 0b??11><3h><12h>
"~^(?<uuid_g1>[0-9a-f]{8})(?<uuid_g2>[0-9a-f]{4})[0-9a-f](?<uuid_g3>[0-9a-f]{3})[37bf](?<uuid_g4>[0-9a-f]{3})(?<uuid_g5>[0-9a-f]{12})$" "${uuid_g1}-${uuid_g2}-4${uuid_g3}-b${uuid_g4}-${uuid_g5}";
}
# use $request_uuid4 in your log directive, or in a addheader directive to send the value back in responses.
Beware that $request_id generated by nginx is not a real UUID (it is not the same format).