package logger import ( "fmt" "log/syslog" "os" "time" "github.com/rs/zerolog" "github.com/rs/zerolog/pkgerrors" "base/config" ) type Level string type LogConfig struct { Environment string AppName string LogLevel Level Host string Port string Protocol string } const ( TRACE Level = "TRACE" DEBUG Level = "DEBUG" INFO Level = "INFO" WARN Level = "WARN" ERROR Level = "ERROR" PANIC Level = "PANIC" ) func New(appCfg *config.AppConfig) zerolog.Logger { zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack time.Sleep(700 * time.Millisecond) // Determine log level from configuration logLevel := INFO // Override with syslog log level if configured if appCfg.Syslog.LogLevel != "" { configuredLevel := Level(appCfg.Syslog.LogLevel) // Validate the configured level switch configuredLevel { case TRACE, DEBUG, INFO, WARN, ERROR, PANIC: logLevel = configuredLevel default: // If invalid level is configured, keep the default fmt.Printf("Invalid log level configured: %s, using default: %s\n", appCfg.Syslog.LogLevel, logLevel) } } cfg := LogConfig{ Environment: appCfg.Environment, AppName: appCfg.Name, // You can customize this or extract from config LogLevel: logLevel, Host: appCfg.Syslog.Host, // You may want to add these to your config Port: appCfg.Syslog.Port, // Default syslog port Protocol: "udp", // Default syslog protocol } switch cfg.Environment { case "development", "local": fmt.Printf("app %s using log level: %s Syslog.LogLevel: %s in %s \n", cfg.AppName, cfg.LogLevel, appCfg.Syslog.LogLevel, cfg.Environment) return zerolog.New( zerolog.NewConsoleWriter( func(w *zerolog.ConsoleWriter) { w.TimeFormat = "03:04:05.000PM" })). Level(logLevelToZero(cfg.LogLevel)). With(). Caller(). Timestamp(). Logger() default: fmt.Printf("app %s using log level: %s Syslog.LogLevel: %s in %s \n", cfg.AppName, cfg.LogLevel, appCfg.Syslog.LogLevel, cfg.Environment) syslogWriter, err := syslog.Dial( cfg.Protocol, fmt.Sprintf("%s:%s", cfg.Host, cfg.Port), syslog.LOG_INFO, cfg.AppName, ) if err != nil { fmt.Printf("Failed to connect to syslog: %s\n", err) return zerolog.New(os.Stdout). Level(logLevelToZero(cfg.LogLevel)). With(). Timestamp(). Logger() } return zerolog. New(zerolog.SyslogLevelWriter(syslogWriter)). Level(logLevelToZero(cfg.LogLevel)). With(). Caller(). Timestamp(). Logger() } } func logLevelToZero(level Level) zerolog.Level { switch level { case PANIC: return zerolog.PanicLevel case ERROR: return zerolog.ErrorLevel case WARN: return zerolog.WarnLevel case INFO: return zerolog.InfoLevel case DEBUG: return zerolog.DebugLevel case TRACE: return zerolog.TraceLevel default: return zerolog.InfoLevel } } // NewTestLogger creates a no-op logger for tests func NewTestLogger() zerolog.Logger { return zerolog.New(nil).Level(zerolog.Disabled) }