mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-04 01:10:49 +01:00
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 <gary@garymoon.net>
This commit is contained in:
parent
2b749af505
commit
29194a9dd6
6 changed files with 13 additions and 6 deletions
|
@ -603,7 +603,7 @@ ROUTER = console
|
||||||
;ACCESS = file
|
;ACCESS = file
|
||||||
;;
|
;;
|
||||||
;; Sets the template used to create the access log.
|
;; 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}}"
|
||||||
;;
|
;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -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
|
- `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`: **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:
|
- The following variables are available:
|
||||||
- `Ctx`: the `context.Context` of the request.
|
- `Ctx`: the `context.Context` of the request.
|
||||||
- `Identity`: the SignedUserName or `"-"` if not logged in.
|
- `Identity`: the SignedUserName or `"-"` if not logged in.
|
||||||
|
|
|
@ -265,7 +265,7 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||||
- `LEVEL`: 日志级别,默认为 `Trace`。
|
- `LEVEL`: 日志级别,默认为 `Trace`。
|
||||||
- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。
|
- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。
|
||||||
- `ENABLE_ACCESS_LOG`: 是否开启 Access Log, 默认为 false。
|
- `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`: 请求上下文。
|
- `Ctx`: 请求上下文。
|
||||||
- `Identity`: 登录用户名,默认: “`-`”。
|
- `Identity`: 登录用户名,默认: “`-`”。
|
||||||
|
|
|
@ -304,7 +304,7 @@ log using the value: `ACCESS = ,`
|
||||||
|
|
||||||
This value represent a go template. It's default value is:
|
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:
|
The template is passed following options:
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -67,17 +68,23 @@ func AccessLogger() func(http.Handler) http.Handler {
|
||||||
requestID = parseRequestIDFromRequestHeader(req)
|
requestID = parseRequestIDFromRequestHeader(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqHost, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||||
|
if err != nil {
|
||||||
|
reqHost = req.RemoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
rw := w.(ResponseWriter)
|
rw := w.(ResponseWriter)
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
err := logTemplate.Execute(buf, routerLoggerOptions{
|
err = logTemplate.Execute(buf, routerLoggerOptions{
|
||||||
req: req,
|
req: req,
|
||||||
Identity: &identity,
|
Identity: &identity,
|
||||||
Start: &start,
|
Start: &start,
|
||||||
ResponseWriter: rw,
|
ResponseWriter: rw,
|
||||||
Ctx: map[string]interface{}{
|
Ctx: map[string]interface{}{
|
||||||
"RemoteAddr": req.RemoteAddr,
|
"RemoteAddr": req.RemoteAddr,
|
||||||
|
"RemoteHost": reqHost,
|
||||||
"Req": req,
|
"Req": req,
|
||||||
},
|
},
|
||||||
RequestID: &requestID,
|
RequestID: &requestID,
|
||||||
|
|
|
@ -152,7 +152,7 @@ func loadLogFrom(rootCfg ConfigProvider) {
|
||||||
Log.EnableSSHLog = sec.Key("ENABLE_SSH_LOG").MustBool(false)
|
Log.EnableSSHLog = sec.Key("ENABLE_SSH_LOG").MustBool(false)
|
||||||
Log.EnableAccessLog = sec.Key("ENABLE_ACCESS_LOG").MustBool(false)
|
Log.EnableAccessLog = sec.Key("ENABLE_ACCESS_LOG").MustBool(false)
|
||||||
Log.AccessLogTemplate = sec.Key("ACCESS_LOG_TEMPLATE").MustString(
|
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(",")
|
Log.RequestIDHeaders = sec.Key("REQUEST_ID_HEADERS").Strings(",")
|
||||||
// the `MustString` updates the default value, and `log.ACCESS` is used by `generateNamedLogger("access")` later
|
// the `MustString` updates the default value, and `log.ACCESS` is used by `generateNamedLogger("access")` later
|
||||||
|
|
Loading…
Reference in a new issue