From 3ef56095e961ec243b3b4e520e835ac07da7892c Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 11:53:19 +0800 Subject: [PATCH 01/16] log reuqest id that parsed from request header --- modules/setting/log.go | 1 + modules/setting/setting.go | 9 +++---- modules/web/routing/logger.go | 47 ++++++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/modules/setting/log.go b/modules/setting/log.go index 8a2d47eda7670..b75d7f5d8c00f 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -273,6 +273,7 @@ func newRouterLogService() { Cfg.Section("log").Key("ROUTER").MustString("console") // Allow [log] DISABLE_ROUTER_LOG to override [server] DISABLE_ROUTER_LOG DisableRouterLog = Cfg.Section("log").Key("DISABLE_ROUTER_LOG").MustBool(DisableRouterLog) + RequestIDHeaders = Cfg.Section("log").Key("REQUEST_ID_HEADERS").Strings(",") if !DisableRouterLog { options := newDefaultLogOptions() diff --git a/modules/setting/setting.go b/modules/setting/setting.go index a68a46f7add10..fe525b890f05c 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -365,11 +365,10 @@ var ( LogRootPath string EnableSSHLog bool EnableXORMLog bool - - DisableRouterLog bool - - EnableAccessLog bool - AccessLogTemplate string + DisableRouterLog bool + EnableAccessLog bool + AccessLogTemplate string + RequestIDHeaders []string // Time settings TimeFormat string diff --git a/modules/web/routing/logger.go b/modules/web/routing/logger.go index d1b0ff0cda6d1..eefe92ec77364 100644 --- a/modules/web/routing/logger.go +++ b/modules/web/routing/logger.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" ) // NewLoggerHandler is a handler that will log routing to the router log taking account of @@ -35,6 +36,22 @@ var ( func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { return func(trigger Event, record *requestRecord) { + var requestID string + if len(setting.RequestIDHeaders) > 0 { + for _, key := range setting.RequestIDHeaders { + headerVal := record.request.Header.Get(key) + if record.request.Header.Get(key) != "" { + requestID = headerVal + break + } + } + } + var format string + var v []interface{} + if requestID != "" { + format = "[%s] " + v = append(v, requestID) + } if trigger == StartEvent { if !logger.IsTrace() { // for performance, if the "started" message shouldn't be logged, we just return as early as possible @@ -43,7 +60,9 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { } // when a request starts, we have no information about the handler function information, we only have the request path req := record.request - logger.Trace("router: %s %v %s for %s", startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr) + format += "router: %s %v %s for %s" + v = append(v, startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr) + logger.Trace(format, v...) return } @@ -64,23 +83,21 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { level = log.INFO message = pollingMessage } - _ = logger.Log(0, level, "router: %s %v %s for %s, elapsed %v @ %s", - message, - log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, - log.ColoredTime(time.Since(record.startTime)), - handlerFuncInfo, - ) + format += "router: %s %v %s for %s, elapsed %v @ %s" + v = append(v, message, log.ColoredMethod(req.Method), req.RequestURI, + req.RemoteAddr, log.ColoredTime(time.Since(record.startTime)), handlerFuncInfo) + _ = logger.Log(0, level, format, v...) return } if panicErr != nil { - _ = logger.Log(0, log.WARN, "router: %s %v %s for %s, panic in %v @ %s, err=%v", - failedMessage, + format += "router: %s %v %s for %s, panic in %v @ %s, err=%v" + v = append(v, failedMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, log.ColoredTime(time.Since(record.startTime)), handlerFuncInfo, - panicErr, - ) + panicErr) + _ = logger.Log(0, log.WARN, format, v...) return } @@ -95,11 +112,11 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { message = unknownHandlerMessage } - _ = logger.Log(0, level, "router: %s %v %s for %s, %v %v in %v @ %s", - message, + format += "router: %s %v %s for %s, %v %v in %v @ %s" + v = append(v, message, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(record.startTime)), - handlerFuncInfo, - ) + handlerFuncInfo) + _ = logger.Log(0, level, format, v...) } } From e23a9f6ffe2177d62a7ff4265210b2c336ae2dda Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 12:06:44 +0800 Subject: [PATCH 02/16] fix --- modules/web/routing/logger.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/web/routing/logger.go b/modules/web/routing/logger.go index eefe92ec77364..863186bc4f020 100644 --- a/modules/web/routing/logger.go +++ b/modules/web/routing/logger.go @@ -36,6 +36,12 @@ var ( func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { return func(trigger Event, record *requestRecord) { + if trigger == StartEvent && !logger.IsTrace() { + // for performance, if the "started" message shouldn't be logged, we just return as early as possible + // developers can set the router log level to TRACE to get the "started" request messages. + return + } + var requestID string if len(setting.RequestIDHeaders) > 0 { for _, key := range setting.RequestIDHeaders { @@ -53,11 +59,6 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { v = append(v, requestID) } if trigger == StartEvent { - if !logger.IsTrace() { - // for performance, if the "started" message shouldn't be logged, we just return as early as possible - // developers can set the router log level to TRACE to get the "started" request messages. - return - } // when a request starts, we have no information about the handler function information, we only have the request path req := record.request format += "router: %s %v %s for %s" From bca651f7ca2fface7b298ccffc41298b9844af4e Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 14:41:41 +0800 Subject: [PATCH 03/16] update example and config cheat sheet --- custom/conf/app.example.ini | 16 ++++++++++++++++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + .../doc/advanced/config-cheat-sheet.zh-cn.md | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b478785a07709..f705baa4822dc 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -576,6 +576,22 @@ ROUTER = console ;; The routing level will default to that of the system but individual router level can be set in ;; [log..router] LEVEL ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Print request id which parsed from request headers in router log +;; * e.g: +;; * In reuqest Header: X-Request-ID: test-id-123 +;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID +;; * Print in log: 2023/02/14 13:18:50 [63eb19ba] [test-id-123] ... +;; +;; If you configure more than one in the .ini file, it will match in the order of configuration, +;; and the first match will be finally printed in the log. +;; * e.g: +;; * In reuqest Header: X-Trace-ID: test-trace-id-123 +;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID, X-Req-ID +;; * Print in log: 2023/02/14 13:18:50 [63eb19ba] [test-trace-id-123] ... +;; +;; REQUEST_ID_HEADERS = ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 04344b15dc73f..441753c801366 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -854,6 +854,7 @@ Default templates for project boards: - `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log. - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default Gitea logger.) NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. +- `REQUEST_ID_HEADERS`: **\**: You can configure multiple values that are splited by comma here. It will match in the order of configuration, and the first match will be finally printed in the log. You can refer to the `app.example.ini` file for examples ### Access Log (`log`) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 2598f16a14963..f5448300f55be 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -77,14 +77,12 @@ menu: - `START_SSH_SERVER`: 是否启用内部SSH服务器。 - `SSH_PORT`: SSH端口,默认为 `22`。 - `OFFLINE_MODE`: 针对静态和头像文件禁用 CDN。 -- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 - `CERT_FILE`: 启用HTTPS的证书文件。 - `KEY_FILE`: 启用HTTPS的密钥文件。 - `STATIC_ROOT_PATH`: 存放模板和静态文件的根目录,默认是 Gitea 的根目录。 - `STATIC_CACHE_TIME`: **6h**: 静态资源文件,包括 `custom/`, `public/` 和所有上传的头像的浏览器缓存时间。 - `ENABLE_GZIP`: 启用实时生成的数据启用 GZIP 压缩,不包括静态资源。 - `LANDING_PAGE`: 未登录用户的默认页面,可选 `home` 或 `explore`。 - - `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。 - `LFS_JWT_SECRET`: LFS 认证密钥,改成自己的。 - `LFS_CONTENT_PATH`: **已废弃**, 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。**废弃** 请使用 `[lfs]` 的设置。 @@ -263,6 +261,8 @@ test01.xls: application/vnd.ms-excel; charset=binary - `ROOT_PATH`: 日志文件根目录。 - `MODE`: 日志记录模式,默认是为 `console`。如果要写到多个通道,用逗号分隔 - `LEVEL`: 日志级别,默认为`Trace`。 +- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 +- `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到router log中。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配,示例可以参考`app.example.ini`文件。 ## Cron (`cron`) From 68ae3090498d2e91a5a9de8b1f672ff35c132d5b Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 17:25:50 +0800 Subject: [PATCH 04/16] put request id into access log --- custom/conf/app.example.ini | 12 ++-- .../doc/advanced/config-cheat-sheet.en-us.md | 31 +++++++++- .../doc/advanced/config-cheat-sheet.zh-cn.md | 50 +++++++++++++++- modules/context/access_log.go | 11 ++++ modules/setting/log.go | 2 +- modules/web/routing/logger.go | 58 +++++++------------ 6 files changed, 114 insertions(+), 50 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index f705baa4822dc..135190a214cac 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -578,18 +578,18 @@ ROUTER = console ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Print request id which parsed from request headers in router log -;; * e.g: +;; Print request id which parsed from request headers in access log, when access log is enabled. +;; * E.g: ;; * In reuqest Header: X-Request-ID: test-id-123 ;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID -;; * Print in log: 2023/02/14 13:18:50 [63eb19ba] [test-id-123] ... +;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "test-id-123" ;; ;; If you configure more than one in the .ini file, it will match in the order of configuration, ;; and the first match will be finally printed in the log. -;; * e.g: -;; * In reuqest Header: X-Trace-ID: test-trace-id-123 +;; * E.g: +;; * In reuqest Header: X-Trace-ID: trace-id-1q2w3e4r ;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID, X-Req-ID -;; * Print in log: 2023/02/14 13:18:50 [63eb19ba] [test-trace-id-123] ... +;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "trace-id-1q2w3e4r" ;; ;; REQUEST_ID_HEADERS = diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 441753c801366..b0dcc6d666f65 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -47,7 +47,7 @@ reported as part of the default configuration when running `gitea --help` or on - A built-in value set at build time (see building from source) - Otherwise it defaults to the directory of the _`AppPath`_ - If any of the above are relative paths then they are made absolute against the -the directory of the _`AppPath`_ + the directory of the _`AppPath`_ - _`CustomPath`_: This is the base directory for custom templates and other options. It is determined by using the first set thing in the following hierarchy: - The `--custom-path` flag passed to the binary @@ -61,7 +61,7 @@ the directory of the _`AppWorkPath`_ - A built-in value set at build time (see building from source) - Otherwise it defaults to _`CustomPath`_`/conf/app.ini` - If any of the above are relative paths then they are made absolute against the -the directory of the _`CustomPath`_ + the directory of the _`CustomPath`_ In addition there is _`StaticRootPath`_ which can be set as a built-in at build time, but will otherwise default to _`AppWorkPath`_ @@ -854,20 +854,45 @@ Default templates for project boards: - `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log. - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default Gitea logger.) NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. -- `REQUEST_ID_HEADERS`: **\**: You can configure multiple values that are splited by comma here. It will match in the order of configuration, and the first match will be finally printed in the log. You can refer to the `app.example.ini` file for examples ### Access Log (`log`) - `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. + - The following variables are available: - `Ctx`: the `context.Context` of the request. - `Identity`: the SignedUserName or `"-"` if not logged in. - `Start`: the start time of the request. - `ResponseWriter`: the responseWriter from the request. + - `RequestID`: the value matching REQUEST_ID_HEADERS(default: `-`, if not matched). - You must be very careful to ensure that this template does not throw errors or panics as this template runs outside of the panic/recovery script. +- `REQUEST_ID_HEADERS`: **\**: You can configure multiple values that are splited by comma here. It will match in the order of configuration, and the first match will be finally printed in the access log. + + E.g 1: + + In the Request Header: X-Request-ID: **test-id-123** + + Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID + + Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... + + + + E.g 2: + + In the Request Header: X-Trace-ID: **trace-id-1q2w3e4r** + + Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID + + Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... + + + ### Log subsections (`log.name`, `log.name.*`) - `LEVEL`: **log.LEVEL**: Sets the log-level of this sublogger. Defaults to the `LEVEL` set in the global `[log]` section. diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index f5448300f55be..396a84f3ea738 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -77,6 +77,7 @@ menu: - `START_SSH_SERVER`: 是否启用内部SSH服务器。 - `SSH_PORT`: SSH端口,默认为 `22`。 - `OFFLINE_MODE`: 针对静态和头像文件禁用 CDN。 +- `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 - `CERT_FILE`: 启用HTTPS的证书文件。 - `KEY_FILE`: 启用HTTPS的密钥文件。 - `STATIC_ROOT_PATH`: 存放模板和静态文件的根目录,默认是 Gitea 的根目录。 @@ -259,14 +260,59 @@ test01.xls: application/vnd.ms-excel; charset=binary ## Log (`log`) - `ROOT_PATH`: 日志文件根目录。 + - `MODE`: 日志记录模式,默认是为 `console`。如果要写到多个通道,用逗号分隔 + - `LEVEL`: 日志级别,默认为`Trace`。 + - `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 -- `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到router log中。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配,示例可以参考`app.example.ini`文件。 + +- `ENABLE_ACCESS_LOG`: 是否开启Access Log, 默认为false。 + +- `ACCESS_LOG_TEMPLATE`: + + 默认模板: + + ```golang + default := `{{.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`: 请求上下文 + - `Identity`: 登录用户名,默认: “`-`”. + - `Start`: 请求开始时间. + - `ResponseWriter`: + - `RequestID`:从请求头中解析得到的与 `REQUEST_ID_HEADERS`匹配的值(默认: “`-`”). + - 一定要谨慎配置该模板,否则可能会引起panic. + +- `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到acces log中(需要在ACCESS_LOG_TEMPLATE中指定输出位置)。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配。 + + 例1: + + 请求头: X-Request-ID: **test-id-123** + + 配置文件: REQUEST_ID_HEADERS = X-Request-ID + + 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... + + + + 例2: + + 请求头: X-Trace-ID: **trace-id-1q2w3e4r** + + 配置文件: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID + + 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... + + + + ## Cron (`cron`) -- `ENABLED`: 是否在后台运行定期任务。 +- `ENABLED`: 是否在后台运行定期任务。s - `RUN_AT_START`: 是否启动时自动运行。 - `SCHEDULE` 所接受的格式 - 完整 crontab 控制, 例如 `* * * * * ?` diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 05c0f86218c94..abe7f2576b08e 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -20,6 +20,7 @@ type routerLoggerOptions struct { Start *time.Time ResponseWriter http.ResponseWriter Ctx map[string]interface{} + RequestID *string } var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey" @@ -34,6 +35,15 @@ func AccessLogger() func(http.Handler) http.Handler { identity := "-" r := req.WithContext(context.WithValue(req.Context(), signedUserNameStringPointerKey, &identity)) + requestID := "-" + for _, key := range setting.RequestIDHeaders { + headerVal := req.Header.Get(key) + if headerVal != "" { + requestID = headerVal + break + } + } + next.ServeHTTP(w, r) rw := w.(ResponseWriter) @@ -47,6 +57,7 @@ func AccessLogger() func(http.Handler) http.Handler { "RemoteAddr": req.RemoteAddr, "Req": req, }, + RequestID: &requestID, }) if err != nil { log.Error("Could not set up chi access logger: %v", err.Error()) diff --git a/modules/setting/log.go b/modules/setting/log.go index b75d7f5d8c00f..f23695cb86809 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -261,6 +261,7 @@ func newAccessLogService() { // the `MustString` updates the default value, and `log.ACCESS` is used by `generateNamedLogger("access")` later _ = Cfg.Section("log").Key("ACCESS").MustString("file") if EnableAccessLog { + RequestIDHeaders = Cfg.Section("log").Key("REQUEST_ID_HEADERS").Strings(",") options := newDefaultLogOptions() options.filename = filepath.Join(LogRootPath, "access.log") options.flags = "" // For the router we don't want any prefixed flags @@ -273,7 +274,6 @@ func newRouterLogService() { Cfg.Section("log").Key("ROUTER").MustString("console") // Allow [log] DISABLE_ROUTER_LOG to override [server] DISABLE_ROUTER_LOG DisableRouterLog = Cfg.Section("log").Key("DISABLE_ROUTER_LOG").MustBool(DisableRouterLog) - RequestIDHeaders = Cfg.Section("log").Key("REQUEST_ID_HEADERS").Strings(",") if !DisableRouterLog { options := newDefaultLogOptions() diff --git a/modules/web/routing/logger.go b/modules/web/routing/logger.go index 863186bc4f020..d1b0ff0cda6d1 100644 --- a/modules/web/routing/logger.go +++ b/modules/web/routing/logger.go @@ -9,7 +9,6 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" ) // NewLoggerHandler is a handler that will log routing to the router log taking account of @@ -36,34 +35,15 @@ var ( func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { return func(trigger Event, record *requestRecord) { - if trigger == StartEvent && !logger.IsTrace() { - // for performance, if the "started" message shouldn't be logged, we just return as early as possible - // developers can set the router log level to TRACE to get the "started" request messages. - return - } - - var requestID string - if len(setting.RequestIDHeaders) > 0 { - for _, key := range setting.RequestIDHeaders { - headerVal := record.request.Header.Get(key) - if record.request.Header.Get(key) != "" { - requestID = headerVal - break - } - } - } - var format string - var v []interface{} - if requestID != "" { - format = "[%s] " - v = append(v, requestID) - } if trigger == StartEvent { + if !logger.IsTrace() { + // for performance, if the "started" message shouldn't be logged, we just return as early as possible + // developers can set the router log level to TRACE to get the "started" request messages. + return + } // when a request starts, we have no information about the handler function information, we only have the request path req := record.request - format += "router: %s %v %s for %s" - v = append(v, startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr) - logger.Trace(format, v...) + logger.Trace("router: %s %v %s for %s", startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr) return } @@ -84,21 +64,23 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { level = log.INFO message = pollingMessage } - format += "router: %s %v %s for %s, elapsed %v @ %s" - v = append(v, message, log.ColoredMethod(req.Method), req.RequestURI, - req.RemoteAddr, log.ColoredTime(time.Since(record.startTime)), handlerFuncInfo) - _ = logger.Log(0, level, format, v...) + _ = logger.Log(0, level, "router: %s %v %s for %s, elapsed %v @ %s", + message, + log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, + log.ColoredTime(time.Since(record.startTime)), + handlerFuncInfo, + ) return } if panicErr != nil { - format += "router: %s %v %s for %s, panic in %v @ %s, err=%v" - v = append(v, failedMessage, + _ = logger.Log(0, log.WARN, "router: %s %v %s for %s, panic in %v @ %s, err=%v", + failedMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, log.ColoredTime(time.Since(record.startTime)), handlerFuncInfo, - panicErr) - _ = logger.Log(0, log.WARN, format, v...) + panicErr, + ) return } @@ -113,11 +95,11 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) { message = unknownHandlerMessage } - format += "router: %s %v %s for %s, %v %v in %v @ %s" - v = append(v, message, + _ = logger.Log(0, level, "router: %s %v %s for %s, %v %v in %v @ %s", + message, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr, log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(record.startTime)), - handlerFuncInfo) - _ = logger.Log(0, level, format, v...) + handlerFuncInfo, + ) } } From 248ca3cd4eaae26d5799637f24fd37549dd98767 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 17:38:40 +0800 Subject: [PATCH 05/16] delete useless character --- docs/content/doc/advanced/config-cheat-sheet.zh-cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 396a84f3ea738..3ed1d17b31a15 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -312,7 +312,7 @@ test01.xls: application/vnd.ms-excel; charset=binary ## Cron (`cron`) -- `ENABLED`: 是否在后台运行定期任务。s +- `ENABLED`: 是否在后台运行定期任务。 - `RUN_AT_START`: 是否启动时自动运行。 - `SCHEDULE` 所接受的格式 - 完整 crontab 控制, 例如 `* * * * * ?` From f15ce89093d90a32a82835d4f3fddbef72fe0a1d Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 14 Feb 2023 22:46:41 +0800 Subject: [PATCH 06/16] fix lint --- .../doc/advanced/config-cheat-sheet.en-us.md | 28 +++++------------ .../doc/advanced/config-cheat-sheet.zh-cn.md | 30 +++++-------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index b0dcc6d666f65..dde97a642c285 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -872,26 +872,14 @@ Default templates for project boards: - You must be very careful to ensure that this template does not throw errors or panics as this template runs outside of the panic/recovery script. - `REQUEST_ID_HEADERS`: **\**: You can configure multiple values that are splited by comma here. It will match in the order of configuration, and the first match will be finally printed in the access log. - - E.g 1: - - In the Request Header: X-Request-ID: **test-id-123** - - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID - - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... - - - - E.g 2: - - In the Request Header: X-Trace-ID: **trace-id-1q2w3e4r** - - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID - - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... - - + E.g1: + In the Request Header: X-Request-ID: **test-id-123** + Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID + Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... + E.g 2: + In the Request Header: X-Trace-ID: **trace-id-1q2w3e4r** + Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID + Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... ### Log subsections (`log.name`, `log.name.*`) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 3ed1d17b31a15..723e215d7b04d 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -282,33 +282,19 @@ test01.xls: application/vnd.ms-excel; charset=binary - `Ctx`: 请求上下文 - `Identity`: 登录用户名,默认: “`-`”. - `Start`: 请求开始时间. - - `ResponseWriter`: - - `RequestID`:从请求头中解析得到的与 `REQUEST_ID_HEADERS`匹配的值(默认: “`-`”). + - `ResponseWriter`: + - `RequestID`: 从请求头中解析得到的与 `REQUEST_ID_HEADERS`匹配的值(默认: “`-`”). - 一定要谨慎配置该模板,否则可能会引起panic. - `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到acces log中(需要在ACCESS_LOG_TEMPLATE中指定输出位置)。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配。 - 例1: - - 请求头: X-Request-ID: **test-id-123** - - 配置文件: REQUEST_ID_HEADERS = X-Request-ID - - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... - - - + 请求头: X-Request-ID: **test-id-123** + 配置文件: REQUEST_ID_HEADERS = X-Request-ID + 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... 例2: - - 请求头: X-Trace-ID: **trace-id-1q2w3e4r** - - 配置文件: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID - - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... - - - - + 请求头: X-Trace-ID: **trace-id-1q2w3e4r** + 配置文件: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID + 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... ## Cron (`cron`) From e040fa85c4d99d586d8af678929d323c01af72e7 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 15 Feb 2023 13:41:55 +0800 Subject: [PATCH 07/16] set the maximum length of request id to 256 bits --- modules/context/access_log.go | 36 ++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/modules/context/access_log.go b/modules/context/access_log.go index abe7f2576b08e..aa99261f9e0ab 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -6,8 +6,10 @@ package context import ( "bytes" "context" + "fmt" "html/template" "net/http" + "strings" "time" "code.gitea.io/gitea/modules/log" @@ -25,23 +27,43 @@ type routerLoggerOptions struct { var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey" +const keyOfRequestIDInTemplate = ".RequestID" + +// According to OpenTracing and OpenTelemetry, the maximum length of trace id is 256 bits. +// (32 bytes = 32 * 8 = 256 bits) +// So we accept a Request ID with a maximum character length of 32 +const maxRequestIDBtyeLength = 32 + +func parseRequestIDFromRequestHeader(req *http.Request) (string, string) { + requestHeader := "-" + requestID := "-" + for _, key := range setting.RequestIDHeaders { + if req.Header.Get(key) != "" { + requestHeader = key + requestID = req.Header.Get(key) + break + } + } + if len(requestID) > maxRequestIDBtyeLength { + requestID = fmt.Sprintf("%s...", requestID[:maxRequestIDBtyeLength]) + } + return requestHeader, requestID +} + // AccessLogger returns a middleware to log access logger func AccessLogger() func(http.Handler) http.Handler { logger := log.GetLogger("access") logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate) + needRequestID := strings.Contains(setting.AccessLogTemplate, keyOfRequestIDInTemplate) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { start := time.Now() identity := "-" r := req.WithContext(context.WithValue(req.Context(), signedUserNameStringPointerKey, &identity)) - requestID := "-" - for _, key := range setting.RequestIDHeaders { - headerVal := req.Header.Get(key) - if headerVal != "" { - requestID = headerVal - break - } + var requestID string + if needRequestID { + _, requestID = parseRequestIDFromRequestHeader(req) } next.ServeHTTP(w, r) From 55c27793ff8433bcc92cf0107071d020873d491a Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 15 Feb 2023 15:10:52 +0800 Subject: [PATCH 08/16] fix markdown --- .../doc/advanced/config-cheat-sheet.en-us.md | 20 ++++--------- .../doc/advanced/config-cheat-sheet.zh-cn.md | 28 +++++-------------- modules/context/access_log.go | 8 ++---- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index dde97a642c285..27979d2969add 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -47,7 +47,7 @@ reported as part of the default configuration when running `gitea --help` or on - A built-in value set at build time (see building from source) - Otherwise it defaults to the directory of the _`AppPath`_ - If any of the above are relative paths then they are made absolute against the - the directory of the _`AppPath`_ +the directory of the _`AppPath`_ - _`CustomPath`_: This is the base directory for custom templates and other options. It is determined by using the first set thing in the following hierarchy: - The `--custom-path` flag passed to the binary @@ -61,7 +61,7 @@ the directory of the _`AppWorkPath`_ - A built-in value set at build time (see building from source) - Otherwise it defaults to _`CustomPath`_`/conf/app.ini` - If any of the above are relative paths then they are made absolute against the - the directory of the _`CustomPath`_ +the directory of the _`CustomPath`_ In addition there is _`StaticRootPath`_ which can be set as a built-in at build time, but will otherwise default to _`AppWorkPath`_ @@ -858,11 +858,8 @@ Default templates for project boards: ### Access Log (`log`) - `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. - - The following variables are available: - `Ctx`: the `context.Context` of the request. - `Identity`: the SignedUserName or `"-"` if not logged in. @@ -870,16 +867,11 @@ Default templates for project boards: - `ResponseWriter`: the responseWriter from the request. - `RequestID`: the value matching REQUEST_ID_HEADERS(default: `-`, if not matched). - You must be very careful to ensure that this template does not throw errors or panics as this template runs outside of the panic/recovery script. - - `REQUEST_ID_HEADERS`: **\**: You can configure multiple values that are splited by comma here. It will match in the order of configuration, and the first match will be finally printed in the access log. - E.g1: - In the Request Header: X-Request-ID: **test-id-123** - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... - E.g 2: - In the Request Header: X-Trace-ID: **trace-id-1q2w3e4r** - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... + - e.g. + - In the Request Header: X-Request-ID: **test-id-123** + - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID + - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... ### Log subsections (`log.name`, `log.name.*`) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 723e215d7b04d..b96a361416760 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -85,6 +85,7 @@ menu: - `ENABLE_GZIP`: 启用实时生成的数据启用 GZIP 压缩,不包括静态资源。 - `LANDING_PAGE`: 未登录用户的默认页面,可选 `home` 或 `explore`。 - `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。 + - `LFS_JWT_SECRET`: LFS 认证密钥,改成自己的。 - `LFS_CONTENT_PATH`: **已废弃**, 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。**废弃** 请使用 `[lfs]` 的设置。 @@ -260,41 +261,26 @@ test01.xls: application/vnd.ms-excel; charset=binary ## Log (`log`) - `ROOT_PATH`: 日志文件根目录。 - - `MODE`: 日志记录模式,默认是为 `console`。如果要写到多个通道,用逗号分隔 - - `LEVEL`: 日志级别,默认为`Trace`。 - - `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 - - `ENABLE_ACCESS_LOG`: 是否开启Access Log, 默认为false。 - -- `ACCESS_LOG_TEMPLATE`: - - 默认模板: - +- `ACCESS_LOG_TEMPLATE`:默认模板: ```golang default := `{{.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`: 请求上下文 - `Identity`: 登录用户名,默认: “`-`”. - `Start`: 请求开始时间. - `ResponseWriter`: - `RequestID`: 从请求头中解析得到的与 `REQUEST_ID_HEADERS`匹配的值(默认: “`-`”). - 一定要谨慎配置该模板,否则可能会引起panic. - - `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到acces log中(需要在ACCESS_LOG_TEMPLATE中指定输出位置)。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配。 - 例1: - 请求头: X-Request-ID: **test-id-123** - 配置文件: REQUEST_ID_HEADERS = X-Request-ID - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... - 例2: - 请求头: X-Trace-ID: **trace-id-1q2w3e4r** - 配置文件: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**trace-id-1q2w3e4r**" ... + - 示例: + - 请求头: X-Request-ID: **test-id-123** + - 配置文件: REQUEST_ID_HEADERS = X-Request-ID + - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... ## Cron (`cron`) diff --git a/modules/context/access_log.go b/modules/context/access_log.go index aa99261f9e0ab..3ba697d617711 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -34,12 +34,10 @@ const keyOfRequestIDInTemplate = ".RequestID" // So we accept a Request ID with a maximum character length of 32 const maxRequestIDBtyeLength = 32 -func parseRequestIDFromRequestHeader(req *http.Request) (string, string) { - requestHeader := "-" +func parseRequestIDFromRequestHeader(req *http.Request) string { requestID := "-" for _, key := range setting.RequestIDHeaders { if req.Header.Get(key) != "" { - requestHeader = key requestID = req.Header.Get(key) break } @@ -47,7 +45,7 @@ func parseRequestIDFromRequestHeader(req *http.Request) (string, string) { if len(requestID) > maxRequestIDBtyeLength { requestID = fmt.Sprintf("%s...", requestID[:maxRequestIDBtyeLength]) } - return requestHeader, requestID + return requestID } // AccessLogger returns a middleware to log access logger @@ -63,7 +61,7 @@ func AccessLogger() func(http.Handler) http.Handler { var requestID string if needRequestID { - _, requestID = parseRequestIDFromRequestHeader(req) + requestID = parseRequestIDFromRequestHeader(req) } next.ServeHTTP(w, r) From c5a544217c4181e514878bb26819d39227781b37 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 15 Feb 2023 15:18:36 +0800 Subject: [PATCH 09/16] lint markdown --- .../doc/advanced/config-cheat-sheet.zh-cn.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index b96a361416760..07a404918463e 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -262,21 +262,18 @@ test01.xls: application/vnd.ms-excel; charset=binary - `ROOT_PATH`: 日志文件根目录。 - `MODE`: 日志记录模式,默认是为 `console`。如果要写到多个通道,用逗号分隔 -- `LEVEL`: 日志级别,默认为`Trace`。 +- `LEVEL`: 日志级别,默认为 `Trace`。 - `DISABLE_ROUTER_LOG`: 关闭日志中的路由日志。 -- `ENABLE_ACCESS_LOG`: 是否开启Access Log, 默认为false。 -- `ACCESS_LOG_TEMPLATE`:默认模板: - ```golang - default := `{{.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}}"` - ``` +- `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}}"`** 模板支持以下参数: - - `Ctx`: 请求上下文 - - `Identity`: 登录用户名,默认: “`-`”. - - `Start`: 请求开始时间. + - `Ctx`: 请求上下文。 + - `Identity`: 登录用户名,默认: “`-`”。 + - `Start`: 请求开始时间。 - `ResponseWriter`: - - `RequestID`: 从请求头中解析得到的与 `REQUEST_ID_HEADERS`匹配的值(默认: “`-`”). + - `RequestID`: 从请求头中解析得到的与 `REQUEST_ID_HEADERS` 匹配的值,默认: “`-`”。 - 一定要谨慎配置该模板,否则可能会引起panic. -- `REQUEST_ID_HEADERS`: 从Request Header中匹配指定Key,并将匹配到的值输出到acces log中(需要在ACCESS_LOG_TEMPLATE中指定输出位置)。如果在该参数中配置多个Key, 请用逗号分割,程序将按照配置的顺序进行匹配。 +- `REQUEST_ID_HEADERS`: 从 Request Header 中匹配指定 Key,并将匹配到的值输出到 `access.log` 中(需要在 `ACCESS_LOG_TEMPLATE` 中指定输出位置)。如果在该参数中配置多个 Key, 请用逗号分割,程序将按照配置的顺序进行匹配。 - 示例: - 请求头: X-Request-ID: **test-id-123** - 配置文件: REQUEST_ID_HEADERS = X-Request-ID From ec0d6c00ae61b1988388bd9c69b9586f3120db50 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 15 Feb 2023 16:03:38 +0800 Subject: [PATCH 10/16] set maxRequestIDBtyeLength to 40 --- docs/content/doc/advanced/config-cheat-sheet.zh-cn.md | 2 +- modules/context/access_log.go | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 07a404918463e..b1ac7bca93159 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -84,8 +84,8 @@ menu: - `STATIC_CACHE_TIME`: **6h**: 静态资源文件,包括 `custom/`, `public/` 和所有上传的头像的浏览器缓存时间。 - `ENABLE_GZIP`: 启用实时生成的数据启用 GZIP 压缩,不包括静态资源。 - `LANDING_PAGE`: 未登录用户的默认页面,可选 `home` 或 `explore`。 -- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。 +- `LFS_START_SERVER`: 是否启用 git-lfs 支持. 可以为 `true` 或 `false`, 默认是 `false`。 - `LFS_JWT_SECRET`: LFS 认证密钥,改成自己的。 - `LFS_CONTENT_PATH`: **已废弃**, 存放 lfs 命令上传的文件的地方,默认是 `data/lfs`。**废弃** 请使用 `[lfs]` 的设置。 diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 3ba697d617711..7360c7b66a89a 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -29,10 +29,13 @@ var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey const keyOfRequestIDInTemplate = ".RequestID" -// According to OpenTracing and OpenTelemetry, the maximum length of trace id is 256 bits. -// (32 bytes = 32 * 8 = 256 bits) -// So we accept a Request ID with a maximum character length of 32 -const maxRequestIDBtyeLength = 32 +// According to: +// In OpenTracing and OpenTelemetry, the maximum length of trace id is 256 bits (32 bytes). +// MD5 output is 16 or 32 bytes. +// UUID ouput is 36 bytes (including four ‘-’) +// SHA1 outpu is 40 bytes +// So, we accept a Request ID with a maximum character length of 40 +const maxRequestIDBtyeLength = 40 func parseRequestIDFromRequestHeader(req *http.Request) string { requestID := "-" From 0c47e3fa71e1df54ac0a5ccccfcd0699667ae0e0 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Wed, 15 Feb 2023 16:10:06 +0800 Subject: [PATCH 11/16] fix comment misspelling --- modules/context/access_log.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 7360c7b66a89a..8dfa66ad789bd 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -32,8 +32,8 @@ const keyOfRequestIDInTemplate = ".RequestID" // According to: // In OpenTracing and OpenTelemetry, the maximum length of trace id is 256 bits (32 bytes). // MD5 output is 16 or 32 bytes. -// UUID ouput is 36 bytes (including four ‘-’) -// SHA1 outpu is 40 bytes +// UUID output is 36 bytes (including four ‘-’) +// SHA1 output is 40 bytes // So, we accept a Request ID with a maximum character length of 40 const maxRequestIDBtyeLength = 40 From dbabb46ecfe66010d202dafcf14e7faa10a6759d Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Fri, 17 Feb 2023 18:07:34 +0800 Subject: [PATCH 12/16] fix comment and the judgement of "needRequestID" --- modules/context/access_log.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 8dfa66ad789bd..0040cd7f47c49 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -30,12 +30,12 @@ var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey const keyOfRequestIDInTemplate = ".RequestID" // According to: -// In OpenTracing and OpenTelemetry, the maximum length of trace id is 256 bits (32 bytes). -// MD5 output is 16 or 32 bytes. -// UUID output is 36 bytes (including four ‘-’) -// SHA1 output is 40 bytes +// TraceId: A valid trace identifier is a 16-byte array with at least one non-zero byte. So it's 128bit, while it's hex string is 32bytes (256-bit is not true for OpenTracing/OpenTelemetry) +// MD5 output is 16 or 32 bytes: md5-bytes is 16, md5-hex is 32 +// SHA1: similar, SHA1-bytes is 20, SHA1-hex is 40. +// UUID is 128-bit, 32 hex chars, 36 ASCII chars with 4 dashes // So, we accept a Request ID with a maximum character length of 40 -const maxRequestIDBtyeLength = 40 +const maxRequestIDByteLength = 40 func parseRequestIDFromRequestHeader(req *http.Request) string { requestID := "-" @@ -45,8 +45,8 @@ func parseRequestIDFromRequestHeader(req *http.Request) string { break } } - if len(requestID) > maxRequestIDBtyeLength { - requestID = fmt.Sprintf("%s...", requestID[:maxRequestIDBtyeLength]) + if len(requestID) > maxRequestIDByteLength { + requestID = fmt.Sprintf("%s...", requestID[:maxRequestIDByteLength]) } return requestID } @@ -55,7 +55,7 @@ func parseRequestIDFromRequestHeader(req *http.Request) string { func AccessLogger() func(http.Handler) http.Handler { logger := log.GetLogger("access") logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate) - needRequestID := strings.Contains(setting.AccessLogTemplate, keyOfRequestIDInTemplate) + needRequestID := len(setting.RequestIDHeaders) > 0 && strings.Contains(setting.AccessLogTemplate, keyOfRequestIDInTemplate) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { start := time.Now() From 84a1a04bd4bc919c63e27bad2db639668c5f16ea Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Fri, 17 Feb 2023 22:40:55 +0800 Subject: [PATCH 13/16] fix comment --- modules/context/access_log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 0040cd7f47c49..eae9260104163 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -30,7 +30,7 @@ var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey const keyOfRequestIDInTemplate = ".RequestID" // According to: -// TraceId: A valid trace identifier is a 16-byte array with at least one non-zero byte. So it's 128bit, while it's hex string is 32bytes (256-bit is not true for OpenTracing/OpenTelemetry) +// TraceId: A valid trace identifier is a 16-byte array with at least one non-zero byte // MD5 output is 16 or 32 bytes: md5-bytes is 16, md5-hex is 32 // SHA1: similar, SHA1-bytes is 20, SHA1-hex is 40. // UUID is 128-bit, 32 hex chars, 36 ASCII chars with 4 dashes From fc843f02903feb16f9c3329cf206b0d9e8db83d1 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Tue, 21 Feb 2023 10:25:53 +0800 Subject: [PATCH 14/16] fix example --- custom/conf/app.example.ini | 2 +- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- docs/content/doc/advanced/config-cheat-sheet.zh-cn.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 135190a214cac..90663f8ca44fb 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -582,7 +582,7 @@ ROUTER = console ;; * E.g: ;; * In reuqest Header: X-Request-ID: test-id-123 ;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID -;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "test-id-123" +;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "test-id-123" ;; ;; If you configure more than one in the .ini file, it will match in the order of configuration, ;; and the first match will be finally printed in the log. diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 2463923e77582..628d07b0727c8 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -886,7 +886,7 @@ Default templates for project boards: - e.g. - In the Request Header: X-Request-ID: **test-id-123** - Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID - - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... + - Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... ### Log subsections (`log.name`, `log.name.*`) diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index b1ac7bca93159..b4d1328f9f90b 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -277,7 +277,7 @@ test01.xls: application/vnd.ms-excel; charset=binary - 示例: - 请求头: X-Request-ID: **test-id-123** - 配置文件: REQUEST_ID_HEADERS = X-Request-ID - - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... + - 日志输出: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "**test-id-123**" ... ## Cron (`cron`) From b387a1e99d8a7dbdc0a25f2102d7d313a4597288 Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 9 Mar 2023 20:28:44 +0000 Subject: [PATCH 15/16] Update custom/conf/app.example.ini --- custom/conf/app.example.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 85b6dd193b29b..5d35269fd680d 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -580,7 +580,7 @@ ROUTER = console ;; ;; Print request id which parsed from request headers in access log, when access log is enabled. ;; * E.g: -;; * In reuqest Header: X-Request-ID: test-id-123 +;; * In request Header: X-Request-ID: test-id-123 ;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID ;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "test-id-123" ;; From f231c640c3620302ab0db4ccbf5d774597335949 Mon Sep 17 00:00:00 2001 From: sillyguodong Date: Fri, 10 Mar 2023 09:39:05 +0800 Subject: [PATCH 16/16] fix eample --- custom/conf/app.example.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 5d35269fd680d..c3c20a216c2df 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -589,7 +589,7 @@ ROUTER = console ;; * E.g: ;; * In reuqest Header: X-Trace-ID: trace-id-1q2w3e4r ;; * Configuration in app.ini: REQUEST_ID_HEADERS = X-Request-ID, X-Trace-ID, X-Req-ID -;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "trace-id-1q2w3e4r" +;; * Print in log: 127.0.0.1:58384 - - [14/Feb/2023:16:33:51 +0800] "trace-id-1q2w3e4r" ;; ;; REQUEST_ID_HEADERS =