From 69cf10f7024e4676314d16936aa3517e6197c111 Mon Sep 17 00:00:00 2001 From: Kevin Mesiab Date: Wed, 13 Mar 2024 08:27:31 -0700 Subject: [PATCH] feat: Add log level parsing func --- klogger.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ klogger_test.go | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 klogger_test.go diff --git a/klogger.go b/klogger.go index 8027cb7..f6cba18 100644 --- a/klogger.go +++ b/klogger.go @@ -15,6 +15,7 @@ package goklogger import ( "fmt" "runtime/debug" + "strings" "sync" "github.com/sirupsen/logrus" @@ -164,3 +165,61 @@ func (l *KLogger) Panic() *KLogger { return l } + +// ParseLogLevel takes a string representation of a log level (e.g., "info", "debug") and returns +// the corresponding logrus.Level. It is designed to be flexible, accepting any case and trimming +// unnecessary whitespace from the input. This function supports all standard logrus levels: +// "trace", "debug", "info", "warn"/"warning", "error", "fatal", and "panic". If the input does not +// match any of these levels, it defaults to logrus.InfoLevel. +// +// Parameters: +// - level: A string representing the desired log level. This parameter is case-insensitive and +// spaces before and after the level name are ignored. +// +// Returns: +// - A logrus.Level corresponding to the input string. If the input is unrecognized, the function +// defaults to returning logrus.InfoLevel. +// +// Usage: +// This function is particularly useful for parsing log level configurations from environment +// variables or configuration files where the input may vary in case or include additional spaces. +// It ensures that the application can dynamically adjust logging verbosity based on runtime +// configurations. +// +// Example: +// logLevel := ParseLogLevel(" DeBug ") +// log.SetLevel(logLevel) +// +// Note: +// The function treats "warn" and "warning" as equivalent, mapping both to logrus.WarnLevel, +// aligning with logrus's own handling of these terms. +func ParseLogLevel(level string) logrus.Level { + level = strings.ToLower(strings.TrimSpace(level)) + + switch level { + case "trace": + return logrus.TraceLevel + + case "debug": + return logrus.DebugLevel + + case "info": + return logrus.InfoLevel + + case "warn", "warning": // logrus treats "warn" and "warning" as equivalent + + return logrus.WarnLevel + case "error": + + return logrus.ErrorLevel + case "fatal": + + return logrus.FatalLevel + case "panic": + + return logrus.PanicLevel + default: + // It's a common practice to default to InfoLevel when an unknown level is provided + return logrus.InfoLevel + } +} diff --git a/klogger_test.go b/klogger_test.go new file mode 100644 index 0000000..fddf70a --- /dev/null +++ b/klogger_test.go @@ -0,0 +1,44 @@ +package goklogger + +import ( + "strings" + "testing" + + "github.com/sirupsen/logrus" +) + +func TestParseLogLevel(t *testing.T) { + tests := []struct { + name string + level string + expectedLevel logrus.Level + }{ + {name: "trace level", level: "trace", expectedLevel: logrus.TraceLevel}, + {name: "debug level", level: "debug", expectedLevel: logrus.DebugLevel}, + {name: "info level", level: "info", expectedLevel: logrus.InfoLevel}, + {name: "warn level", level: "warn", expectedLevel: logrus.WarnLevel}, + {name: "warning level", level: "warning", expectedLevel: logrus.WarnLevel}, // Test equivalent to "warn" + {name: "error level", level: "error", expectedLevel: logrus.ErrorLevel}, + {name: "fatal level", level: "fatal", expectedLevel: logrus.FatalLevel}, + {name: "panic level", level: "panic", expectedLevel: logrus.PanicLevel}, + {name: "default to info level", level: "unknown", expectedLevel: logrus.InfoLevel}, + {name: "case insensitivity", level: "DeBuG", expectedLevel: logrus.DebugLevel}, + {name: "leading/trailing spaces", level: " info ", expectedLevel: logrus.InfoLevel}, + + // Negative tests + {name: "numeric level", level: "123", expectedLevel: logrus.InfoLevel}, + {name: "special characters", level: "@#&*", expectedLevel: logrus.InfoLevel}, + {name: "empty string", level: "", expectedLevel: logrus.InfoLevel}, + {name: "whitespace only", level: " ", expectedLevel: logrus.InfoLevel}, + {name: "mixed characters", level: "info123", expectedLevel: logrus.InfoLevel}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualLevel := ParseLogLevel(tt.level) + if actualLevel != tt.expectedLevel { + t.Errorf("ParseLogLevel(%s) = %v, want %v", strings.TrimSpace(tt.level), actualLevel, tt.expectedLevel) + } + }) + } +}