feat: add log-local-time flag for local timezone in logs

Add a --log-local-time flag that configures cloudflared to use local
timezone for log timestamps instead of the default UTC.

This helps users correlate logs with local system events and other
services running in their timezone.

The flag can also be set via the TUNNEL_LOG_LOCAL_TIME environment
variable.

Closes #1530
This commit is contained in:
Hugh 2026-01-28 20:25:39 -08:00
parent d7c62aed71
commit 10a654becb
5 changed files with 48 additions and 0 deletions

View File

@ -54,6 +54,12 @@ func ConfigureLoggingFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_TRACE_OUTPUT"},
Hidden: shouldHide,
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: flags.LogLocalTime,
Usage: "Use local timezone for log timestamps instead of UTC.",
EnvVars: []string{"TUNNEL_LOG_LOCAL_TIME"},
Hidden: shouldHide,
}),
FlagLogOutput,
}
}

View File

@ -143,6 +143,9 @@ const (
LogFormatOutputValueDefault = "default"
LogFormatOutputValueJSON = "json"
// LogLocalTime uses local timezone instead of UTC for log timestamps.
LogLocalTime = "log-local-time"
// TraceOutput is the command line flag to set the name of trace output file
TraceOutput = "trace-output"

View File

@ -115,6 +115,7 @@ var (
cfdflags.LogFile,
cfdflags.LogDirectory,
cfdflags.TraceOutput,
cfdflags.LogLocalTime,
cfdflags.ProxyDns,
"proxy-dns-port",
"proxy-dns-address",

View File

@ -44,6 +44,16 @@ func utcNow() time.Time {
return time.Now().UTC()
}
func localNow() time.Time {
return time.Now()
}
func configureTimestampFunc(useLocalTime bool) {
if useLocalTime {
zerolog.TimestampFunc = localNow
}
}
func fallbackLogger(err error) *zerolog.Logger {
failLog := fallbacklog.With().Logger()
fallbacklog.Error().Msgf("Falling back to a default logger due to logger setup failure: %s", err)
@ -146,6 +156,8 @@ func createFromContext(
logDirectoryFlagName string,
disableTerminal bool,
) *zerolog.Logger {
configureTimestampFunc(c.Bool(cfdflags.LogLocalTime))
logLevel := c.String(logLevelFlagName)
logFile := c.String(cfdflags.LogFile)
logDirectory := c.String(logDirectoryFlagName)

View File

@ -3,6 +3,7 @@ package logger
import (
"io"
"testing"
"time"
"github.com/pkg/errors"
"github.com/rs/zerolog"
@ -130,3 +131,28 @@ func TestResilientMultiWriter_Management(t *testing.T) {
})
}
}
func TestTimestampFunctions(t *testing.T) {
t.Run("utcNow returns UTC", func(t *testing.T) {
ts := utcNow()
_, offset := ts.Zone()
assert.Equal(t, 0, offset)
})
t.Run("localNow returns local timezone", func(t *testing.T) {
ts := localNow()
expected := time.Now()
_, expectedOffset := expected.Zone()
_, actualOffset := ts.Zone()
assert.Equal(t, expectedOffset, actualOffset)
})
t.Run("configureTimestampFunc sets local time when true", func(t *testing.T) {
configureTimestampFunc(true)
ts := zerolog.TimestampFunc()
expected := time.Now()
_, expectedOffset := expected.Zone()
_, actualOffset := ts.Zone()
assert.Equal(t, expectedOffset, actualOffset)
})
}