From 4ae16bce8c6aa8e3d96ca69015d2065badee3994 Mon Sep 17 00:00:00 2001 From: Daenney Date: Mon, 21 Aug 2023 20:07:55 +0200 Subject: [feature] Make log format configurable (#2130) * [feature] Don't emit timestamp in log lines When running gotosocial with a service manager like systemd, or a container runtime, the associated log driver usually emits timestamps itself. In those cases, having the extra timestamp from our own log lines ends up being a bit noisy and when centrally ingesting logs is duplicate information. This introduces a configuration flag that allows disabling emitting the timestamp. It's only wired up for "daemonised" processes, meaning server and testrig. * [chore] Add docs for log-timestamp * [feature] Simplify timestamp handling Co-Authored-By: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> * [chore] Less escaped double-quotes * [chore] Fix help string --------- Co-authored-by: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> --- internal/log/log.go | 34 ++++++++++++++++++++++------------ internal/log/syslog_test.go | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) (limited to 'internal/log') diff --git a/internal/log/log.go b/internal/log/log.go index ae8607fc3..15c917757 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -23,7 +23,6 @@ import ( "log/syslog" "os" "strings" - "sync/atomic" "syscall" "time" @@ -33,7 +32,7 @@ import ( var ( // loglvl is the currently set logging level. - loglvl atomic.Uint32 + loglvl level.LEVEL // lvlstrs is the lookup table of log levels to strings. lvlstrs = level.Default() @@ -41,8 +40,9 @@ var ( // syslog output, only set if enabled. sysout *syslog.Writer - // timefmt is the logging time format used. - timefmt = "02/01/2006 15:04:05.000" + // timefmt is the logging time format used, which includes + // the full field and required quoting + timefmt = `timestamp="02/01/2006 15:04:05.000" ` // ctxhooks allows modifying log content based on context. ctxhooks []func(context.Context, []kv.Field) []kv.Field @@ -55,12 +55,26 @@ func Hook(hook func(ctx context.Context, kvs []kv.Field) []kv.Field) { // Level returns the currently set log level. func Level() level.LEVEL { - return level.LEVEL(loglvl.Load()) + return loglvl } // SetLevel sets the max logging level. func SetLevel(lvl level.LEVEL) { - loglvl.Store(uint32(lvl)) + loglvl = lvl +} + +// TimeFormat returns the currently-set timestamp format. +func TimeFormat() string { + return timefmt +} + +// SetTimeFormat sets the timestamp format to the given string. +func SetTimeFormat(format string) { + if format == "" { + timefmt = format + return + } + timefmt = `timestamp="` + format + `" ` } // New starts a new log entry. @@ -164,10 +178,8 @@ func printf(depth int, fields []kv.Field, s string, a ...interface{}) { // Acquire buffer buf := getBuf() - // Append formatted timestamp - buf.B = append(buf.B, `timestamp="`...) + // Append formatted timestamp according to `timefmt` buf.B = time.Now().AppendFormat(buf.B, timefmt) - buf.B = append(buf.B, `" `...) // Append formatted caller func buf.B = append(buf.B, `func=`...) @@ -217,10 +229,8 @@ func logf(ctx context.Context, depth int, lvl level.LEVEL, fields []kv.Field, s // Acquire buffer buf := getBuf() - // Append formatted timestamp - buf.B = append(buf.B, `timestamp="`...) + // Append formatted timestamp according to `timefmt` buf.B = time.Now().AppendFormat(buf.B, timefmt) - buf.B = append(buf.B, `" `...) // Append formatted caller func buf.B = append(buf.B, `func=`...) diff --git a/internal/log/syslog_test.go b/internal/log/syslog_test.go index e7e82ec58..7432e61b3 100644 --- a/internal/log/syslog_test.go +++ b/internal/log/syslog_test.go @@ -71,6 +71,22 @@ func (suite *SyslogTestSuite) TestSyslog() { suite.Regexp(regexp.MustCompile(`timestamp=.* func=.* level=INFO msg="this is a test of the emergency broadcast system!"`), entry["content"]) } +func (suite *SyslogTestSuite) TestSyslogDisableTimestamp() { + // Get the current format. + timefmt := log.TimeFormat() + + // Set an empty timestamp. + log.SetTimeFormat("") + + // Set old timestamp on return. + defer log.SetTimeFormat(timefmt) + + log.Info(nil, "this is a test of the emergency broadcast system!") + + entry := <-suite.syslogChannel + suite.Regexp(regexp.MustCompile(`func=.* level=INFO msg="this is a test of the emergency broadcast system!"`), entry["content"]) +} + func (suite *SyslogTestSuite) TestSyslogLongMessage() { log.Warn(nil, longMessage) -- cgit v1.3