From d58b61067f519e90bee843429076cfe14cf81d4fb67283e9022d5d4667264272 Mon Sep 17 00:00:00 2001 From: Lixen Wraith Date: Mon, 29 Sep 2025 04:47:48 -0400 Subject: [PATCH] e3.1.2 Changed output stdout to console for clarity. --- builder.go | 122 ++++++++++++++++++++++++++++++++-- builder_test.go | 4 +- config.go | 28 ++++---- config_test.go | 4 +- doc/compatibility-adapters.md | 4 +- doc/config-builder.md | 2 +- doc/configuration.md | 6 +- integration_test.go | 4 +- logger.go | 4 +- logger_test.go | 6 +- processor.go | 6 +- 11 files changed, 149 insertions(+), 41 deletions(-) diff --git a/builder.go b/builder.go index 85ff7c7..f30cc0a 100644 --- a/builder.go +++ b/builder.go @@ -94,12 +94,6 @@ func (b *Builder) MaxSizeMB(size int64) *Builder { return b } -// EnableStdout enables mirroring logs to stdout/stderr. -func (b *Builder) EnableStdout(enable bool) *Builder { - b.cfg.EnableStdout = enable - return b -} - // DisableFile disables file output entirely. func (b *Builder) DisableFile(disable bool) *Builder { b.cfg.DisableFile = disable @@ -118,6 +112,120 @@ func (b *Builder) HeartbeatIntervalS(interval int64) *Builder { return b } +// ShowTimestamp sets whether to show timestamps in logs. +func (b *Builder) ShowTimestamp(show bool) *Builder { + b.cfg.ShowTimestamp = show + return b +} + +// ShowLevel sets whether to show log levels. +func (b *Builder) ShowLevel(show bool) *Builder { + b.cfg.ShowLevel = show + return b +} + +// TimestampFormat sets the timestamp format string. +func (b *Builder) TimestampFormat(format string) *Builder { + b.cfg.TimestampFormat = format + return b +} + +// MaxTotalSizeKB sets the maximum total size of all log files in KB. +func (b *Builder) MaxTotalSizeKB(size int64) *Builder { + b.cfg.MaxTotalSizeKB = size + return b +} + +// MaxTotalSizeMB sets the maximum total size of all log files in MB. Convenience. +func (b *Builder) MaxTotalSizeMB(size int64) *Builder { + b.cfg.MaxTotalSizeKB = size * 1000 + return b +} + +// MinDiskFreeKB sets the minimum required free disk space in KB. +func (b *Builder) MinDiskFreeKB(size int64) *Builder { + b.cfg.MinDiskFreeKB = size + return b +} + +// MinDiskFreeMB sets the minimum required free disk space in MB. Convenience. +func (b *Builder) MinDiskFreeMB(size int64) *Builder { + b.cfg.MinDiskFreeKB = size * 1000 + return b +} + +// FlushIntervalMs sets the flush interval in milliseconds. +func (b *Builder) FlushIntervalMs(interval int64) *Builder { + b.cfg.FlushIntervalMs = interval + return b +} + +// TraceDepth sets the default trace depth for stack traces. +func (b *Builder) TraceDepth(depth int64) *Builder { + b.cfg.TraceDepth = depth + return b +} + +// RetentionPeriodHrs sets the log retention period in hours. +func (b *Builder) RetentionPeriodHrs(hours float64) *Builder { + b.cfg.RetentionPeriodHrs = hours + return b +} + +// RetentionCheckMins sets the retention check interval in minutes. +func (b *Builder) RetentionCheckMins(mins float64) *Builder { + b.cfg.RetentionCheckMins = mins + return b +} + +// DiskCheckIntervalMs sets the disk check interval in milliseconds. +func (b *Builder) DiskCheckIntervalMs(interval int64) *Builder { + b.cfg.DiskCheckIntervalMs = interval + return b +} + +// EnableAdaptiveInterval enables adaptive disk check intervals. +func (b *Builder) EnableAdaptiveInterval(enable bool) *Builder { + b.cfg.EnableAdaptiveInterval = enable + return b +} + +// EnablePeriodicSync enables periodic file sync. +func (b *Builder) EnablePeriodicSync(enable bool) *Builder { + b.cfg.EnablePeriodicSync = enable + return b +} + +// MinCheckIntervalMs sets the minimum disk check interval in milliseconds. +func (b *Builder) MinCheckIntervalMs(interval int64) *Builder { + b.cfg.MinCheckIntervalMs = interval + return b +} + +// MaxCheckIntervalMs sets the maximum disk check interval in milliseconds. +func (b *Builder) MaxCheckIntervalMs(interval int64) *Builder { + b.cfg.MaxCheckIntervalMs = interval + return b +} + +// ConsoleTarget sets the console output target ("stdout", "stderr", or "split"). +func (b *Builder) ConsoleTarget(target string) *Builder { + b.cfg.ConsoleTarget = target + return b +} + +// InternalErrorsToStderr sets whether to write internal errors to stderr. +func (b *Builder) InternalErrorsToStderr(enable bool) *Builder { + b.cfg.InternalErrorsToStderr = enable + return b +} + +// EnableConsole enables mirroring logs to console. +func (b *Builder) EnableConsole(enable bool) *Builder { + b.cfg.EnableConsole = enable + return b +} + // Example usage: // logger, err := log.NewBuilder(). // @@ -125,7 +233,7 @@ func (b *Builder) HeartbeatIntervalS(interval int64) *Builder { // LevelString("debug"). // Format("json"). // BufferSize(4096). -// EnableStdout(true). +// EnableConsole(true). // Build() // // if err == nil { diff --git a/builder_test.go b/builder_test.go index c4ffc2e..fd3a537 100644 --- a/builder_test.go +++ b/builder_test.go @@ -20,7 +20,7 @@ func TestBuilder_Build(t *testing.T) { LevelString("debug"). Format("json"). BufferSize(2048). - EnableStdout(true). + EnableConsole(true). MaxSizeMB(10). HeartbeatLevel(2). Build() @@ -43,7 +43,7 @@ func TestBuilder_Build(t *testing.T) { assert.Equal(t, LevelDebug, cfg.Level) assert.Equal(t, "json", cfg.Format) assert.Equal(t, int64(2048), cfg.BufferSize) - assert.True(t, cfg.EnableStdout, "EnableStdout should be true") + assert.True(t, cfg.EnableConsole, "EnableConsole should be true") assert.Equal(t, int64(10*1000), cfg.MaxSizeKB) assert.Equal(t, int64(2), cfg.HeartbeatLevel) }) diff --git a/config.go b/config.go index c393661..010f487 100644 --- a/config.go +++ b/config.go @@ -46,9 +46,9 @@ type Config struct { HeartbeatIntervalS int64 `toml:"heartbeat_interval_s"` // Interval seconds for heartbeat // Stdout/console output settings - EnableStdout bool `toml:"enable_stdout"` // Mirror logs to stdout/stderr - StdoutTarget string `toml:"stdout_target"` // "stdout" or "stderr" - DisableFile bool `toml:"disable_file"` // Disable file output entirely + EnableConsole bool `toml:"enable_console"` // Mirror logs to stdout/stderr + ConsoleTarget string `toml:"console_target"` // "stdout" or "stderr" + DisableFile bool `toml:"disable_file"` // Disable file output entirely // Internal error handling InternalErrorsToStderr bool `toml:"internal_errors_to_stderr"` // Write internal errors to stderr @@ -92,9 +92,9 @@ var defaultConfig = Config{ HeartbeatIntervalS: 60, // Stdout settings - EnableStdout: false, - StdoutTarget: "stdout", - DisableFile: false, + EnableConsole: false, + ConsoleTarget: "stdout", + DisableFile: false, // Internal error handling InternalErrorsToStderr: false, @@ -131,8 +131,8 @@ func (c *Config) Validate() error { return fmtErrorf("timestamp_format cannot be empty") } - if c.StdoutTarget != "stdout" && c.StdoutTarget != "stderr" && c.StdoutTarget != "split" { - return fmtErrorf("invalid stdout_target: '%s' (use stdout, stderr, or split)", c.StdoutTarget) + if c.ConsoleTarget != "stdout" && c.ConsoleTarget != "stderr" && c.ConsoleTarget != "split" { + return fmtErrorf("invalid console_target: '%s' (use stdout, stderr, or split)", c.ConsoleTarget) } // Numeric validations @@ -315,15 +315,15 @@ func applyConfigField(cfg *Config, key, value string) error { } cfg.HeartbeatIntervalS = intVal - // Stdout/console output settings - case "enable_stdout": + // Console output settings + case "enable_console": boolVal, err := strconv.ParseBool(value) if err != nil { - return fmtErrorf("invalid boolean value for enable_stdout '%s': %w", value, err) + return fmtErrorf("invalid boolean value for enable_console '%s': %w", value, err) } - cfg.EnableStdout = boolVal - case "stdout_target": - cfg.StdoutTarget = value + cfg.EnableConsole = boolVal + case "console_target": + cfg.ConsoleTarget = value case "disable_file": boolVal, err := strconv.ParseBool(value) if err != nil { diff --git a/config_test.go b/config_test.go index ec2628c..8d717f7 100644 --- a/config_test.go +++ b/config_test.go @@ -84,8 +84,8 @@ func TestConfigValidate(t *testing.T) { }, { name: "invalid stdout target", - modify: func(c *Config) { c.StdoutTarget = "invalid" }, - wantError: "invalid stdout_target", + modify: func(c *Config) { c.ConsoleTarget = "invalid" }, + wantError: "invalid console_target", }, { name: "min > max check interval", diff --git a/doc/compatibility-adapters.md b/doc/compatibility-adapters.md index 8821793..3e24f5e 100644 --- a/doc/compatibility-adapters.md +++ b/doc/compatibility-adapters.md @@ -286,7 +286,7 @@ builder := compat.NewBuilder(). "format=txt", // Human-readable "level=-4", // Debug level "trace_depth=3", // Include traces - "enable_stdout=true", // Console output + "enable_console=true", // Console output "flush_interval_ms=50", // Quick feedback ) ``` @@ -297,7 +297,7 @@ builder := compat.NewBuilder(). builder := compat.NewBuilder(). WithOptions( "disable_file=true", // No files - "enable_stdout=true", // Console only + "enable_console=true", // Console only "format=json", // For aggregators "level=0", // Info and above ) diff --git a/doc/config-builder.md b/doc/config-builder.md index 6865a1f..519c63e 100644 --- a/doc/config-builder.md +++ b/doc/config-builder.md @@ -28,7 +28,7 @@ All builder methods return `*ConfigBuilder` for chaining. Errors are accumulated | `Format(format string)` | `format`: Output format | Sets format ("txt", "json", "raw") | | `BufferSize(size int64)` | `size`: Buffer size | Sets channel buffer size | | `MaxSizeKB(size int64)` | `size`: Size in MB | Sets max file size | -| `EnableStdout(enable bool)` | `enable`: Boolean | Enables console output | +| `EnableConsole(enable bool)` | `enable`: Boolean | Enables console output | | `DisableFile(disable bool)` | `disable`: Boolean | Disables file output | | `HeartbeatLevel(level int64)` | `level`: 0-3 | Sets monitoring level | diff --git a/doc/configuration.md b/doc/configuration.md index 6f4ccac..fd18930 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -60,11 +60,11 @@ logger.Info("info txt log record written to /var/log/myapp.txt") |-----------|------|-------------|---------| | `show_timestamp` | `bool` | Include timestamps in log entries | `true` | | `show_level` | `bool` | Include log level in entries | `true` | -| `enable_stdout` | `bool` | Mirror logs to stdout/stderr | `false` | -| `stdout_target` | `string` | Console target: `"stdout"`, `"stderr"`, or `"split"` | `"stdout"` | +| `enable_console` | `bool` | Mirror logs to stdout/stderr | `false` | +| `console_target` | `string` | Console target: `"stdout"`, `"stderr"`, or `"split"` | `"stdout"` | | `disable_file` | `bool` | Disable file output (console-only) | `false` | -**Note:** When `stdout_target="split"`, INFO/DEBUG logs go to stdout while WARN/ERROR logs go to stderr. +**Note:** When `console_target="split"`, INFO/DEBUG logs go to stdout while WARN/ERROR logs go to stderr. ### Performance Tuning diff --git a/integration_test.go b/integration_test.go index 1b1d091..62d4b58 100644 --- a/integration_test.go +++ b/integration_test.go @@ -22,7 +22,7 @@ func TestFullLifecycle(t *testing.T) { Format("json"). MaxSizeKB(1). BufferSize(1000). - EnableStdout(false). + EnableConsole(false). HeartbeatLevel(1). HeartbeatIntervalS(2). Build() @@ -60,7 +60,7 @@ func TestFullLifecycle(t *testing.T) { logger.InfoTrace(2, "trace info") // Apply runtime override - err = logger.ApplyConfigString("enable_stdout=true", "stdout_target=stderr") + err = logger.ApplyConfigString("enable_console=true", "console_target=stderr") require.NoError(t, err) // More logging after reconfiguration diff --git a/logger.go b/logger.go index 2525b63..e655b71 100644 --- a/logger.go +++ b/logger.go @@ -430,9 +430,9 @@ func (l *Logger) applyConfig(cfg *Config) error { } // Setup stdout writer based on config - if cfg.EnableStdout { + if cfg.EnableConsole { var writer io.Writer - if cfg.StdoutTarget == "stderr" { + if cfg.ConsoleTarget == "stderr" { writer = os.Stderr } else { writer = os.Stdout diff --git a/logger_test.go b/logger_test.go index 5dcbf6c..0724923 100644 --- a/logger_test.go +++ b/logger_test.go @@ -89,12 +89,12 @@ func TestApplyConfigString(t *testing.T) { { name: "boolean values", configString: []string{ - "enable_stdout=true", + "enable_console=true", "disable_file=false", "show_timestamp=false", }, verify: func(t *testing.T, cfg *Config) { - assert.True(t, cfg.EnableStdout) + assert.True(t, cfg.EnableConsole) assert.False(t, cfg.DisableFile) assert.False(t, cfg.ShowTimestamp) }, @@ -265,7 +265,7 @@ func TestLoggerStdoutMirroring(t *testing.T) { cfg := DefaultConfig() cfg.Directory = t.TempDir() - cfg.EnableStdout = true + cfg.EnableConsole = true cfg.DisableFile = true err := logger.ApplyConfig(cfg) diff --git a/processor.go b/processor.go index 54d4de6..28a06ba 100644 --- a/processor.go +++ b/processor.go @@ -115,12 +115,12 @@ func (l *Logger) processLogRecord(record logRecord) int64 { dataLen := int64(len(data)) // Mirror to stdout if enabled - enableStdout := c.EnableStdout - if enableStdout { + enableConsole := c.EnableConsole + if enableConsole { if s := l.state.StdoutWriter.Load(); s != nil { if sinkWrapper, ok := s.(*sink); ok && sinkWrapper != nil { // Handle split mode - if c.StdoutTarget == "split" { + if c.ConsoleTarget == "split" { if record.Level >= LevelWarn { // Write WARN and ERROR to stderr _, _ = os.Stderr.Write(data)