loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix sub-command log level (#25537)

More fix for #24981

* #24981


Close #22361

* #22361

There were many patches for Gitea's sub-commands to satisfy the facts:

* Some sub-commands shouldn't output any log, otherwise the git protocol
would be broken
* Sometimes the users want to see "verbose" or "quiet" outputs

That's a longstanding problem, and very fragile. This PR is only a quick
patch for the problem.

In the future, the sub-command system should be refactored to a clear
solution.

----

Other changes:

* Use `ReplaceAllWriters` to replace
`RemoveAllWriters().AddWriters(writer)`, then it's an atomic operation.
* Remove unnecessary `syncLevelInternal` calls, because
`AddWriters/addWritersInternal` already calls it.

Co-authored-by: Giteabot <teabot@gitea.io>

authored by

wxiaoguang
Giteabot
and committed by
GitHub
65d3e116 b9433186

+39 -18
+17 -1
cmd/cmd.go
··· 106 106 WriterOption: log.WriterConsoleOption{Stderr: out == os.Stderr}, 107 107 } 108 108 writer := log.NewEventWriterConsole("console-default", writeMode) 109 - log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer) 109 + log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer) 110 + } 111 + 112 + // PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout. 113 + // Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever. 114 + func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error { 115 + return func(c *cli.Context) error { 116 + level := defaultLevel 117 + if c.Bool("quiet") || c.GlobalBoolT("quiet") { 118 + level = log.FATAL 119 + } 120 + if c.Bool("debug") || c.GlobalBool("debug") || c.Bool("verbose") || c.GlobalBool("verbose") { 121 + level = log.TRACE 122 + } 123 + log.SetConsoleLogger(log.DEFAULT, "console-default", level) 124 + return nil 125 + } 110 126 }
+1 -1
cmd/doctor.go
··· 151 151 log.FallbackErrorf("unable to create file log writer: %v", err) 152 152 return 153 153 } 154 - log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer) 154 + log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer) 155 155 } 156 156 } 157 157
+2
cmd/hook.go
··· 15 15 "time" 16 16 17 17 "code.gitea.io/gitea/modules/git" 18 + "code.gitea.io/gitea/modules/log" 18 19 "code.gitea.io/gitea/modules/private" 19 20 repo_module "code.gitea.io/gitea/modules/repository" 20 21 "code.gitea.io/gitea/modules/setting" ··· 32 33 Name: "hook", 33 34 Usage: "Delegate commands to corresponding Git hooks", 34 35 Description: "This should only be called by Git", 36 + Before: PrepareConsoleLoggerLevel(log.FATAL), 35 37 Subcommands: []cli.Command{ 36 38 subcmdHookPreReceive, 37 39 subcmdHookUpdate,
+2
cmd/keys.go
··· 8 8 "fmt" 9 9 "strings" 10 10 11 + "code.gitea.io/gitea/modules/log" 11 12 "code.gitea.io/gitea/modules/private" 12 13 13 14 "github.com/urfave/cli" ··· 17 18 var CmdKeys = cli.Command{ 18 19 Name: "keys", 19 20 Usage: "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint", 21 + Before: PrepareConsoleLoggerLevel(log.FATAL), 20 22 Action: runKeys, 21 23 Flags: []cli.Flag{ 22 24 cli.StringFlag{
+1
cmd/serv.go
··· 44 44 Name: "serv", 45 45 Usage: "This command should only be called by SSH shell", 46 46 Description: "Serv provides access auth for repositories", 47 + Before: PrepareConsoleLoggerLevel(log.FATAL), 47 48 Action: runServ, 48 49 Flags: []cli.Flag{ 49 50 cli.BoolFlag{
+1 -5
cmd/web.go
··· 35 35 Usage: "Start Gitea web server", 36 36 Description: `Gitea web server is the only thing you need to run, 37 37 and it takes care of all the other things for you`, 38 + Before: PrepareConsoleLoggerLevel(log.INFO), 38 39 Action: runWeb, 39 40 Flags: []cli.Flag{ 40 41 cli.StringFlag{ ··· 206 207 } 207 208 208 209 func runWeb(ctx *cli.Context) error { 209 - if ctx.Bool("verbose") { 210 - setupConsoleLogger(log.TRACE, log.CanColorStdout, os.Stdout) 211 - } else if ctx.Bool("quiet") { 212 - setupConsoleLogger(log.FATAL, log.CanColorStdout, os.Stdout) 213 - } 214 210 defer func() { 215 211 if panicked := recover(); panicked != nil { 216 212 log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2))
+5 -2
main.go
··· 108 108 cmd.CmdActions, 109 109 } 110 110 111 - // default configuration flags 111 + // shared configuration flags, they are for global and for each sub-command at the same time 112 + // eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed 113 + // keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore. 112 114 globalFlags := []cli.Flag{ 113 115 cli.HelpFlag, 114 116 cli.StringFlag{ ··· 128 130 129 131 // Set the default to be equivalent to cmdWeb and add the default flags 130 132 app.Flags = append(app.Flags, globalFlags...) 131 - app.Flags = append(app.Flags, cmd.CmdWeb.Flags...) 133 + app.Flags = append(app.Flags, cmd.CmdWeb.Flags...) // TODO: the web flags polluted the global flags, they are not really global flags 132 134 app.Action = prepareWorkPathAndCustomConf(cmd.CmdWeb.Action) 133 135 app.HideHelp = true // use our own help action to show helps (with more information like default config) 136 + app.Before = cmd.PrepareConsoleLoggerLevel(log.INFO) 134 137 app.Commands = append(app.Commands, cmdHelp) 135 138 for i := range app.Commands { 136 139 prepareSubcommands(&app.Commands[i], globalFlags)
+1 -1
modules/log/logger_global.go
··· 79 79 Colorize: CanColorStdout, 80 80 WriterOption: WriterConsoleOption{}, 81 81 }) 82 - GetManager().GetLogger(loggerName).RemoveAllWriters().AddWriters(writer) 82 + GetManager().GetLogger(loggerName).ReplaceAllWriters(writer) 83 83 }
+7 -6
modules/log/logger_impl.go
··· 96 96 func (l *LoggerImpl) AddWriters(writer ...EventWriter) { 97 97 l.eventWriterMu.Lock() 98 98 defer l.eventWriterMu.Unlock() 99 + l.addWritersInternal(writer...) 100 + } 99 101 102 + func (l *LoggerImpl) addWritersInternal(writer ...EventWriter) { 100 103 for _, w := range writer { 101 104 if old, ok := l.eventWriters[w.GetWriterName()]; ok { 102 105 l.removeWriterInternal(old) ··· 126 129 return nil 127 130 } 128 131 129 - // RemoveAllWriters removes all writers from the logger, non-shared writers are closed and flushed 130 - func (l *LoggerImpl) RemoveAllWriters() *LoggerImpl { 132 + // ReplaceAllWriters replaces all writers from the logger, non-shared writers are closed and flushed 133 + func (l *LoggerImpl) ReplaceAllWriters(writer ...EventWriter) { 131 134 l.eventWriterMu.Lock() 132 135 defer l.eventWriterMu.Unlock() 133 136 ··· 135 138 l.removeWriterInternal(w) 136 139 } 137 140 l.eventWriters = map[string]EventWriter{} 138 - l.syncLevelInternal() 139 - return l 141 + l.addWritersInternal(writer...) 140 142 } 141 143 142 144 // DumpWriters dumps the writers as a JSON map, it's used for debugging and display purposes. ··· 161 163 162 164 // Close closes the logger, non-shared writers are closed and flushed 163 165 func (l *LoggerImpl) Close() { 164 - l.RemoveAllWriters() 166 + l.ReplaceAllWriters() 165 167 l.ctxCancel() 166 168 } 167 169 ··· 233 235 l.ctx, l.ctxCancel = newProcessTypedContext(ctx, "Logger: "+name) 234 236 l.LevelLogger = BaseLoggerToGeneralLogger(l) 235 237 l.eventWriters = map[string]EventWriter{} 236 - l.syncLevelInternal() 237 238 l.AddWriters(writer...) 238 239 return l 239 240 }
+1 -1
modules/log/manager_test.go
··· 23 23 loggerTest := m.GetLogger("test") 24 24 loggerTest.AddWriters(w) 25 25 loggerTest.Info("msg-1") 26 - loggerTest.RemoveAllWriters() // the shared writer is not closed here 26 + loggerTest.ReplaceAllWriters() // the shared writer is not closed here 27 27 loggerTest.Info("never seen") 28 28 29 29 // the shared writer can still be used later
+1 -1
modules/setting/log.go
··· 244 244 eventWriters = append(eventWriters, eventWriter) 245 245 } 246 246 247 - manager.GetLogger(loggerName).RemoveAllWriters().AddWriters(eventWriters...) 247 + manager.GetLogger(loggerName).ReplaceAllWriters(eventWriters...) 248 248 } 249 249 250 250 func InitSQLLoggersForCli(level log.Level) {