- // Copyright 2020 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"
- "time"
-
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
-
- "github.com/urfave/cli"
- )
-
- var (
- // CmdManager represents the manager command
- CmdManager = cli.Command{
- Name: "manager",
- Usage: "Manage the running gitea process",
- Description: "This is a command for managing the running gitea process",
- Subcommands: []cli.Command{
- subcmdShutdown,
- subcmdRestart,
- subcmdFlushQueues,
- subcmdLogging,
- },
- }
- subcmdShutdown = cli.Command{
- Name: "shutdown",
- Usage: "Gracefully shutdown the running process",
- Flags: []cli.Flag{
- cli.BoolFlag{
- Name: "debug",
- },
- },
- Action: runShutdown,
- }
- subcmdRestart = cli.Command{
- Name: "restart",
- Usage: "Gracefully restart the running process - (not implemented for windows servers)",
- Flags: []cli.Flag{
- cli.BoolFlag{
- Name: "debug",
- },
- },
- Action: runRestart,
- }
- subcmdFlushQueues = cli.Command{
- Name: "flush-queues",
- Usage: "Flush queues in the running process",
- Action: runFlushQueues,
- Flags: []cli.Flag{
- cli.DurationFlag{
- Name: "timeout",
- Value: 60 * time.Second,
- Usage: "Timeout for the flushing process",
- }, cli.BoolFlag{
- Name: "non-blocking",
- Usage: "Set to true to not wait for flush to complete before returning",
- },
- cli.BoolFlag{
- Name: "debug",
- },
- },
- }
- 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,
- },
- },
- },
- },
- }
- )
-
- 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()
- statusCode, msg := private.RemoveLogger(group, name)
- switch statusCode {
- case http.StatusInternalServerError:
- 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")
- }
- statusCode, msg := private.AddLogger(group, name, mode, vals)
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runShutdown(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.Shutdown()
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runRestart(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.Restart()
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runFlushQueues(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.FlushQueues(c.Duration("timeout"), c.Bool("non-blocking"))
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runPauseLogging(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.PauseLogging()
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runResumeLogging(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.ResumeLogging()
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
-
- func runReleaseReopenLogging(c *cli.Context) error {
- setup("manager", c.Bool("debug"))
- statusCode, msg := private.ReleaseReopenLogging()
- switch statusCode {
- case http.StatusInternalServerError:
- fail("InternalServerError", msg)
- }
-
- fmt.Fprintln(os.Stdout, msg)
- return nil
- }
|