mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-02 23:41:05 +00:00 
			
		
		
		
	This PR adds a new manager command to switch on SQL logging and to turn it off. ``` gitea manager logging log-sql gitea manager logging log-sql --off ``` Signed-off-by: Andrew Thornton <art27@cantab.net>
		
			
				
	
	
		
			410 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2022 The Gitea Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a MIT-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package cmd
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"os"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/modules/log"
 | 
						|
	"code.gitea.io/gitea/modules/private"
 | 
						|
 | 
						|
	"github.com/urfave/cli"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	defaultLoggingFlags = []cli.Flag{
 | 
						|
		cli.StringFlag{
 | 
						|
			Name:  "group, g",
 | 
						|
			Usage: "Group to add logger to - will default to \"default\"",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "name, n",
 | 
						|
			Usage: "Name of the new logger - will default to mode",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "level, l",
 | 
						|
			Usage: "Logging level for the new logger",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "stacktrace-level, L",
 | 
						|
			Usage: "Stacktrace logging level",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "flags, F",
 | 
						|
			Usage: "Flags for the logger",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "expression, e",
 | 
						|
			Usage: "Matching expression for the logger",
 | 
						|
		}, cli.StringFlag{
 | 
						|
			Name:  "prefix, p",
 | 
						|
			Usage: "Prefix for the logger",
 | 
						|
		}, cli.BoolFlag{
 | 
						|
			Name:  "color",
 | 
						|
			Usage: "Use color in the logs",
 | 
						|
		}, cli.BoolFlag{
 | 
						|
			Name: "debug",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	subcmdLogging = cli.Command{
 | 
						|
		Name:  "logging",
 | 
						|
		Usage: "Adjust logging commands",
 | 
						|
		Subcommands: []cli.Command{
 | 
						|
			{
 | 
						|
				Name:  "pause",
 | 
						|
				Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
 | 
						|
				Flags: []cli.Flag{
 | 
						|
					cli.BoolFlag{
 | 
						|
						Name: "debug",
 | 
						|
					},
 | 
						|
				},
 | 
						|
				Action: runPauseLogging,
 | 
						|
			}, {
 | 
						|
				Name:  "resume",
 | 
						|
				Usage: "Resume logging",
 | 
						|
				Flags: []cli.Flag{
 | 
						|
					cli.BoolFlag{
 | 
						|
						Name: "debug",
 | 
						|
					},
 | 
						|
				},
 | 
						|
				Action: runResumeLogging,
 | 
						|
			}, {
 | 
						|
				Name:  "release-and-reopen",
 | 
						|
				Usage: "Cause Gitea to release and re-open files used for logging",
 | 
						|
				Flags: []cli.Flag{
 | 
						|
					cli.BoolFlag{
 | 
						|
						Name: "debug",
 | 
						|
					},
 | 
						|
				},
 | 
						|
				Action: runReleaseReopenLogging,
 | 
						|
			}, {
 | 
						|
				Name:      "remove",
 | 
						|
				Usage:     "Remove a logger",
 | 
						|
				ArgsUsage: "[name] Name of logger to remove",
 | 
						|
				Flags: []cli.Flag{
 | 
						|
					cli.BoolFlag{
 | 
						|
						Name: "debug",
 | 
						|
					}, cli.StringFlag{
 | 
						|
						Name:  "group, g",
 | 
						|
						Usage: "Group to add logger to - will default to \"default\"",
 | 
						|
					},
 | 
						|
				},
 | 
						|
				Action: runRemoveLogger,
 | 
						|
			}, {
 | 
						|
				Name:  "add",
 | 
						|
				Usage: "Add a logger",
 | 
						|
				Subcommands: []cli.Command{
 | 
						|
					{
 | 
						|
						Name:  "console",
 | 
						|
						Usage: "Add a console logger",
 | 
						|
						Flags: append(defaultLoggingFlags,
 | 
						|
							cli.BoolFlag{
 | 
						|
								Name:  "stderr",
 | 
						|
								Usage: "Output console logs to stderr - only relevant for console",
 | 
						|
							}),
 | 
						|
						Action: runAddConsoleLogger,
 | 
						|
					}, {
 | 
						|
						Name:  "file",
 | 
						|
						Usage: "Add a file logger",
 | 
						|
						Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
						|
							cli.StringFlag{
 | 
						|
								Name:  "filename, f",
 | 
						|
								Usage: "Filename for the logger - this must be set.",
 | 
						|
							}, cli.BoolTFlag{
 | 
						|
								Name:  "rotate, r",
 | 
						|
								Usage: "Rotate logs",
 | 
						|
							}, cli.Int64Flag{
 | 
						|
								Name:  "max-size, s",
 | 
						|
								Usage: "Maximum size in bytes before rotation",
 | 
						|
							}, cli.BoolTFlag{
 | 
						|
								Name:  "daily, d",
 | 
						|
								Usage: "Rotate logs daily",
 | 
						|
							}, cli.IntFlag{
 | 
						|
								Name:  "max-days, D",
 | 
						|
								Usage: "Maximum number of daily logs to keep",
 | 
						|
							}, cli.BoolTFlag{
 | 
						|
								Name:  "compress, z",
 | 
						|
								Usage: "Compress rotated logs",
 | 
						|
							}, cli.IntFlag{
 | 
						|
								Name:  "compression-level, Z",
 | 
						|
								Usage: "Compression level to use",
 | 
						|
							},
 | 
						|
						}...),
 | 
						|
						Action: runAddFileLogger,
 | 
						|
					}, {
 | 
						|
						Name:  "conn",
 | 
						|
						Usage: "Add a net conn logger",
 | 
						|
						Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
						|
							cli.BoolFlag{
 | 
						|
								Name:  "reconnect-on-message, R",
 | 
						|
								Usage: "Reconnect to host for every message",
 | 
						|
							}, cli.BoolFlag{
 | 
						|
								Name:  "reconnect, r",
 | 
						|
								Usage: "Reconnect to host when connection is dropped",
 | 
						|
							}, cli.StringFlag{
 | 
						|
								Name:  "protocol, P",
 | 
						|
								Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
 | 
						|
							}, cli.StringFlag{
 | 
						|
								Name:  "address, a",
 | 
						|
								Usage: "Host address and port to connect to (defaults to :7020)",
 | 
						|
							},
 | 
						|
						}...),
 | 
						|
						Action: runAddConnLogger,
 | 
						|
					}, {
 | 
						|
						Name:  "smtp",
 | 
						|
						Usage: "Add an SMTP logger",
 | 
						|
						Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
						|
							cli.StringFlag{
 | 
						|
								Name:  "username, u",
 | 
						|
								Usage: "Mail server username",
 | 
						|
							}, cli.StringFlag{
 | 
						|
								Name:  "password, P",
 | 
						|
								Usage: "Mail server password",
 | 
						|
							}, cli.StringFlag{
 | 
						|
								Name:  "host, H",
 | 
						|
								Usage: "Mail server host (defaults to: 127.0.0.1:25)",
 | 
						|
							}, cli.StringSliceFlag{
 | 
						|
								Name:  "send-to, s",
 | 
						|
								Usage: "Email address(es) to send to",
 | 
						|
							}, cli.StringFlag{
 | 
						|
								Name:  "subject, S",
 | 
						|
								Usage: "Subject header of sent emails",
 | 
						|
							},
 | 
						|
						}...),
 | 
						|
						Action: runAddSMTPLogger,
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}, {
 | 
						|
				Name:  "log-sql",
 | 
						|
				Usage: "Set LogSQL",
 | 
						|
				Flags: []cli.Flag{
 | 
						|
					cli.BoolFlag{
 | 
						|
						Name: "debug",
 | 
						|
					}, cli.BoolFlag{
 | 
						|
						Name:  "off",
 | 
						|
						Usage: "Switch off SQL logging",
 | 
						|
					},
 | 
						|
				},
 | 
						|
				Action: runSetLogSQL,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
func runRemoveLogger(c *cli.Context) error {
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	group := c.String("group")
 | 
						|
	if len(group) == 0 {
 | 
						|
		group = log.DEFAULT
 | 
						|
	}
 | 
						|
	name := c.Args().First()
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
 | 
						|
	statusCode, msg := private.RemoveLogger(ctx, group, name)
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func runAddSMTPLogger(c *cli.Context) error {
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	vals := map[string]interface{}{}
 | 
						|
	mode := "smtp"
 | 
						|
	if c.IsSet("host") {
 | 
						|
		vals["host"] = c.String("host")
 | 
						|
	} else {
 | 
						|
		vals["host"] = "127.0.0.1:25"
 | 
						|
	}
 | 
						|
 | 
						|
	if c.IsSet("username") {
 | 
						|
		vals["username"] = c.String("username")
 | 
						|
	}
 | 
						|
	if c.IsSet("password") {
 | 
						|
		vals["password"] = c.String("password")
 | 
						|
	}
 | 
						|
 | 
						|
	if !c.IsSet("send-to") {
 | 
						|
		return fmt.Errorf("Some recipients must be provided")
 | 
						|
	}
 | 
						|
	vals["sendTos"] = c.StringSlice("send-to")
 | 
						|
 | 
						|
	if c.IsSet("subject") {
 | 
						|
		vals["subject"] = c.String("subject")
 | 
						|
	} else {
 | 
						|
		vals["subject"] = "Diagnostic message from Gitea"
 | 
						|
	}
 | 
						|
 | 
						|
	return commonAddLogger(c, mode, vals)
 | 
						|
}
 | 
						|
 | 
						|
func runAddConnLogger(c *cli.Context) error {
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	vals := map[string]interface{}{}
 | 
						|
	mode := "conn"
 | 
						|
	vals["net"] = "tcp"
 | 
						|
	if c.IsSet("protocol") {
 | 
						|
		switch c.String("protocol") {
 | 
						|
		case "udp":
 | 
						|
			vals["net"] = "udp"
 | 
						|
		case "unix":
 | 
						|
			vals["net"] = "unix"
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if c.IsSet("address") {
 | 
						|
		vals["address"] = c.String("address")
 | 
						|
	} else {
 | 
						|
		vals["address"] = ":7020"
 | 
						|
	}
 | 
						|
	if c.IsSet("reconnect") {
 | 
						|
		vals["reconnect"] = c.Bool("reconnect")
 | 
						|
	}
 | 
						|
	if c.IsSet("reconnect-on-message") {
 | 
						|
		vals["reconnectOnMsg"] = c.Bool("reconnect-on-message")
 | 
						|
	}
 | 
						|
	return commonAddLogger(c, mode, vals)
 | 
						|
}
 | 
						|
 | 
						|
func runAddFileLogger(c *cli.Context) error {
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	vals := map[string]interface{}{}
 | 
						|
	mode := "file"
 | 
						|
	if c.IsSet("filename") {
 | 
						|
		vals["filename"] = c.String("filename")
 | 
						|
	} else {
 | 
						|
		return fmt.Errorf("filename must be set when creating a file logger")
 | 
						|
	}
 | 
						|
	if c.IsSet("rotate") {
 | 
						|
		vals["rotate"] = c.Bool("rotate")
 | 
						|
	}
 | 
						|
	if c.IsSet("max-size") {
 | 
						|
		vals["maxsize"] = c.Int64("max-size")
 | 
						|
	}
 | 
						|
	if c.IsSet("daily") {
 | 
						|
		vals["daily"] = c.Bool("daily")
 | 
						|
	}
 | 
						|
	if c.IsSet("max-days") {
 | 
						|
		vals["maxdays"] = c.Int("max-days")
 | 
						|
	}
 | 
						|
	if c.IsSet("compress") {
 | 
						|
		vals["compress"] = c.Bool("compress")
 | 
						|
	}
 | 
						|
	if c.IsSet("compression-level") {
 | 
						|
		vals["compressionLevel"] = c.Int("compression-level")
 | 
						|
	}
 | 
						|
	return commonAddLogger(c, mode, vals)
 | 
						|
}
 | 
						|
 | 
						|
func runAddConsoleLogger(c *cli.Context) error {
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	vals := map[string]interface{}{}
 | 
						|
	mode := "console"
 | 
						|
	if c.IsSet("stderr") && c.Bool("stderr") {
 | 
						|
		vals["stderr"] = c.Bool("stderr")
 | 
						|
	}
 | 
						|
	return commonAddLogger(c, mode, vals)
 | 
						|
}
 | 
						|
 | 
						|
func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error {
 | 
						|
	if len(c.String("level")) > 0 {
 | 
						|
		vals["level"] = log.FromString(c.String("level")).String()
 | 
						|
	}
 | 
						|
	if len(c.String("stacktrace-level")) > 0 {
 | 
						|
		vals["stacktraceLevel"] = log.FromString(c.String("stacktrace-level")).String()
 | 
						|
	}
 | 
						|
	if len(c.String("expression")) > 0 {
 | 
						|
		vals["expression"] = c.String("expression")
 | 
						|
	}
 | 
						|
	if len(c.String("prefix")) > 0 {
 | 
						|
		vals["prefix"] = c.String("prefix")
 | 
						|
	}
 | 
						|
	if len(c.String("flags")) > 0 {
 | 
						|
		vals["flags"] = log.FlagsFromString(c.String("flags"))
 | 
						|
	}
 | 
						|
	if c.IsSet("color") {
 | 
						|
		vals["colorize"] = c.Bool("color")
 | 
						|
	}
 | 
						|
	group := "default"
 | 
						|
	if c.IsSet("group") {
 | 
						|
		group = c.String("group")
 | 
						|
	}
 | 
						|
	name := mode
 | 
						|
	if c.IsSet("name") {
 | 
						|
		name = c.String("name")
 | 
						|
	}
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
 | 
						|
	statusCode, msg := private.AddLogger(ctx, group, name, mode, vals)
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func runPauseLogging(c *cli.Context) error {
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	statusCode, msg := private.PauseLogging(ctx)
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func runResumeLogging(c *cli.Context) error {
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	statusCode, msg := private.ResumeLogging(ctx)
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func runReleaseReopenLogging(c *cli.Context) error {
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
	statusCode, msg := private.ReleaseReopenLogging(ctx)
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func runSetLogSQL(c *cli.Context) error {
 | 
						|
	ctx, cancel := installSignals()
 | 
						|
	defer cancel()
 | 
						|
	setup("manager", c.Bool("debug"))
 | 
						|
 | 
						|
	statusCode, msg := private.SetLogSQL(ctx, !c.Bool("off"))
 | 
						|
	switch statusCode {
 | 
						|
	case http.StatusInternalServerError:
 | 
						|
		return fail("InternalServerError", msg)
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Fprintln(os.Stdout, msg)
 | 
						|
	return nil
 | 
						|
}
 |