diff --git a/logger/format.go b/logger/format.go deleted file mode 100644 index 9679a22..0000000 --- a/logger/format.go +++ /dev/null @@ -1,87 +0,0 @@ -// logger.go -package logger - -import ( - "encoding/json" - "fmt" - "log" - "reflect" -) - -// LogEntry represents the structure of a log entry. -type LogEntry struct { - Level string `json:"level"` - Timestamp string `json:"timestamp"` - Message string `json:"msg"` - Additional map[string]interface{} `json:"-"` -} - -// UnmarshalJSONLog customizes the unmarshalling of LogEntry to handle arbitrary key-value pairs. -func (le *LogEntry) UnmarshalJSONLog(data []byte) error { - // Unmarshal fixed fields first - type Alias LogEntry - aux := &struct { - *Alias - }{ - Alias: (*Alias)(le), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - // Unmarshal additional fields into a map - var additionalFields map[string]interface{} - if err := json.Unmarshal(data, &additionalFields); err != nil { - return err - } - - // Remove fixed fields from the map - delete(additionalFields, "level") - delete(additionalFields, "timestamp") - delete(additionalFields, "msg") - - le.Additional = additionalFields - return nil -} - -// ProcessLogs parses and outputs the log entries in a human-readable form. -func ProcessLogs(logEntries []string) { - for _, logEntryStr := range logEntries { - var logEntry LogEntry - if err := json.Unmarshal([]byte(logEntryStr), &logEntry); err != nil { - log.Printf("Failed to parse log entry: %v", err) - continue - } - - fmt.Printf("[%s] %s: %s\n", logEntry.Timestamp, logEntry.Level, logEntry.Message) - for key, value := range logEntry.Additional { - valueStr := formatValue(value) - fmt.Printf(" %s: %s\n", key, valueStr) - } - fmt.Println() - } -} - -// formatValue returns a string representation of the value, considering its type. -func formatValue(value interface{}) string { - if value == nil { - return "null" - } - val := reflect.ValueOf(value) - switch val.Kind() { - case reflect.String: - return fmt.Sprintf("%q", value) - case reflect.Int, reflect.Int64, reflect.Float64: - return fmt.Sprintf("%v", value) - case reflect.Bool: - return fmt.Sprintf("%t", value) - case reflect.Map, reflect.Slice, reflect.Array: - bytes, err := json.Marshal(value) - if err != nil { - return "error" - } - return string(bytes) - default: - return fmt.Sprintf("%v", value) - } -} diff --git a/logger/loggerconfig.go b/logger/loggerconfig.go index 7370dcc..83522d1 100644 --- a/logger/loggerconfig.go +++ b/logger/loggerconfig.go @@ -4,8 +4,6 @@ package logger // Ref: https://betterstack.com/community/guides/logging/go/zap/#logging-errors-with-zap import ( - "os" - "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -23,7 +21,10 @@ func BuildLogger(logLevel LogLevel, logOutputFormat string) Logger { // Set up custom encoder configuration encoderCfg := zap.NewProductionEncoderConfig() encoderCfg.TimeKey = "timestamp" - encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder // Use ISO8601 format for timestamps + encoderCfg.EncodeTime = zapcore.RFC3339TimeEncoder // ISO8601TimeEncoder /Use ISO8601 format for timestamps + encoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder // Encodes the level in uppercase (e.g., "INFO", "ERROR") with ANSI colour. + encoderCfg.EncodeCaller = zapcore.ShortCallerEncoder // Encodes the file and line number of the caller if the log level is at least DebugLevel + encoderCfg.EncodeName = zapcore.FullNameEncoder // Encodes the logger name // Convert the custom LogLevel to zap's logging level zapLogLevel := convertToZapLevel(logLevel) @@ -62,34 +63,6 @@ func BuildLogger(logLevel LogLevel, logOutputFormat string) Logger { } } -func NewHumanReadableLogger(logLevel LogLevel, logOutputFormat string) Logger { - encoderCfg := zap.NewProductionEncoderConfig() - encoderCfg.TimeKey = "timestamp" - encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder - - var encoder zapcore.Encoder - if logOutputFormat == LogOutputHumanReadable { - // For human-readable format, use a console encoder with customized level encoder - encoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder - encoder = zapcore.NewConsoleEncoder(encoderCfg) - } else { - // Default to JSON encoder for structured logging - encoder = zapcore.NewJSONEncoder(encoderCfg) - } - - core := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), convertToZapLevel(logLevel)) - - // Wrap the core with customCore to maintain field reordering logic - wrappedCore := &customCore{Core: core} - - logger := zap.New(wrappedCore, zap.AddCaller()) - - return &defaultLogger{ - logger: logger, - logLevel: logLevel, - } -} - // convertToZapLevel converts the custom LogLevel to a zapcore.Level func convertToZapLevel(level LogLevel) zapcore.Level { switch level {