Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Router Logger #17308

Merged
merged 58 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
81fc293
introduce router log handler v2
wxiaoguang Oct 18, 2021
1bedc91
Merge branch 'main' into optimize-logger
wxiaoguang Oct 18, 2021
9a7017e
add comment about performance
wxiaoguang Oct 18, 2021
298c1b9
Merge branch 'main' into optimize-logger
wxiaoguang Oct 19, 2021
ce63306
fix
wxiaoguang Oct 19, 2021
5f67c98
Merge branch 'main' into optimize-logger
wxiaoguang Oct 19, 2021
3942088
Merge remote-tracking branch 'origin/main' into optimize-logger
zeripath Oct 19, 2021
22b13f2
Add some comments and a test
zeripath Oct 19, 2021
be8af1a
apply suggestion
wxiaoguang Oct 20, 2021
a485d9d
Merge branch 'optimize-logger' of github.com:wxiaoguang/gitea into op…
wxiaoguang Oct 20, 2021
32a6690
Merge remote-tracking branch 'go-gitea/main' into optimize-logger
wxiaoguang Oct 20, 2021
af90a2c
Merge branch 'main' into optimize-logger
wxiaoguang Oct 21, 2021
fd46839
Merge branch 'main' into optimize-logger
wxiaoguang Oct 21, 2021
ebaee13
Merge branch 'main' into optimize-logger
wxiaoguang Oct 21, 2021
2f40634
Merge branch 'main' into optimize-logger
wxiaoguang Oct 28, 2021
ffc86fb
Merge remote-tracking branch 'zeripath/optimize-logger' into optimize…
wxiaoguang Oct 28, 2021
3eff51e
tune comments
wxiaoguang Oct 28, 2021
cca722c
we can use `time.NewTicker` safely and it reduces memory allocations.
wxiaoguang Oct 28, 2021
05de541
tune tests
wxiaoguang Oct 28, 2021
90ce83c
Merge branch 'main' into optimize-logger
wxiaoguang Nov 9, 2021
e7a5b6f
Merge branch 'main' into optimize-logger
wxiaoguang Nov 10, 2021
84768f6
Merge branch 'main' into optimize-logger
wxiaoguang Nov 13, 2021
a3de079
Merge branch 'main' into optimize-logger
wxiaoguang Nov 17, 2021
e3e212d
Merge branch 'main' into optimize-logger
wxiaoguang Nov 19, 2021
354127e
Merge remote-tracking branch 'go-gitea/main' into optimize-logger
wxiaoguang Nov 19, 2021
a0bc540
Merge branch 'main' into optimize-logger
wxiaoguang Nov 24, 2021
3bddad9
Merge branch 'main' into optimize-logger
wxiaoguang Dec 1, 2021
c2032bd
Fix merge
wxiaoguang Dec 1, 2021
afd3200
make the duration more readable
wxiaoguang Dec 1, 2021
90ead72
Merge branch 'main' into optimize-logger
wxiaoguang Dec 10, 2021
c92c4e9
Merge branch 'main' into optimize-logger
wxiaoguang Dec 20, 2021
f5332d8
Merge branch 'main' into optimize-logger
wxiaoguang Dec 21, 2021
8dafc18
show "started" message in DEBUG level, show long-polling message
wxiaoguang Dec 22, 2021
7a743f1
Merge branch 'main' into optimize-logger
wxiaoguang Dec 22, 2021
cb989fe
fix lint
wxiaoguang Dec 22, 2021
81ca64a
add comment
wxiaoguang Dec 22, 2021
bce0875
better format
wxiaoguang Dec 22, 2021
65a48bd
Generate FuncInfo outside of handlers and pre-wrap handlers
zeripath Dec 22, 2021
24760ed
Update messages
zeripath Dec 22, 2021
142957f
ourHandlerFunc -> wrappedHandlerFunc
zeripath Dec 23, 2021
e506e3e
move wrap to web
zeripath Dec 23, 2021
4836f06
Remove IsEnabledOn
zeripath Dec 23, 2021
bf08538
Move the requestrecord infrastructure to modules/web/routing
zeripath Dec 23, 2021
d3e6ded
Merge pull request #3 from zeripath/optimize-logger
wxiaoguang Dec 23, 2021
37d7928
fix comment for logger v1
wxiaoguang Dec 23, 2021
6d14aac
Improve app.example.ini and document, refactor wrap and router logger
wxiaoguang Dec 23, 2021
a284f30
fix documents and comments
wxiaoguang Dec 23, 2021
34ddd09
Merge branch 'main' into optimize-logger
wxiaoguang Dec 23, 2021
9f34791
fix log.ACCESS
wxiaoguang Dec 24, 2021
f7fe8a7
revert document
wxiaoguang Dec 24, 2021
78afbc0
Merge branch 'main' into optimize-logger
wxiaoguang Dec 25, 2021
4cb7e03
Remove logger v1
zeripath Dec 26, 2021
f0d5559
Merge pull request #5 from zeripath/optimize-logger-no-logger-v1
wxiaoguang Jan 20, 2022
00da10b
Merge branch 'main' into optimize-logger
wxiaoguang Jan 20, 2022
8d143fe
fix broken conflicts resolution
zeripath Jan 20, 2022
3e77481
Merge branch 'main' into optimize-logger
wxiaoguang Jan 20, 2022
f2cfdcf
Use TRACE level to show router started message
wxiaoguang Jan 20, 2022
5a39871
Fix document
wxiaoguang Jan 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func runWeb(ctx *cli.Context) error {
}
defer func() {
if panicked := recover(); panicked != nil {
log.Fatal("PANIC: %v\n%s", panicked, string(log.Stack(2)))
log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2))
}
}()

