nghttpx: Add accesslog variables to record request path without query

This commit the following variables to construct request line without
including query component:

* $method
* $path
* $path_without_query
* $protocol_version
This commit is contained in:
Tatsuhiro Tsujikawa 2020-09-19 23:58:37 +09:00
parent 7b4de401d2
commit 4e3c61ef4d
5 changed files with 63 additions and 0 deletions

View File

@ -205,6 +205,10 @@ LOGVARS = [
"tls_client_serial",
"backend_host",
"backend_port",
"method",
"path",
"path_without_query",
"protocol_version",
]
if __name__ == '__main__':

View File

@ -2607,6 +2607,14 @@ Logging:
request. "-" if backend host is not available.
* $backend_port: backend port used to fulfill the
request. "-" if backend host is not available.
* $method: HTTP method
* $path: Request path including query. For CONNECT
request, authority is recorded.
* $path_without_query: $path up to the first '?'
character. For CONNECT request, authority is
recorded.
* $protocol_version: HTTP version (e.g., HTTP/1.1,
HTTP/2)
The variable can be enclosed by "{" and "}" for
disambiguation (e.g., ${remote_addr}).

View File

@ -387,6 +387,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
break;
case 4:
switch (name[3]) {
case 'h':
if (util::strieq_l("pat", name, 3)) {
return LogFragmentType::PATH;
}
break;
case 'n':
if (util::strieq_l("alp", name, 3)) {
return LogFragmentType::ALPN;
@ -396,6 +401,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
break;
case 6:
switch (name[5]) {
case 'd':
if (util::strieq_l("metho", name, 5)) {
return LogFragmentType::METHOD;
}
break;
case 's':
if (util::strieq_l("statu", name, 5)) {
return LogFragmentType::STATUS;
@ -502,6 +512,15 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
break;
}
break;
case 16:
switch (name[15]) {
case 'n':
if (util::strieq_l("protocol_versio", name, 15)) {
return LogFragmentType::PROTOCOL_VERSION;
}
break;
}
break;
case 17:
switch (name[16]) {
case 'l':
@ -521,6 +540,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
return LogFragmentType::TLS_SESSION_REUSED;
}
break;
case 'y':
if (util::strieq_l("path_without_quer", name, 17)) {
return LogFragmentType::PATH_WITHOUT_QUERY;
}
break;
}
break;
case 22:

View File

@ -603,6 +603,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
? StringRef::from_lit("*")
: StringRef::from_lit("-")
: req.path;
auto path_without_query =
req.method == HTTP_CONNECT
? path
: StringRef{std::begin(path),
std::find(std::begin(path), std::end(path), '?')};
auto p = std::begin(buf);
auto last = std::end(buf) - 2;
@ -632,6 +637,24 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
std::tie(p, last) = copy(req.http_minor, p, last);
}
break;
case LogFragmentType::METHOD:
std::tie(p, last) = copy(method, p, last);
std::tie(p, last) = copy(' ', p, last);
break;
case LogFragmentType::PATH:
std::tie(p, last) = copy_escape(path, p, last);
break;
case LogFragmentType::PATH_WITHOUT_QUERY:
std::tie(p, last) = copy_escape(path_without_query, p, last);
break;
case LogFragmentType::PROTOCOL_VERSION:
std::tie(p, last) = copy_l("HTTP/", p, last);
std::tie(p, last) = copy(req.http_major, p, last);
if (req.http_major < 2) {
std::tie(p, last) = copy('.', p, last);
std::tie(p, last) = copy(req.http_minor, p, last);
}
break;
case LogFragmentType::STATUS:
std::tie(p, last) = copy(resp.http_status, p, last);
break;

View File

@ -249,6 +249,10 @@ enum class LogFragmentType {
TLS_CLIENT_SUBJECT_NAME,
BACKEND_HOST,
BACKEND_PORT,
METHOD,
PATH,
PATH_WITHOUT_QUERY,
PROTOCOL_VERSION,
};
struct LogFragment {