From 77b095a8c32c423dea495f94babe49d7f169f060 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:30:33 +0000 Subject: [PATCH] [chore] ensure consistent caller name fetching regardless of compiler inlining (#3323) * move logging levels into log package itself * ensure inconsistent inlining doesn't mess with log calling function name * remove unused global variable * fix log level --- cmd/process-emoji/main.go | 3 +- cmd/process-media/main.go | 3 +- go.mod | 1 - go.sum | 2 - internal/db/bundb/hook.go | 3 +- internal/log/caller.go | 12 +- internal/log/entry.go | 93 +++++-- internal/log/init.go | 18 +- internal/log/level.go | 38 +++ internal/log/log.go | 231 ++++++++++++------ internal/middleware/logger.go | 7 +- internal/processing/workers/fromclientapi.go | 3 +- internal/processing/workers/fromfediapi.go | 3 +- internal/router/router.go | 4 +- vendor/codeberg.org/gruf/go-logger/v2/LICENSE | 9 - .../gruf/go-logger/v2/level/levels.go | 63 ----- vendor/modules.txt | 3 - 17 files changed, 292 insertions(+), 204 deletions(-) create mode 100644 internal/log/level.go delete mode 100644 vendor/codeberg.org/gruf/go-logger/v2/LICENSE delete mode 100644 vendor/codeberg.org/gruf/go-logger/v2/level/levels.go diff --git a/cmd/process-emoji/main.go b/cmd/process-emoji/main.go index 0e999503e..d43962d88 100644 --- a/cmd/process-emoji/main.go +++ b/cmd/process-emoji/main.go @@ -24,7 +24,6 @@ import ( "os/signal" "syscall" - "codeberg.org/gruf/go-logger/v2/level" "codeberg.org/gruf/go-storage/memory" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db/bundb" @@ -41,7 +40,7 @@ func main() { ctx, cncl := signal.NotifyContext(ctx, syscall.SIGTERM, syscall.SIGINT) defer cncl() - log.SetLevel(level.INFO) + log.SetLevel(log.INFO) if len(os.Args) != 3 { log.Panic(ctx, "Usage: go run ./cmd/process-emoji ") diff --git a/cmd/process-media/main.go b/cmd/process-media/main.go index 7487917bf..9fc4983ec 100644 --- a/cmd/process-media/main.go +++ b/cmd/process-media/main.go @@ -24,7 +24,6 @@ import ( "os/signal" "syscall" - "codeberg.org/gruf/go-logger/v2/level" "codeberg.org/gruf/go-storage/memory" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db/bundb" @@ -40,7 +39,7 @@ func main() { ctx, cncl := signal.NotifyContext(ctx, syscall.SIGTERM, syscall.SIGINT) defer cncl() - log.SetLevel(level.INFO) + log.SetLevel(log.INFO) if len(os.Args) != 4 { log.Panic(ctx, "Usage: go run ./cmd/process-media ") diff --git a/go.mod b/go.mod index 58a93278e..e14990b14 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf codeberg.org/gruf/go-kv v1.6.4 codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f - codeberg.org/gruf/go-logger/v2 v2.2.1 codeberg.org/gruf/go-mempool v0.0.0-20240507125005-cef10d64a760 codeberg.org/gruf/go-mimetypes v1.2.0 codeberg.org/gruf/go-mutexes v1.5.1 diff --git a/go.sum b/go.sum index 2d4608b0f..3c9d29dc7 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,6 @@ codeberg.org/gruf/go-kv v1.6.4 h1:3NZiW8HVdBM3kpOiLb7XfRiihnzZWMAixdCznguhILk= codeberg.org/gruf/go-kv v1.6.4/go.mod h1:O/YkSvKiS9XsRolM3rqCd9YJmND7dAXu9z+PrlYO4bc= codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f h1:Ss6Z+vygy+jOGhj96d/GwsYYDd22QmIcH74zM7/nQkw= codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f/go.mod h1:F9pl4h34iuVN7kucKam9fLwsItTc+9mmaKt7pNXRd/4= -codeberg.org/gruf/go-logger/v2 v2.2.1 h1:RP2u059EQKTBFV3cN8X6xDxNk2RkzqdgXGKflKqB7Oc= -codeberg.org/gruf/go-logger/v2 v2.2.1/go.mod h1:m/vBfG5jNUmYXI8Hg9aVSk7Pn8YgEBITQB/B/CzdRss= codeberg.org/gruf/go-loosy v0.0.0-20231007123304-bb910d1ab5c4 h1:IXwfoU7f2whT6+JKIKskNl/hBlmWmnF1vZd84Eb3cyA= codeberg.org/gruf/go-loosy v0.0.0-20231007123304-bb910d1ab5c4/go.mod h1:fiO8HE1wjZCephcYmRRsVnNI/i0+mhy44Z5dQalS0rM= codeberg.org/gruf/go-mangler v1.4.1 h1:Dv58jFfy9On49L11ji6tpADUknwoJA46iaiZvnNXecs= diff --git a/internal/db/bundb/hook.go b/internal/db/bundb/hook.go index a8f225a38..16de74f11 100644 --- a/internal/db/bundb/hook.go +++ b/internal/db/bundb/hook.go @@ -22,7 +22,6 @@ import ( "time" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/uptrace/bun" ) @@ -50,7 +49,7 @@ func (queryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) { // On trace, we log query information, // manually crafting so DB query not escaped. - case log.Level() >= level.TRACE: + case log.Level() >= log.TRACE: log.Printf("level=TRACE duration=%s query=%s", dur, event.Query) } } diff --git a/internal/log/caller.go b/internal/log/caller.go index 75b8d82d9..5385b63b5 100644 --- a/internal/log/caller.go +++ b/internal/log/caller.go @@ -23,11 +23,13 @@ import ( ) // Caller fetches the calling function name, skipping 'depth'. +// +//go:noinline func Caller(depth int) string { - var pcs [1]uintptr + pcs := make([]uintptr, 1) - // Fetch calling function using calldepth - _ = runtime.Callers(depth, pcs[:]) + // Fetch calling func using depth. + _ = runtime.Callers(depth, pcs) fn := runtime.FuncForPC(pcs[0]) if fn == nil { @@ -37,14 +39,14 @@ func Caller(depth int) string { // Get func name. name := fn.Name() - // Drop all but the package name and function name, no mod path + // Drop all but package and function name, no path. if idx := strings.LastIndex(name, "/"); idx >= 0 { name = name[idx+1:] } const params = `[...]` - // Drop any generic type parameter markers + // Drop any function generic type parameter markers. if idx := strings.Index(name, params); idx >= 0 { name = name[:idx] + name[idx+len(params):] } diff --git a/internal/log/entry.go b/internal/log/entry.go index 103994fbf..52e90caed 100644 --- a/internal/log/entry.go +++ b/internal/log/entry.go @@ -20,10 +20,8 @@ package log import ( "context" "fmt" - "syscall" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" ) type Entry struct { @@ -31,93 +29,136 @@ type Entry struct { kvs []kv.Field } +// WithContext updates Entry{} value context. func (e Entry) WithContext(ctx context.Context) Entry { e.ctx = ctx return e } +// WithField appends key-value field to Entry{}. func (e Entry) WithField(key string, value interface{}) Entry { e.kvs = append(e.kvs, kv.Field{K: key, V: value}) return e } +// WithFields appends key-value fields to Entry{}. func (e Entry) WithFields(kvs ...kv.Field) Entry { e.kvs = append(e.kvs, kvs...) return e } +// Trace will log formatted args as 'msg' field to the log at TRACE level. +// +//go:noinline func (e Entry) Trace(a ...interface{}) { - logf(e.ctx, 3, level.TRACE, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, TRACE, e.kvs, args(len(a)), a...) } +// Tracef will log format string as 'msg' field to the log at TRACE level. +// +//go:noinline func (e Entry) Tracef(s string, a ...interface{}) { - logf(e.ctx, 3, level.TRACE, e.kvs, s, a...) + logf(e.ctx, 3, TRACE, e.kvs, s, a...) } +// Debug will log formatted args as 'msg' field to the log at DEBUG level. +// +//go:noinline func (e Entry) Debug(a ...interface{}) { - logf(e.ctx, 3, level.DEBUG, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, DEBUG, e.kvs, args(len(a)), a...) } +// Debugf will log format string as 'msg' field to the log at DEBUG level. +// +//go:noinline func (e Entry) Debugf(s string, a ...interface{}) { - logf(e.ctx, 3, level.DEBUG, e.kvs, s, a...) + logf(e.ctx, 3, DEBUG, e.kvs, s, a...) } +// Info will log formatted args as 'msg' field to the log at INFO level. +// +//go:noinline func (e Entry) Info(a ...interface{}) { - logf(e.ctx, 3, level.INFO, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, INFO, e.kvs, args(len(a)), a...) } +// Infof will log format string as 'msg' field to the log at INFO level. +// +//go:noinline func (e Entry) Infof(s string, a ...interface{}) { - logf(e.ctx, 3, level.INFO, e.kvs, s, a...) + logf(e.ctx, 3, INFO, e.kvs, s, a...) } +// Warn will log formatted args as 'msg' field to the log at WARN level. +// +//go:noinline func (e Entry) Warn(a ...interface{}) { - logf(e.ctx, 3, level.WARN, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, WARN, e.kvs, args(len(a)), a...) } +// Warnf will log format string as 'msg' field to the log at WARN level. +// +//go:noinline func (e Entry) Warnf(s string, a ...interface{}) { - logf(e.ctx, 3, level.WARN, e.kvs, s, a...) + logf(e.ctx, 3, WARN, e.kvs, s, a...) } +// Error will log formatted args as 'msg' field to the log at ERROR level. +// +//go:noinline func (e Entry) Error(a ...interface{}) { - logf(e.ctx, 3, level.ERROR, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, ERROR, e.kvs, args(len(a)), a...) } +// Errorf will log format string as 'msg' field to the log at ERROR level. +// +//go:noinline func (e Entry) Errorf(s string, a ...interface{}) { - logf(e.ctx, 3, level.ERROR, e.kvs, s, a...) -} - -func (e Entry) Fatal(a ...interface{}) { - defer syscall.Exit(1) - logf(e.ctx, 3, level.FATAL, e.kvs, args(len(a)), a...) -} - -func (e Entry) Fatalf(s string, a ...interface{}) { - defer syscall.Exit(1) - logf(e.ctx, 3, level.FATAL, e.kvs, s, a...) + logf(e.ctx, 3, ERROR, e.kvs, s, a...) } +// Panic will log formatted args as 'msg' field to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func (e Entry) Panic(a ...interface{}) { defer panic(fmt.Sprint(a...)) - logf(e.ctx, 3, level.PANIC, e.kvs, args(len(a)), a...) + logf(e.ctx, 3, PANIC, e.kvs, args(len(a)), a...) } +// Panicf will log format string as 'msg' field to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func (e Entry) Panicf(s string, a ...interface{}) { defer panic(fmt.Sprintf(s, a...)) - logf(e.ctx, 3, level.PANIC, e.kvs, s, a...) + logf(e.ctx, 3, PANIC, e.kvs, s, a...) } -func (e Entry) Log(lvl level.LEVEL, a ...interface{}) { +// Log will log formatted args as 'msg' field to the log at given level. +// +//go:noinline +func (e Entry) Log(lvl LEVEL, a ...interface{}) { logf(e.ctx, 3, lvl, e.kvs, args(len(a)), a...) } -func (e Entry) Logf(lvl level.LEVEL, s string, a ...interface{}) { +// Logf will log format string as 'msg' field to the log at given level. +// +//go:noinline +func (e Entry) Logf(lvl LEVEL, s string, a ...interface{}) { logf(e.ctx, 3, lvl, e.kvs, s, a...) } +// Print will log formatted args to the stdout log output. +// +//go:noinline func (e Entry) Print(a ...interface{}) { printf(3, e.kvs, args(len(a)), a...) } +// Printf will log format string to the stdout log output. +// +//go:noinline func (e Entry) Printf(s string, a ...interface{}) { printf(3, e.kvs, s, a...) } diff --git a/internal/log/init.go b/internal/log/init.go index 411a599d5..850ae8b5d 100644 --- a/internal/log/init.go +++ b/internal/log/init.go @@ -21,25 +21,23 @@ import ( "fmt" "log/syslog" "strings" - - "codeberg.org/gruf/go-logger/v2/level" ) -// ParseLevel will parse the log level from given string and set to appropriate level. +// ParseLevel will parse the log level from given string and set to appropriate LEVEL. func ParseLevel(str string) error { switch strings.ToLower(str) { case "trace": - SetLevel(level.TRACE) + SetLevel(TRACE) case "debug": - SetLevel(level.DEBUG) + SetLevel(DEBUG) case "", "info": - SetLevel(level.INFO) + SetLevel(INFO) case "warn": - SetLevel(level.WARN) + SetLevel(WARN) case "error": - SetLevel(level.ERROR) - case "fatal": - SetLevel(level.FATAL) + SetLevel(ERROR) + case "fatal", "panic": + SetLevel(PANIC) default: return fmt.Errorf("unknown log level: %q", str) } diff --git a/internal/log/level.go b/internal/log/level.go new file mode 100644 index 000000000..be45e2964 --- /dev/null +++ b/internal/log/level.go @@ -0,0 +1,38 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package log + +// LEVEL defines a level of logging. +type LEVEL uint8 + +// Default levels of logging. +const ( + UNSET LEVEL = 0 + PANIC LEVEL = 1 + ERROR LEVEL = 100 + WARN LEVEL = 150 + INFO LEVEL = 200 + DEBUG LEVEL = 250 + TRACE LEVEL = 254 + ALL LEVEL = ^LEVEL(0) +) + +// CanLog returns whether an incoming log of 'lvl' can be logged against receiving level. +func (loglvl LEVEL) CanLog(lvl LEVEL) bool { + return loglvl > lvl +} diff --git a/internal/log/log.go b/internal/log/log.go index c90a8167f..bb2e561b3 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -24,19 +24,26 @@ import ( "os" "slices" "strings" - "syscall" "time" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" ) var ( - // loglvl is the currently set logging level. - loglvl level.LEVEL + // loglvl is the currently + // set logging output + loglvl LEVEL - // lvlstrs is the lookup table of log levels to strings. - lvlstrs = level.Default() + // lvlstrs is the lookup table + // of all log levels to strings. + lvlstrs = [int(ALL) + 1]string{ + TRACE: "TRACE", + DEBUG: "DEBUG", + INFO: "INFO", + WARN: "WARN", + ERROR: "ERROR", + PANIC: "PANIC", + } // syslog output, only set if enabled. sysout *syslog.Writer @@ -54,13 +61,13 @@ func Hook(hook func(ctx context.Context, kvs []kv.Field) []kv.Field) { ctxhooks = append(ctxhooks, hook) } -// Level returns the currently set log level. -func Level() level.LEVEL { +// Level returns the currently set log +func Level() LEVEL { return loglvl } -// SetLevel sets the max logging level. -func SetLevel(lvl level.LEVEL) { +// SetLevel sets the max logging +func SetLevel(lvl LEVEL) { loglvl = lvl } @@ -83,174 +90,259 @@ func New() Entry { return Entry{} } +// WithContext returns a new prepared Entry{} with context. func WithContext(ctx context.Context) Entry { return Entry{ctx: ctx} } +// WithField returns a new prepared Entry{} with key-value field. func WithField(key string, value interface{}) Entry { - return New().WithField(key, value) + return Entry{kvs: []kv.Field{{K: key, V: value}}} } +// WithFields returns a new prepared Entry{} with key-value fields. func WithFields(fields ...kv.Field) Entry { - return New().WithFields(fields...) + return Entry{kvs: fields} } +// Note that most of the below logging +// functions we specifically do NOT allow +// the Go buildchain to inline, to ensure +// expected behaviour in caller fetching. + +// Trace will log formatted args as 'msg' field to the log at TRACE level. +// +//go:noinline func Trace(ctx context.Context, a ...interface{}) { - logf(ctx, 3, level.TRACE, nil, args(len(a)), a...) + logf(ctx, 3, TRACE, nil, args(len(a)), a...) } +// Tracef will log format string as 'msg' field to the log at TRACE level. +// +//go:noinline func Tracef(ctx context.Context, s string, a ...interface{}) { - logf(ctx, 3, level.TRACE, nil, s, a...) + logf(ctx, 3, TRACE, nil, s, a...) } +// TraceKV will log the one key-value field to the log at TRACE level. +// +//go:noinline func TraceKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.TRACE, []kv.Field{{K: key, V: value}}, "") + logf(ctx, 3, TRACE, []kv.Field{{K: key, V: value}}, "") } +// TraceKVs will log key-value fields to the log at TRACE level. +// +//go:noinline func TraceKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.TRACE, kvs, "") + logf(ctx, 3, TRACE, kvs, "") } +// Debug will log formatted args as 'msg' field to the log at DEBUG level. +// +//go:noinline func Debug(ctx context.Context, a ...interface{}) { - logf(ctx, 3, level.DEBUG, nil, args(len(a)), a...) + logf(ctx, 3, DEBUG, nil, args(len(a)), a...) } +// Debugf will log format string as 'msg' field to the log at DEBUG level. +// +//go:noinline func Debugf(ctx context.Context, s string, a ...interface{}) { - logf(ctx, 3, level.DEBUG, nil, s, a...) + logf(ctx, 3, DEBUG, nil, s, a...) } +// DebugKV will log the one key-value field to the log at DEBUG level. +// +//go:noinline func DebugKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.DEBUG, []kv.Field{{K: key, V: value}}, "") + logf(ctx, 3, DEBUG, []kv.Field{{K: key, V: value}}, "") } +// DebugKVs will log key-value fields to the log at DEBUG level. +// +//go:noinline func DebugKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.DEBUG, kvs, "") + logf(ctx, 3, DEBUG, kvs, "") } +// Info will log formatted args as 'msg' field to the log at INFO level. +// +//go:noinline func Info(ctx context.Context, a ...interface{}) { - logf(ctx, 3, level.INFO, nil, args(len(a)), a...) + logf(ctx, 3, INFO, nil, args(len(a)), a...) } +// Infof will log format string as 'msg' field to the log at INFO level. +// +//go:noinline func Infof(ctx context.Context, s string, a ...interface{}) { - logf(ctx, 3, level.INFO, nil, s, a...) + logf(ctx, 3, INFO, nil, s, a...) } +// InfoKV will log the one key-value field to the log at INFO level. +// +//go:noinline func InfoKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.INFO, []kv.Field{{K: key, V: value}}, "") + logf(ctx, 3, INFO, []kv.Field{{K: key, V: value}}, "") } +// InfoKVs will log key-value fields to the log at INFO level. +// +//go:noinline func InfoKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.INFO, kvs, "") + logf(ctx, 3, INFO, kvs, "") } +// Warn will log formatted args as 'msg' field to the log at WARN level. +// +//go:noinline func Warn(ctx context.Context, a ...interface{}) { - logf(ctx, 3, level.WARN, nil, args(len(a)), a...) + logf(ctx, 3, WARN, nil, args(len(a)), a...) } +// Warnf will log format string as 'msg' field to the log at WARN level. +// +//go:noinline func Warnf(ctx context.Context, s string, a ...interface{}) { - logf(ctx, 3, level.WARN, nil, s, a...) + logf(ctx, 3, WARN, nil, s, a...) } +// WarnKV will log the one key-value field to the log at WARN level. +// +//go:noinline func WarnKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.WARN, []kv.Field{{K: key, V: value}}, "") + logf(ctx, 3, WARN, []kv.Field{{K: key, V: value}}, "") } +// WarnKVs will log key-value fields to the log at WARN level. +// +//go:noinline func WarnKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.WARN, kvs, "") + logf(ctx, 3, WARN, kvs, "") } +// Error will log formatted args as 'msg' field to the log at ERROR level. +// +//go:noinline func Error(ctx context.Context, a ...interface{}) { - logf(ctx, 3, level.ERROR, nil, args(len(a)), a...) + logf(ctx, 3, ERROR, nil, args(len(a)), a...) } +// Errorf will log format string as 'msg' field to the log at ERROR level. +// +//go:noinline func Errorf(ctx context.Context, s string, a ...interface{}) { - logf(ctx, 3, level.ERROR, nil, s, a...) + logf(ctx, 3, ERROR, nil, s, a...) } +// ErrorKV will log the one key-value field to the log at ERROR level. +// +//go:noinline func ErrorKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.ERROR, []kv.Field{{K: key, V: value}}, "") + logf(ctx, 3, ERROR, []kv.Field{{K: key, V: value}}, "") } +// ErrorKVs will log key-value fields to the log at ERROR level. +// +//go:noinline func ErrorKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.WARN, kvs, "") -} - -func Fatal(ctx context.Context, a ...interface{}) { - defer syscall.Exit(1) - logf(ctx, 3, level.FATAL, nil, args(len(a)), a...) -} - -func Fatalf(ctx context.Context, s string, a ...interface{}) { - defer syscall.Exit(1) - logf(ctx, 3, level.FATAL, nil, s, a...) -} - -func FatalKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.FATAL, []kv.Field{{K: key, V: value}}, "") -} - -func FatalKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.FATAL, kvs, "") + logf(ctx, 3, ERROR, kvs, "") } +// Panic will log formatted args as 'msg' field to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func Panic(ctx context.Context, a ...interface{}) { defer panic(fmt.Sprint(a...)) - logf(ctx, 3, level.PANIC, nil, args(len(a)), a...) + logf(ctx, 3, PANIC, nil, args(len(a)), a...) } +// Panicf will log format string as 'msg' field to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func Panicf(ctx context.Context, s string, a ...interface{}) { defer panic(fmt.Sprintf(s, a...)) - logf(ctx, 3, level.PANIC, nil, s, a...) + logf(ctx, 3, PANIC, nil, s, a...) } +// PanicKV will log the one key-value field to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func PanicKV(ctx context.Context, key string, value interface{}) { - logf(ctx, 3, level.PANIC, []kv.Field{{K: key, V: value}}, "") + defer panic(kv.Field{K: key, V: value}.String()) + logf(ctx, 3, PANIC, []kv.Field{{K: key, V: value}}, "") } +// PanicKVs will log key-value fields to the log at PANIC level. +// This will then call panic causing the application to crash. +// +//go:noinline func PanicKVs(ctx context.Context, kvs ...kv.Field) { - logf(ctx, 3, level.PANIC, kvs, "") + defer panic(kv.Fields(kvs).String()) + logf(ctx, 3, PANIC, kvs, "") } // Log will log formatted args as 'msg' field to the log at given level. -func Log(ctx context.Context, lvl level.LEVEL, a ...interface{}) { +// +//go:noinline +func Log(ctx context.Context, lvl LEVEL, a ...interface{}) { logf(ctx, 3, lvl, nil, args(len(a)), a...) } // Logf will log format string as 'msg' field to the log at given level. -func Logf(ctx context.Context, lvl level.LEVEL, s string, a ...interface{}) { +// +//go:noinline +func Logf(ctx context.Context, lvl LEVEL, s string, a ...interface{}) { logf(ctx, 3, lvl, nil, s, a...) } // LogKV will log the one key-value field to the log at given level. -func LogKV(ctx context.Context, lvl level.LEVEL, key string, value interface{}) { //nolint:revive - logf(ctx, 3, level.DEBUG, []kv.Field{{K: key, V: value}}, "") +// +//go:noinline +func LogKV(ctx context.Context, lvl LEVEL, key string, value interface{}) { //nolint:revive + logf(ctx, 3, lvl, []kv.Field{{K: key, V: value}}, "") } // LogKVs will log key-value fields to the log at given level. -func LogKVs(ctx context.Context, lvl level.LEVEL, kvs ...kv.Field) { //nolint:revive +// +//go:noinline +func LogKVs(ctx context.Context, lvl LEVEL, kvs ...kv.Field) { //nolint:revive logf(ctx, 3, lvl, kvs, "") } // Print will log formatted args to the stdout log output. +// +//go:noinline func Print(a ...interface{}) { printf(3, nil, args(len(a)), a...) } // Printf will log format string to the stdout log output. +// +//go:noinline func Printf(s string, a ...interface{}) { printf(3, nil, s, a...) } // PrintKVs will log the one key-value field to the stdout log output. +// +//go:noinline func PrintKV(key string, value interface{}) { printf(3, []kv.Field{{K: key, V: value}}, "") } // PrintKVs will log key-value fields to the stdout log output. +// +//go:noinline func PrintKVs(kvs ...kv.Field) { printf(3, kvs, "") } +//go:noinline func printf(depth int, fields []kv.Field, s string, a ...interface{}) { // Acquire buffer buf := getBuf() @@ -279,7 +371,7 @@ func printf(depth int, fields []kv.Field, s string, a ...interface{}) { if sysout != nil { // Write log entry to syslog - logsys(level.INFO, buf.String()) + logsys(INFO, buf.String()) } // Write to log and release @@ -287,17 +379,18 @@ func printf(depth int, fields []kv.Field, s string, a ...interface{}) { putBuf(buf) } -func logf(ctx context.Context, depth int, lvl level.LEVEL, fields []kv.Field, s string, a ...interface{}) { +//go:noinline +func logf(ctx context.Context, depth int, lvl LEVEL, fields []kv.Field, s string, a ...interface{}) { var out *os.File // Check if enabled. - if lvl > Level() { + if lvl > loglvl { return } // Split errors to stderr, // all else goes to stdout. - if lvl <= level.ERROR { + if lvl <= ERROR { out = os.Stderr } else { out = os.Stdout @@ -354,21 +447,21 @@ func logf(ctx context.Context, depth int, lvl level.LEVEL, fields []kv.Field, s // logsys will log given msg at given severity to the syslog. // Max length: https://www.rfc-editor.org/rfc/rfc5424.html#section-6.1 -func logsys(lvl level.LEVEL, msg string) { +func logsys(lvl LEVEL, msg string) { if max := 2048; len(msg) > max { // Truncate up to max msg = msg[:max] } switch lvl { - case level.TRACE, level.DEBUG: + case TRACE, DEBUG: _ = sysout.Debug(msg) - case level.INFO: + case INFO: _ = sysout.Info(msg) - case level.WARN: + case WARN: _ = sysout.Warning(msg) - case level.ERROR: + case ERROR: _ = sysout.Err(msg) - case level.FATAL, level.PANIC: + case PANIC: _ = sysout.Crit(msg) } } diff --git a/internal/middleware/logger.go b/internal/middleware/logger.go index 89a0c396d..097c73cbd 100644 --- a/internal/middleware/logger.go +++ b/internal/middleware/logger.go @@ -26,7 +26,6 @@ import ( "codeberg.org/gruf/go-bytesize" "codeberg.org/gruf/go-errors/v2" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" "github.com/gin-gonic/gin" "github.com/superseriousbusiness/gotosocial/internal/gtscontext" "github.com/superseriousbusiness/gotosocial/internal/gtserror" @@ -99,11 +98,11 @@ func Logger(logClientIP bool) gin.HandlerFunc { l = l.WithFields(fields...) // Default is info - lvl := level.INFO + lvl := log.INFO if code >= 500 { - // Actual server error. - lvl = level.ERROR + // Actual error. + lvl = log.ERROR } if len(c.Errors) > 0 { diff --git a/internal/processing/workers/fromclientapi.go b/internal/processing/workers/fromclientapi.go index c8bc8352f..c5dfc157d 100644 --- a/internal/processing/workers/fromclientapi.go +++ b/internal/processing/workers/fromclientapi.go @@ -23,7 +23,6 @@ import ( "time" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtscontext" @@ -62,7 +61,7 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg *messages.Fro // Include GTSModel in logs if appropriate. if cMsg.GTSModel != nil && - log.Level() >= level.DEBUG { + log.Level() >= log.DEBUG { fields = append(fields, kv.Field{ "model", cMsg.GTSModel, }) diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go index d8abaa865..d3e714674 100644 --- a/internal/processing/workers/fromfediapi.go +++ b/internal/processing/workers/fromfediapi.go @@ -23,7 +23,6 @@ import ( "time" "codeberg.org/gruf/go-kv" - "codeberg.org/gruf/go-logger/v2/level" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing" @@ -69,7 +68,7 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF // Include GTSModel in logs if appropriate. if fMsg.GTSModel != nil && - log.Level() >= level.DEBUG { + log.Level() >= log.DEBUG { fields = append(fields, kv.Field{ "model", fMsg.GTSModel, }) diff --git a/internal/router/router.go b/internal/router/router.go index 3a790dec9..cf9033059 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -176,7 +176,7 @@ func (r *Router) Start() error { go func() { log.Infof(nil, "listening on %s", r.srv.Addr) if err := listen(); err != nil && err != http.ErrServerClosed { - log.Fatalf(nil, "listen: %s", err) + log.Panicf(nil, "listen: %v", err) } }() @@ -273,7 +273,7 @@ func (r *Router) letsEncryptTLS() (func() error, error) { log.Infof(nil, "letsencrypt listening on %s", leSrv.Addr) if err := leSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - log.Fatalf(nil, "letsencrypt: listen: %s", err) + log.Panicf(nil, "letsencrypt: listen: %v", err) } }() diff --git a/vendor/codeberg.org/gruf/go-logger/v2/LICENSE b/vendor/codeberg.org/gruf/go-logger/v2/LICENSE deleted file mode 100644 index e4163ae35..000000000 --- a/vendor/codeberg.org/gruf/go-logger/v2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2022 gruf - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/codeberg.org/gruf/go-logger/v2/level/levels.go b/vendor/codeberg.org/gruf/go-logger/v2/level/levels.go deleted file mode 100644 index 3b1715a3c..000000000 --- a/vendor/codeberg.org/gruf/go-logger/v2/level/levels.go +++ /dev/null @@ -1,63 +0,0 @@ -package level - -import ( - "fmt" - "strings" -) - -// LEVEL defines a level of logging. -type LEVEL uint8 - -// Default levels of logging. -const ( - UNSET LEVEL = 0 - PANIC LEVEL = 1 - FATAL LEVEL = 50 - ERROR LEVEL = 100 - WARN LEVEL = 150 - INFO LEVEL = 200 - DEBUG LEVEL = 250 - TRACE LEVEL = 254 - ALL LEVEL = ^LEVEL(0) -) - -// CanLog returns whether an incoming log of 'lvl' can be logged against receiving level. -func (loglvl LEVEL) CanLog(lvl LEVEL) bool { - return loglvl > lvl -} - -// Levels defines a mapping of log LEVELs to formatted level strings. -type Levels [int(ALL) + 1]string - -// Default returns the default set of log levels. -func Default() Levels { - return Levels{ - TRACE: "TRACE", - DEBUG: "DEBUG", - INFO: "INFO", - WARN: "WARN", - ERROR: "ERROR", - FATAL: "FATAL", - PANIC: "PANIC", - } -} - -// Get fetches the level string for the provided value. -func (l Levels) Get(lvl LEVEL) string { - return l[int(lvl)] -} - -// Parse will attempt to decode a LEVEL from given string, checking (case insensitive) against strings in Levels. -func (l Levels) Parse(s string) (LEVEL, error) { - // Ensure consistent casing - s = strings.ToUpper(s) - - for lvl := LEVEL(0); int(lvl) < len(l); lvl++ { - // Compare to eqach known level - if strings.ToUpper(l[lvl]) == s { - return lvl, nil - } - } - - return 0, fmt.Errorf("unrecognized log level: %s", s) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 19e346a1d..adaadae51 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -44,9 +44,6 @@ codeberg.org/gruf/go-kv/format # codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f ## explicit; go 1.21.3 codeberg.org/gruf/go-list -# codeberg.org/gruf/go-logger/v2 v2.2.1 -## explicit; go 1.19 -codeberg.org/gruf/go-logger/v2/level # codeberg.org/gruf/go-mangler v1.4.1 ## explicit; go 1.19 codeberg.org/gruf/go-mangler