Expand Down
17 changes: 13 additions & 4 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -455,26 +455,35 @@ APP_ID = ; e.g. http://localhost:3000/
;; Use comma to separate multiple modes, e.g. "console, file"
MODE = console
;;
;; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
;; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical" or "None", default is "Info"
LEVEL = Info
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Router Logger
;;
;; Switch off the router log
;DISABLE_ROUTER_LOG= ; false
;DISABLE_ROUTER_LOG=false
;;
;; Set the log "modes" for the router log (if file is set the log file will default to router.log)
ROUTER = console
;;
;; The level at which the router logs
;ROUTER_LOG_LEVEL = Info
;; The router will log different things at different levels.
;;
;; * started messages will be logged at TRACE level
;; * polling/completed routers will be logged at INFO
;; * slow routers will be logged at WARN
;; * failed routers will be logged at WARN
;;
;; The routing level will default to that of the system but individual router level can be set in
;; [log.<mode>.router] LEVEL
;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Access Logger (Creates log in NCSA common log format)
;;
;ENABLE_ACCESS_LOG = false
;;
;; Set the log "modes" for the access log (if file is set the log file will default to access.log)
;ACCESS = file
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
;;
Expand Down
13 changes: 8 additions & 5 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type.

- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
- `DISABLE_ROUTER_LOG`: **false**: Mute printing of the router log.
- `CERT_FILE`: **https/cert.pem**: Cert file path used for HTTPS. When chaining, the server certificate must come first, then intermediate CA certificates (if any). From 1.11 paths are relative to `CUSTOM_PATH`.
- `KEY_FILE`: **https/key.pem**: Key file path used for HTTPS. From 1.11 paths are relative to `CUSTOM_PATH`.
- `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path.
Expand Down Expand Up @@ -752,11 +751,16 @@ Default templates for project boards:
- `MODE`: **console**: Logging mode. For multiple modes, use a comma to separate values. You can configure each mode in per mode log subsections `\[log.modename\]`. By default the file mode will log to `$ROOT_PATH/gitea.log`.
- `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
- `ENABLE_SSH_LOG`: **false**: save ssh log to log file
- `ENABLE_XORM_LOG`: **true**: Set whether to perform XORM logging. Please note SQL statement logging can be disabled by setting `LOG_SQL` to false in the `[database]` section.

