feat: Log query text for POST requests (#20993)

The HTTP handler logs URLs, but not body values for POST requests.
This means that queries sent by GET are logged, because the query
is in the URL, but queries sent by POST have no query text in the
log.  This feature prints all the key-value pairs in the post body,
which includes the query text, except passwords, which are redacted. 

Closes https://github.com/influxdata/influxdb/issues/20653
pull/21041/head
davidby-influx 2021-03-22 10:31:56 -07:00 committed by GitHub
parent 76777680b0
commit 70755bf42c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 15 deletions

View File

@ -45,6 +45,7 @@ v1.8.5 [unreleased]
- [#20118](https://github.com/influxdata/influxdb/pull/20118): feat: Optimize shard lookups in groups containing only one shard. Thanks @StoneYunZhao!
- [#20910](https://github.com/influxdata/influxdb/pull/20910): feat: Make meta queries respect QueryTimeout values
- [#20977](https://github.com/influxdata/influxdb/pull/20977): feat: influx_inspect export to standard out
- [#20993](https://github.com/influxdata/influxdb/pull/20993): feat: Log query text for POST requests
### Bugfixes

View File

@ -101,21 +101,56 @@ func buildLogLine(l *responseLogger, r *http.Request, start time.Time) string {
userAgent := r.UserAgent()
return fmt.Sprintf(`%s - %s [%s] "%s %s %s" %s %s "%s" "%s" %s %d`,
host,
detect(username, "-"),
start.Format("02/Jan/2006:15:04:05 -0700"),
r.Method,
uri,
r.Proto,
detect(strconv.Itoa(l.Status()), "-"),
strconv.Itoa(l.Size()),
detect(referer, "-"),
detect(userAgent, "-"),
r.Header.Get("Request-Id"),
// response time, report in microseconds because this is consistent
// with apache's %D parameter in mod_log_config
int64(time.Since(start)/time.Microsecond))
allKeyValues := make([]string, 0, len(r.PostForm))
if r.Method == "POST" {
for k, values := range r.PostForm {
if k == "p" || k == "P" {
// Note: if there are multiple "p" values, they are all replaced by a single "[REDACTED]".
r.PostForm.Set(k, "[REDACTED]")
values = r.PostForm[k]
}
valuesSlice := make([]string, 0, len(values))
for _, v := range values {
valuesSlice = append(valuesSlice, fmt.Sprintf("'%s'", v))
}
joined := strings.Join(valuesSlice, ", ")
allKeyValues = append(allKeyValues, fmt.Sprintf("{'%s': %s}", k, joined))
}
return fmt.Sprintf(`%s - %s [%s] "%s %s %s %s" %s %s "%s" "%s" %s %d`,
host,
detect(username, "-"),
start.Format("02/Jan/2006:15:04:05 -0700"),
r.Method,
uri,
r.Proto,
strings.Join(allKeyValues, ", "),
detect(strconv.Itoa(l.Status()), "-"),
strconv.Itoa(l.Size()),
detect(referer, "-"),
detect(userAgent, "-"),
r.Header.Get("Request-Id"),
// response time, report in microseconds because this is consistent
// with apache's %D parameter in mod_log_config
int64(time.Since(start)/time.Microsecond))
} else {
return fmt.Sprintf(`%s - %s [%s] "%s %s %s" %s %s "%s" "%s" %s %d`,
host,
detect(username, "-"),
start.Format("02/Jan/2006:15:04:05 -0700"),
r.Method,
uri,
r.Proto,
detect(strconv.Itoa(l.Status()), "-"),
strconv.Itoa(l.Size()),
detect(referer, "-"),
detect(userAgent, "-"),
r.Header.Get("Request-Id"),
// response time, report in microseconds because this is consistent
// with apache's %D parameter in mod_log_config
int64(time.Since(start)/time.Microsecond))
}
}
// detect detects the first presence of a non blank string and returns it