WriterOption: log.WriterConsoleOption{Stderr: out == os.Stderr},
}
writer := log.NewEventWriterConsole("console-default", writeMode)
- log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer)
+ log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
+}
+
+// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
+// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
+func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error {
+ return func(c *cli.Context) error {
+ level := defaultLevel
+ if c.Bool("quiet") || c.GlobalBoolT("quiet") {
+ level = log.FATAL
+ }
+ if c.Bool("debug") || c.GlobalBool("debug") || c.Bool("verbose") || c.GlobalBool("verbose") {
+ level = log.TRACE
+ }
+ log.SetConsoleLogger(log.DEFAULT, "console-default", level)
+ return nil
+ }
}
log.FallbackErrorf("unable to create file log writer: %v", err)
return
}
- log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer)
+ log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
}
}
"time"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
Name: "hook",
Usage: "Delegate commands to corresponding Git hooks",
Description: "This should only be called by Git",
+ Before: PrepareConsoleLoggerLevel(log.FATAL),
Subcommands: []cli.Command{
subcmdHookPreReceive,
subcmdHookUpdate,
"fmt"
"strings"
+ "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli"
var CmdKeys = cli.Command{
Name: "keys",
Usage: "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint",
+ Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runKeys,
Flags: []cli.Flag{
cli.StringFlag{
Name: "serv",
Usage: "This command should only be called by SSH shell",
Description: "Serv provides access auth for repositories",
+ Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runServ,
Flags: []cli.Flag{
cli.BoolFlag{
Usage: "Start Gitea web server",
Description: `Gitea web server is the only thing you need to run,
and it takes care of all the other things for you`,
+ Before: PrepareConsoleLoggerLevel(log.INFO),
Action: runWeb,
Flags: []cli.Flag{
cli.StringFlag{
}
func runWeb(ctx *cli.Context) error {
- if ctx.Bool("verbose") {
- setupConsoleLogger(log.TRACE, log.CanColorStdout, os.Stdout)
- } else if ctx.Bool("quiet") {
- setupConsoleLogger(log.FATAL, log.CanColorStdout, os.Stdout)
- }
defer func() {
if panicked := recover(); panicked != nil {
log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2))
cmd.CmdActions,
}
- // default configuration flags
+ // shared configuration flags, they are for global and for each sub-command at the same time
+ // eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
+ // keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
globalFlags := []cli.Flag{
cli.HelpFlag,
cli.StringFlag{
// Set the default to be equivalent to cmdWeb and add the default flags
app.Flags = append(app.Flags, globalFlags...)
- app.Flags = append(app.Flags, cmd.CmdWeb.Flags...)
+ app.Flags = append(app.Flags, cmd.CmdWeb.Flags...) // TODO: the web flags polluted the global flags, they are not really global flags
app.Action = prepareWorkPathAndCustomConf(cmd.CmdWeb.Action)
app.HideHelp = true // use our own help action to show helps (with more information like default config)
+ app.Before = cmd.PrepareConsoleLoggerLevel(log.INFO)
app.Commands = append(app.Commands, cmdHelp)
for i := range app.Commands {
prepareSubcommands(&app.Commands[i], globalFlags)
Colorize: CanColorStdout,
WriterOption: WriterConsoleOption{},
})
- GetManager().GetLogger(loggerName).RemoveAllWriters().AddWriters(writer)
+ GetManager().GetLogger(loggerName).ReplaceAllWriters(writer)
}
func (l *LoggerImpl) AddWriters(writer ...EventWriter) {
l.eventWriterMu.Lock()
defer l.eventWriterMu.Unlock()
+ l.addWritersInternal(writer...)
+}
+func (l *LoggerImpl) addWritersInternal(writer ...EventWriter) {
for _, w := range writer {
if old, ok := l.eventWriters[w.GetWriterName()]; ok {
l.removeWriterInternal(old)
return nil
}
-// RemoveAllWriters removes all writers from the logger, non-shared writers are closed and flushed
-func (l *LoggerImpl) RemoveAllWriters() *LoggerImpl {
+// ReplaceAllWriters replaces all writers from the logger, non-shared writers are closed and flushed
+func (l *LoggerImpl) ReplaceAllWriters(writer ...EventWriter) {
l.eventWriterMu.Lock()
defer l.eventWriterMu.Unlock()
l.removeWriterInternal(w)
}
l.eventWriters = map[string]EventWriter{}
- l.syncLevelInternal()
- return l
+ l.addWritersInternal(writer...)
}
// DumpWriters dumps the writers as a JSON map, it's used for debugging and display purposes.
// Close closes the logger, non-shared writers are closed and flushed
func (l *LoggerImpl) Close() {
- l.RemoveAllWriters()
+ l.ReplaceAllWriters()
l.ctxCancel()
}
l.ctx, l.ctxCancel = newProcessTypedContext(ctx, "Logger: "+name)
l.LevelLogger = BaseLoggerToGeneralLogger(l)
l.eventWriters = map[string]EventWriter{}
- l.syncLevelInternal()
l.AddWriters(writer...)
return l
}
loggerTest := m.GetLogger("test")
loggerTest.AddWriters(w)
loggerTest.Info("msg-1")
- loggerTest.RemoveAllWriters() // the shared writer is not closed here
+ loggerTest.ReplaceAllWriters() // the shared writer is not closed here
loggerTest.Info("never seen")
// the shared writer can still be used later
eventWriters = append(eventWriters, eventWriter)
}
- manager.GetLogger(loggerName).RemoveAllWriters().AddWriters(eventWriters...)
+ manager.GetLogger(loggerName).ReplaceAllWriters(eventWriters...)
}
func InitSQLLoggersForCli(level log.Level) {