From 29194a9dd6f5d8a98096a4a01c33d9be89616ed7 Mon Sep 17 00:00:00 2001 From: Gary Moon Date: Thu, 13 Apr 2023 09:14:06 -0400 Subject: [PATCH] Correct the access log format (#24085) The default access log format has been unnecessarily escaped, leading to spurious backslashes appearing in log lines. Additionally, the `RemoteAddr` field includes the port, which breaks most log parsers attempting to process it. I've added a call to `net.SplitHostPort()` attempting to isolate the address alone, with a fallback to the original address if it errs. Signed-off-by: Gary Moon --- custom/conf/app.example.ini | 2 +- .../doc/administration/config-cheat-sheet.en-us.md | 2 +- .../doc/administration/config-cheat-sheet.zh-cn.md | 2 +- .../doc/administration/logging-documentation.en-us.md | 2 +- modules/context/access_log.go | 9 ++++++++- modules/setting/log.go | 2 +- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 88297fe0d..f9f207522 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -603,7 +603,7 @@ ROUTER = console ;ACCESS = file ;; ;; Sets the template used to create the access log. -;ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}" +;ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}" ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/docs/content/doc/administration/config-cheat-sheet.en-us.md b/docs/content/doc/administration/config-cheat-sheet.en-us.md index 76952df40..f26e7eaa0 100644 --- a/docs/content/doc/administration/config-cheat-sheet.en-us.md +++ b/docs/content/doc/administration/config-cheat-sheet.en-us.md @@ -878,7 +878,7 @@ Default templates for project boards: - `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template - `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default Gitea logger.) -- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. +- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. - The following variables are available: - `Ctx`: the `context.Context` of the request. - `Identity`: the SignedUserName or `"-"` if not logged in. diff --git a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md index 043cc42e5..83e212f32 100644 --- a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md @@ -265,7 +265,7 @@ test01.xls: application/vnd.ms-excel; charset=binary - `LEVEL`: 日志级别,默认为 `Trace`。 - `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 - `ENABLE_ACCESS_LOG`: 是否开启 Access Log, 默认为 false。 -- `ACCESS_LOG_TEMPLATE`: `access.log` 输出内容的模板,默认模板:**`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`** +- `ACCESS_LOG_TEMPLATE`: `access.log` 输出内容的模板,默认模板:**`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`** 模板支持以下参数: - `Ctx`: 请求上下文。 - `Identity`: 登录用户名,默认: “`-`”。 diff --git a/docs/content/doc/administration/logging-documentation.en-us.md b/docs/content/doc/administration/logging-documentation.en-us.md index 13de8ab88..029eb5de0 100644 --- a/docs/content/doc/administration/logging-documentation.en-us.md +++ b/docs/content/doc/administration/logging-documentation.en-us.md @@ -304,7 +304,7 @@ log using the value: `ACCESS = ,` This value represent a go template. It's default value is: -`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"` +`{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"` The template is passed following options: diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 515682b64..64d204733 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "fmt" + "net" "net/http" "strings" "text/template" @@ -67,17 +68,23 @@ func AccessLogger() func(http.Handler) http.Handler { requestID = parseRequestIDFromRequestHeader(req) } + reqHost, _, err := net.SplitHostPort(req.RemoteAddr) + if err != nil { + reqHost = req.RemoteAddr + } + next.ServeHTTP(w, r) rw := w.(ResponseWriter) buf := bytes.NewBuffer([]byte{}) - err := logTemplate.Execute(buf, routerLoggerOptions{ + err = logTemplate.Execute(buf, routerLoggerOptions{ req: req, Identity: &identity, Start: &start, ResponseWriter: rw, Ctx: map[string]interface{}{ "RemoteAddr": req.RemoteAddr, + "RemoteHost": reqHost, "Req": req, }, RequestID: &requestID, diff --git a/modules/setting/log.go b/modules/setting/log.go index dabdb543a..1ff710073 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -152,7 +152,7 @@ func loadLogFrom(rootCfg ConfigProvider) { Log.EnableSSHLog = sec.Key("ENABLE_SSH_LOG").MustBool(false) Log.EnableAccessLog = sec.Key("ENABLE_ACCESS_LOG").MustBool(false) Log.AccessLogTemplate = sec.Key("ACCESS_LOG_TEMPLATE").MustString( - `{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`, + `{{.Ctx.RemoteHost}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"`, ) Log.RequestIDHeaders = sec.Key("REQUEST_ID_HEADERS").Strings(",") // the `MustString` updates the default value, and `log.ACCESS` is used by `generateNamedLogger("access")` later