package config
import (
"os"
"path/filepath"
"strings"
"time"
"github.com/sirupsen/logrus"
)
// Config holds the application configuration
type Config struct {
Version string
LogLevel logrus.Level
LogFile string
KubeConfig string
K8sContext string
Timeout time.Duration
QPS float32
Burst int
}
// DefaultConfig returns a default configuration
func DefaultConfig() *Config {
return &Config{
Version: "1.0.0",
LogLevel: logrus.InfoLevel,
LogFile: getDefaultLogFile(),
Timeout: 30 * time.Second,
QPS: 50.0,
Burst: 100,
}
}
// LoadFromEnv loads configuration from environment variables
func (c *Config) LoadFromEnv() {
if logLevel := os.Getenv("LOG_LEVEL"); logLevel != "" {
c.LogLevel = ParseLogLevel(logLevel)
}
if kubeConfig := os.Getenv("KUBECONFIG"); kubeConfig != "" {
c.KubeConfig = kubeConfig
}
if k8sContext := os.Getenv("K8S_CONTEXT"); k8sContext != "" {
c.K8sContext = k8sContext
}
}
// getDefaultLogFile returns the default log file path
func getDefaultLogFile() string {
homeDir, err := os.UserHomeDir()
if err != nil {
return "./mcp-k8swizard-logs"
}
return homeDir + "/mcp-k8swizard-logs"
}
// ParseLogLevel parses log level from string
func ParseLogLevel(level string) logrus.Level {
switch strings.ToUpper(level) {
case "DEBUG":
return logrus.DebugLevel
case "INFO":
return logrus.InfoLevel
case "WARN", "WARNING":
return logrus.WarnLevel
case "ERROR":
return logrus.ErrorLevel
default:
logrus.Warnf("Invalid LOG_LEVEL '%s', using INFO level. Valid levels: DEBUG, INFO, WARN, ERROR", level)
return logrus.InfoLevel
}
}
// Setup configures the logger with the specified configuration
func Setup(logLevel logrus.Level, logFile string) error {
// Create log file if it doesn't exist
if err := ensureLogFile(logFile); err != nil {
logrus.SetOutput(os.Stderr)
logrus.Warnf("Failed to create log file %s, using stderr: %v", logFile, err)
return err
}
// Open log file for writing with secure permissions
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
logrus.SetOutput(os.Stderr)
logrus.Warnf("Failed to open log file %s, using stderr: %v", logFile, err)
return err
}
// Configure logrus
logrus.SetOutput(file)
logrus.SetLevel(logLevel)
logrus.SetFormatter(&logrus.JSONFormatter{
TimestampFormat: "2006-01-02T15:04:05.000Z07:00",
})
// Log startup message
logrus.WithFields(logrus.Fields{
"log_file": logFile,
"log_level": logLevel.String(),
}).Info("Logger initialized")
return nil
}
// ensureLogFile ensures the log file directory exists
func ensureLogFile(logFile string) error {
dir := filepath.Dir(logFile)
return os.MkdirAll(dir, 0755)
}