mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-07-07 09:55:41 +02:00
Some checks are pending
/ release (push) Waiting to run
testing-integration / test-unit (push) Waiting to run
testing-integration / test-sqlite (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
This feature is intended to help reduce noisy logs generated by routine Kubernetes probes and Prometheus scraping. While logs are essential, these specific requests (e.g., to /metrics and /api/healthz) generally don't provide useful information and tend to clutter the output. The goal is to introduce functionality that effectively acts as the inverse of the existing EXPRESSION mode—allowing logging to be excluded based on a condition, rather than included. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8212 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: zokki <zokki.softwareschmiede@gmail.com> Co-committed-by: zokki <zokki.softwareschmiede@gmail.com>
358 lines
8.5 KiB
Go
358 lines
8.5 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"forgejo.org/modules/log"
|
|
"forgejo.org/modules/private"
|
|
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
func defaultLoggingFlags() []cli.Flag {
|
|
return []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "logger",
|
|
Usage: `Logger name - will default to "default"`,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "writer",
|
|
Usage: "Name of the log writer - will default to mode",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "level",
|
|
Usage: "Logging level for the new logger",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "stacktrace-level",
|
|
Aliases: []string{"L"},
|
|
Usage: "Stacktrace logging level",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "flags",
|
|
Aliases: []string{"F"},
|
|
Usage: "Flags for the logger",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "expression",
|
|
Aliases: []string{"e"},
|
|
Usage: "Matching expression for the logger",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "exclusion",
|
|
Aliases: []string{"x"},
|
|
Usage: "Exclusion for the logger",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "prefix",
|
|
Aliases: []string{"p"},
|
|
Usage: "Prefix for the logger",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "color",
|
|
Usage: "Use color in the logs",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "debug",
|
|
},
|
|
}
|
|
}
|
|
|
|
func subcmdLogging() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "logging",
|
|
Usage: "Adjust logging commands",
|
|
Commands: []*cli.Command{
|
|
{
|
|
Name: "pause",
|
|
Usage: "Pause logging (Forgejo 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 Forgejo 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: "logger",
|
|
Usage: `Logger name - will default to "default"`,
|
|
},
|
|
},
|
|
Action: runRemoveLogger,
|
|
}, {
|
|
Name: "add",
|
|
Usage: "Add a logger",
|
|
Commands: []*cli.Command{
|
|
{
|
|
Name: "file",
|
|
Usage: "Add a file logger",
|
|
Flags: append(defaultLoggingFlags(), []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "filename",
|
|
Aliases: []string{"f"},
|
|
Usage: "Filename for the logger - this must be set.",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "rotate",
|
|
Aliases: []string{"r"},
|
|
Usage: "Rotate logs",
|
|
Value: true,
|
|
},
|
|
&cli.Int64Flag{
|
|
Name: "max-size",
|
|
Aliases: []string{"s"},
|
|
Usage: "Maximum size in bytes before rotation",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "daily",
|
|
Aliases: []string{"d"},
|
|
Usage: "Rotate logs daily",
|
|
Value: true,
|
|
},
|
|
&cli.IntFlag{
|
|
Name: "max-days",
|
|
Aliases: []string{"D"},
|
|
Usage: "Maximum number of daily logs to keep",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "compress",
|
|
Aliases: []string{"z"},
|
|
Usage: "Compress rotated logs",
|
|
Value: true,
|
|
},
|
|
&cli.IntFlag{
|
|
Name: "compression-level",
|
|
Aliases: []string{"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",
|
|
Aliases: []string{"R"},
|
|
Usage: "Reconnect to host for every message",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "reconnect",
|
|
Aliases: []string{"r"},
|
|
Usage: "Reconnect to host when connection is dropped",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "protocol",
|
|
Aliases: []string{"P"},
|
|
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "address",
|
|
Aliases: []string{"a"},
|
|
Usage: "Host address and port to connect to (defaults to :7020)",
|
|
},
|
|
}...),
|
|
Action: runAddConnLogger,
|
|
},
|
|
},
|
|
}, {
|
|
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(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
logger := c.String("logger")
|
|
if len(logger) == 0 {
|
|
logger = log.DEFAULT
|
|
}
|
|
writer := c.Args().First()
|
|
|
|
extra := private.RemoveLogger(ctx, logger, writer)
|
|
return handleCliResponseExtra(extra)
|
|
}
|
|
|
|
func runAddConnLogger(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
vals := map[string]any{}
|
|
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(ctx, c, mode, vals)
|
|
}
|
|
|
|
func runAddFileLogger(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
vals := map[string]any{}
|
|
mode := "file"
|
|
if c.IsSet("filename") {
|
|
vals["filename"] = c.String("filename")
|
|
} else {
|
|
return errors.New("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(ctx, c, mode, vals)
|
|
}
|
|
|
|
func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[string]any) error {
|
|
if len(c.String("level")) > 0 {
|
|
vals["level"] = log.LevelFromString(c.String("level")).String()
|
|
}
|
|
if len(c.String("stacktrace-level")) > 0 {
|
|
vals["stacktraceLevel"] = log.LevelFromString(c.String("stacktrace-level")).String()
|
|
}
|
|
if len(c.String("expression")) > 0 {
|
|
vals["expression"] = c.String("expression")
|
|
}
|
|
if len(c.String("exclusion")) > 0 {
|
|
vals["exclusion"] = c.String("exclusion")
|
|
}
|
|
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")
|
|
}
|
|
logger := log.DEFAULT
|
|
if c.IsSet("logger") {
|
|
logger = c.String("logger")
|
|
}
|
|
writer := mode
|
|
if c.IsSet("writer") {
|
|
writer = c.String("writer")
|
|
}
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
extra := private.AddLogger(ctx, logger, writer, mode, vals)
|
|
return handleCliResponseExtra(extra)
|
|
}
|
|
|
|
func runPauseLogging(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
userMsg := private.PauseLogging(ctx)
|
|
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
|
return nil
|
|
}
|
|
|
|
func runResumeLogging(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
userMsg := private.ResumeLogging(ctx)
|
|
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
|
return nil
|
|
}
|
|
|
|
func runReleaseReopenLogging(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
|
|
setup(ctx, c.Bool("debug"), false)
|
|
userMsg := private.ReleaseReopenLogging(ctx)
|
|
_, _ = fmt.Fprintln(os.Stdout, userMsg)
|
|
return nil
|
|
}
|
|
|
|
func runSetLogSQL(ctx context.Context, c *cli.Command) error {
|
|
ctx, cancel := installSignals(ctx)
|
|
defer cancel()
|
|
setup(ctx, c.Bool("debug"), false)
|
|
|
|
extra := private.SetLogSQL(ctx, !c.Bool("off"))
|
|
return handleCliResponseExtra(extra)
|
|
}
|