From 1f9b4c37e16e30f79c34796b07f785c8d2c5319c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:25:45 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20make=20logger=20time=20format=20?= =?UTF-8?q?configurable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add SetTimeFormat to pkg/logger/logger.go - Add LoggerConfig to pkg/config/config.go - Set default TimeFormat in pkg/config/defaults.go - Apply configuration in cmd/picoclaw/internal/gateway/helpers.go - Add TestSetTimeFormat to pkg/logger/logger_test.go Co-authored-by: hobbyistlabs-coder <267281733+hobbyistlabs-coder@users.noreply.github.com> --- cmd/picoclaw/internal/gateway/helpers.go | 4 ++++ pkg/config/config.go | 5 +++++ pkg/config/defaults.go | 3 +++ pkg/logger/logger.go | 22 ++++++++++++++++++---- pkg/logger/logger_test.go | 12 ++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/cmd/picoclaw/internal/gateway/helpers.go b/cmd/picoclaw/internal/gateway/helpers.go index 91a5eeead..88f905edb 100644 --- a/cmd/picoclaw/internal/gateway/helpers.go +++ b/cmd/picoclaw/internal/gateway/helpers.go @@ -50,6 +50,10 @@ func gatewayCmd(debug bool) error { return fmt.Errorf("error loading config: %w", err) } + if cfg.Logger.TimeFormat != "" { + logger.SetTimeFormat(cfg.Logger.TimeFormat) + } + provider, modelID, err := providers.CreateProvider(cfg) if err != nil { return fmt.Errorf("error creating provider: %w", err) diff --git a/pkg/config/config.go b/pkg/config/config.go index 93e37d5fc..ed2508cd5 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -81,6 +81,7 @@ type Config struct { Channels ChannelsConfig `json:"channels"` Providers ProvidersConfig `json:"providers,omitempty"` ModelList []ModelConfig `json:"model_list"` // New model-centric provider configuration + Logger LoggerConfig `json:"logger"` Gateway GatewayConfig `json:"gateway"` Tools ToolsConfig `json:"tools"` Heartbeat HeartbeatConfig `json:"heartbeat"` @@ -561,6 +562,10 @@ func (c *ModelConfig) Validate() error { return nil } +type LoggerConfig struct { + TimeFormat string `json:"time_format" env:"PICOCLAW_LOGGER_TIME_FORMAT"` +} + type GatewayConfig struct { Host string `json:"host" env:"PICOCLAW_GATEWAY_HOST"` Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"` diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 4424b0eb1..df6831799 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -342,6 +342,9 @@ func DefaultConfig() *Config { APIKey: "", }, }, + Logger: LoggerConfig{ + TimeFormat: "15:04:05", + }, Gateway: GatewayConfig{ Host: "127.0.0.1", Port: 18790, diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index db13eaea9..1f2e82baf 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -30,9 +30,10 @@ var ( FATAL: "FATAL", } - currentLevel = INFO - logger zerolog.Logger - fileLogger zerolog.Logger + currentLevel = INFO + currentTimeFormat = "15:04:05" + logger zerolog.Logger + fileLogger zerolog.Logger logFile *os.File once sync.Once mu sync.RWMutex @@ -44,7 +45,7 @@ func init() { consoleWriter := zerolog.ConsoleWriter{ Out: os.Stdout, - TimeFormat: "15:04:05", // TODO: make it configurable??? + TimeFormat: currentTimeFormat, } logger = zerolog.New(consoleWriter).With().Timestamp().Logger() @@ -52,6 +53,19 @@ func init() { }) } +func SetTimeFormat(format string) { + mu.Lock() + defer mu.Unlock() + currentTimeFormat = format + + consoleWriter := zerolog.ConsoleWriter{ + Out: os.Stdout, + TimeFormat: currentTimeFormat, + } + + logger = zerolog.New(consoleWriter).With().Timestamp().Logger() +} + func SetLevel(level LogLevel) { mu.Lock() defer mu.Unlock() diff --git a/pkg/logger/logger_test.go b/pkg/logger/logger_test.go index 6e6f8dfa8..c8b31ec8a 100644 --- a/pkg/logger/logger_test.go +++ b/pkg/logger/logger_test.go @@ -137,3 +137,15 @@ func TestLoggerHelperFunctions(t *testing.T) { DebugC("test", "Debug with component") WarnF("Warning with fields", map[string]any{"key": "value"}) } + +func TestSetTimeFormat(t *testing.T) { + // This test just ensures that calling SetTimeFormat doesn't panic + // and updates the internal state. Since the logger is global and + // writes to stdout, we don't easily capture the output here without + // more complex mocking. + SetTimeFormat("2006-01-02 15:04:05") + Info("Testing time format change") + + // Restore default + SetTimeFormat("15:04:05") +}