### Router Log (`log`)
- `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\]`.
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\]`.

### Access Log (`log`)
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
- `ENABLE_SSH_LOG`: **false**: save ssh log to log file
- `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.)
zeripath marked this conversation as resolved.
Show resolved Hide resolved
- `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:
Expand All @@ -765,7 +769,6 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `Start`: the start time of the request.
- `ResponseWriter`: the responseWriter from the request.
- 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.
- `ENABLE_XORM_LOG`: **true**: Set whether to perform XORM logging. Please note SQL statement logging can be disabled by setting `LOG_SQL` to false in the `[database]` section.

### Log subsections (`log.name`, `log.name.*`)

Expand Down
19 changes: 13 additions & 6 deletions docs/content/doc/advanced/logging-documentation.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,23 @@ multiple subloggers that will log to files.

### The "Router" logger

You can disable Router log by setting `DISABLE_ROUTER_LOG`.
The Router logger has been substantially changed in v1.17. If you are using the router logger for fail2ban or other monitoring
you will need to update this configuration.

You can disable Router log by setting `DISABLE_ROUTER_LOG` or by setting all of its sublogger configurations to `none`.

You can configure the outputs of this
router log by setting the `ROUTER` value in the `[log]` section of the
configuration. `ROUTER` will default to `console` if unset. The Gitea
Router logs at the `Info` level by default, but this can be
changed if desired by setting the `ROUTER_LOG_LEVEL` value.
configuration. `ROUTER` will default to `console` if unset and will default to same level as main logger.

The Router logger logs the following:

- `started` messages will be logged at DEBUG level
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
- `slow` routers will be logged at WARN
- `polling`/`completed` routers will be logged at INFO
- `failed` routers will be logged at WARN

Please note, setting the `LEVEL` of this logger to a level above
`ROUTER_LOG_LEVEL` will result in no router logs.
The logging level for the router will default to that of the main configuration. Set `[log.<mode>.router]` `LEVEL` to change this.

Each output sublogger for this logger is configured in
`[log.sublogger.router]` sections. There are certain default values
Expand Down
11 changes: 8 additions & 3 deletions modules/log/colors_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package log

import (
"fmt"
"time"
)

Expand Down Expand Up @@ -72,12 +73,16 @@ var (
wayTooLong = ColorBytes(BgMagenta)
)

// ColoredTime adds colors for time on log
// ColoredTime converts the provided time to a ColoredValue for logging. The duration is always formatted in milliseconds.
func ColoredTime(duration time.Duration) *ColoredValue {
// the output of duration in Millisecond is more readable:
// * before: "100.1ms" "100.1μs" "100.1s"
// * better: "100.1ms" "0.1ms" "100100.0ms", readers can compare the values at first glance.
str := fmt.Sprintf("%.1fms", float64(duration.Microseconds())/1000)
for i, k := range durations {
if duration < k {
return NewColoredValueBytes(duration, &durationColors[i])
return NewColoredValueBytes(str, &durationColors[i])
}
}
return NewColoredValueBytes(duration, &wayTooLong)
return NewColoredValueBytes(str, &wayTooLong)
}
4 changes: 4 additions & 0 deletions modules/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,8 @@ func (l *LoggerAsWriter) Log(msg string) {
func init() {
_, filename, _, _ := runtime.Caller(0)
prefix = strings.TrimSuffix(filename, "modules/log/log.go")
if prefix == filename {
// in case the source code file is moved, we can not trim the suffix, the code above should also be updated.
panic("unable to detect correct package prefix, please update file: " + filename)
}
}
89 changes: 43 additions & 46 deletions modules/public/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ type Options struct {
CorsHandler func(http.Handler) http.Handler
}

// AssetsHandler implements the static handler for serving custom or original assets.
func AssetsHandler(opts *Options) func(next http.Handler) http.Handler {
// AssetsURLPathPrefix is the path prefix for static asset files
const AssetsURLPathPrefix = "/assets/"

// AssetsHandlerFunc implements the static handler for serving custom or original assets.
func AssetsHandlerFunc(opts *Options) http.HandlerFunc {
var custPath = filepath.Join(setting.CustomPath, "public")
if !filepath.IsAbs(custPath) {
custPath = filepath.Join(setting.AppWorkPath, custPath)
Expand All @@ -36,52 +39,46 @@ func AssetsHandler(opts *Options) func(next http.Handler) http.Handler {
opts.Prefix += "/"
}

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if !strings.HasPrefix(req.URL.Path, opts.Prefix) {
next.ServeHTTP(resp, req)
return
}
if req.Method != "GET" && req.Method != "HEAD" {
resp.WriteHeader(http.StatusNotFound)
return
}

file := req.URL.Path
file = file[len(opts.Prefix):]
if len(file) == 0 {
resp.WriteHeader(http.StatusNotFound)
return
}
if strings.Contains(file, "\\") {
resp.WriteHeader(http.StatusBadRequest)
return
}
file = "/" + file

var written bool
if opts.CorsHandler != nil {
written = true
opts.CorsHandler(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
written = false
})).ServeHTTP(resp, req)
}
if written {
return
}

// custom files
if opts.handle(resp, req, http.Dir(custPath), file) {
return
}

// internal files
if opts.handle(resp, req, fileSystem(opts.Directory), file) {
return
}
return func(resp http.ResponseWriter, req *http.Request) {
if req.Method != "GET" && req.Method != "HEAD" {
resp.WriteHeader(http.StatusNotFound)
return
}

file := req.URL.Path
file = file[len(opts.Prefix):]
if len(file) == 0 {
resp.WriteHeader(http.StatusNotFound)
})
return
}
if strings.Contains(file, "\\") {
resp.WriteHeader(http.StatusBadRequest)
return
}
file = "/" + file

var written bool
if opts.CorsHandler != nil {
written = true
opts.CorsHandler(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
written = false
})).ServeHTTP(resp, req)
}
if written {
return
}

// custom files
if opts.handle(resp, req, http.Dir(custPath), file) {
return
}

// internal files
if opts.handle(resp, req, fileSystem(opts.Directory), file) {
return
}

resp.WriteHeader(http.StatusNotFound)
}
}

Expand Down
7 changes: 5 additions & 2 deletions modules/setting/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func getStacktraceLogLevel(section *ini.Section, key, defaultValue string) strin

func generateLogConfig(sec *ini.Section, name string, defaults defaultLogOptions) (mode, jsonConfig, levelName string) {
level := getLogLevel(sec, "LEVEL", LogLevel)
levelName = level.String()
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
stacktraceLevelName := getStacktraceLogLevel(sec, "STACKTRACE_LEVEL", StacktraceLogLevel)
stacktraceLevel := log.FromString(stacktraceLevelName)
mode = name
Expand Down Expand Up @@ -254,8 +255,10 @@ func generateNamedLogger(key string, options defaultLogOptions) *LogDescription
func newAccessLogService() {
EnableAccessLog = Cfg.Section("log").Key("ENABLE_ACCESS_LOG").MustBool(false)
AccessLogTemplate = Cfg.Section("log").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}}"`)
Cfg.Section("log").Key("ACCESS").MustString("file")
`{{.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}}"`,
)
// the `MustString` updates the default value, and `log.ACCESS` is used by `generateNamedLogger("access")` later
_ = Cfg.Section("log").Key("ACCESS").MustString("file")
if EnableAccessLog {
options := newDefaultLogOptions()
options.filename = filepath.Join(LogRootPath, "access.log")
Expand Down
10 changes: 5 additions & 5 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,14 @@ var (
LogLevel log.Level
StacktraceLogLevel string
LogRootPath string
DisableRouterLog bool
RouterLogLevel log.Level
EnableAccessLog bool
EnableSSHLog bool
AccessLogTemplate string
EnableXORMLog bool

DisableRouterLog bool

EnableAccessLog bool
AccessLogTemplate string

// Time settings
TimeFormat string
// UILocation is the location on the UI, so that we can display the time on UI.
Expand Down Expand Up @@ -601,7 +602,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
StacktraceLogLevel = getStacktraceLogLevel(Cfg.Section("log"), "STACKTRACE_LEVEL", "None")
LogRootPath = Cfg.Section("log").Key("ROOT_PATH").MustString(path.Join(AppWorkPath, "log"))
forcePathSeparator(LogRootPath)
RouterLogLevel = log.FromString(Cfg.Section("log").Key("ROUTER_LOG_LEVEL").MustString("Info"))

sec := Cfg.Section("server")
AppName = Cfg.Section("").Key("APP_NAME").MustString("Gitea: Git with a cup of tea")
Expand Down
Loading