From d6feb408ce8e52b1cca103d499f68c2d8ba0c7e6 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Fri, 28 Mar 2025 14:15:34 -0500 Subject: [PATCH] use only global logger --- core/http/httplogger.go | 6 +-- core/http/server.go | 29 +++++----- core/logger/logger.go | 112 ++++++++++++++++++++++++++++++--------- core/watchers/api.go | 34 ++++++------ core/watchers/dir.go | 11 ++-- core/watchers/manager.go | 16 +++--- moonshark.go | 93 ++++++++++++++++---------------- 7 files changed, 175 insertions(+), 126 deletions(-) diff --git a/core/http/httplogger.go b/core/http/httplogger.go index 13ecac4..6fee2b4 100644 --- a/core/http/httplogger.go +++ b/core/http/httplogger.go @@ -18,12 +18,12 @@ const ( ) // LogRequest logs an HTTP request with custom formatting -func LogRequest(log *logger.Logger, statusCode int, r *http.Request, duration time.Duration) { +func LogRequest(statusCode int, r *http.Request, duration time.Duration) { statusColor := getStatusColor(statusCode) // Use the logger's raw message writer to bypass the standard format - log.LogRaw("%s%s%s %s%d %s%s %s %s(%v)%s", - colorGray, time.Now().Format(log.TimeFormat()), colorReset, + logger.LogRaw("%s%s%s %s%d %s%s %s %s(%v)%s", + colorGray, time.Now().Format(logger.TimeFormat()), colorReset, statusColor, statusCode, r.Method, colorReset, r.URL.Path, colorGray, duration, colorReset) } diff --git a/core/http/server.go b/core/http/server.go index 5a80f3f..ae1cb83 100644 --- a/core/http/server.go +++ b/core/http/server.go @@ -19,7 +19,6 @@ type Server struct { luaRouter *routers.LuaRouter staticRouter *routers.StaticRouter luaRunner *runner.LuaRunner - logger *logger.Logger httpServer *http.Server loggingEnabled bool debugMode bool // Controls whether to show error details @@ -28,15 +27,13 @@ type Server struct { } // New creates a new HTTP server with optimized connection settings -func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, - runner *runner.LuaRunner, log *logger.Logger, +func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, runner *runner.LuaRunner, loggingEnabled bool, debugMode bool, overrideDir string, config *config.Config) *Server { server := &Server{ luaRouter: luaRouter, staticRouter: staticRouter, luaRunner: runner, - logger: log, httpServer: &http.Server{}, loggingEnabled: loggingEnabled, debugMode: debugMode, @@ -63,13 +60,13 @@ func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, // ListenAndServe starts the server on the given address func (s *Server) ListenAndServe(addr string) error { s.httpServer.Addr = addr - s.logger.Info("Server listening at http://localhost%s", addr) + logger.Info("Server listening at http://localhost%s", addr) return s.httpServer.ListenAndServe() } // Shutdown gracefully shuts down the server func (s *Server) Shutdown(ctx context.Context) error { - s.logger.Info("Server shutting down...") + logger.Info("Server shutting down...") return s.httpServer.Shutdown(ctx) } @@ -84,7 +81,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Calculate and log request duration duration := time.Since(start) if s.loggingEnabled { - LogRequest(s.logger, http.StatusOK, r, duration) + LogRequest(http.StatusOK, r, duration) } return } @@ -103,13 +100,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Log the request with our custom format if s.loggingEnabled { - LogRequest(s.logger, statusCode, r, duration) + LogRequest(statusCode, r, duration) } } // handleRequest processes the actual request func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) { - s.logger.Debug("Processing request %s %s", r.Method, r.URL.Path) + logger.Debug("Processing request %s %s", r.Method, r.URL.Path) // Try Lua routes first params := &routers.Params{} @@ -126,7 +123,7 @@ func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) { errorMsg = node.Error.Error() } - s.logger.Error("%s %s - %s", r.Method, r.URL.Path, errorMsg) + logger.Error("%s %s - %s", r.Method, r.URL.Path, errorMsg) // Show error page with the actual error message w.Header().Set("Content-Type", "text/html; charset=utf-8") @@ -135,7 +132,7 @@ func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) { w.Write([]byte(errorHTML)) return } else if found { - s.logger.Debug("Found Lua route match for %s %s with %d params", r.Method, r.URL.Path, params.Count) + logger.Debug("Found Lua route match for %s %s with %d params", r.Method, r.URL.Path, params.Count) s.handleLuaRoute(w, r, bytecode, scriptPath, params) return } @@ -165,7 +162,7 @@ func (s *Server) handleLuaRoute(w http.ResponseWriter, r *http.Request, bytecode defer ctx.Release() // Log bytecode size - s.logger.Debug("Executing Lua route with %d bytes of bytecode", len(bytecode)) + logger.Debug("Executing Lua route with %d bytes of bytecode", len(bytecode)) // Add request info directly to context ctx.Set("method", r.Method) @@ -219,7 +216,7 @@ func (s *Server) handleLuaRoute(w http.ResponseWriter, r *http.Request, bytecode // Execute Lua script result, err := s.luaRunner.Run(bytecode, ctx, scriptPath) if err != nil { - s.logger.Error("Error executing Lua route: %v", err) + logger.Error("Error executing Lua route: %v", err) // Set content type to HTML w.Header().Set("Content-Type", "text/html; charset=utf-8") @@ -232,7 +229,7 @@ func (s *Server) handleLuaRoute(w http.ResponseWriter, r *http.Request, bytecode return } - writeResponse(w, result, s.logger) + writeResponse(w, result) } // Content types for responses @@ -242,7 +239,7 @@ const ( ) // writeResponse writes the Lua result to the HTTP response -func writeResponse(w http.ResponseWriter, result any, log *logger.Logger) { +func writeResponse(w http.ResponseWriter, result any) { if result == nil { w.WriteHeader(http.StatusNoContent) return @@ -283,7 +280,7 @@ func writeResponse(w http.ResponseWriter, result any, log *logger.Logger) { setContentTypeIfMissing(w, contentTypeJSON) data, err := json.Marshal(res) if err != nil { - log.Error("Failed to marshal response: %v", err) + logger.Error("Failed to marshal response: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } diff --git a/core/logger/logger.go b/core/logger/logger.go index 16e214d..a1b8e50 100644 --- a/core/logger/logger.go +++ b/core/logger/logger.go @@ -54,13 +54,20 @@ const ( defaultRateLimitTime = 10 * time.Second // How long to pause during rate limiting ) +// Single global logger instance with mutex for safe initialization +var ( + globalLogger *Logger + globalLoggerOnce sync.Once +) + // Logger handles logging operations type Logger struct { writer io.Writer level int useColors bool timeFormat string - mu sync.Mutex // Mutex for thread-safe writing + mu sync.Mutex // Mutex for thread-safe writing + debugMode atomic.Bool // Force debug logging regardless of level // Simple rate limiting logCount atomic.Int64 // Number of logs in current window @@ -71,8 +78,23 @@ type Logger struct { limitDuration time.Duration // How long to pause logging when rate limited } -// New creates a new logger -func New(minLevel int, useColors bool) *Logger { +// GetLogger returns the global logger instance, creating it if needed +func GetLogger() *Logger { + globalLoggerOnce.Do(func() { + globalLogger = newLogger(LevelInfo, true) + }) + return globalLogger +} + +// InitGlobalLogger initializes the global logger with custom settings +func InitGlobalLogger(minLevel int, useColors bool) { + globalLoggerOnce.Do(func() { + globalLogger = newLogger(minLevel, useColors) + }) +} + +// newLogger creates a new logger instance (internal use) +func newLogger(minLevel int, useColors bool) *Logger { logger := &Logger{ writer: os.Stdout, level: minLevel, @@ -88,6 +110,11 @@ func New(minLevel int, useColors bool) *Logger { return logger } +// New creates a new logger (deprecated - use GetLogger() instead) +func New(minLevel int, useColors bool) *Logger { + return newLogger(minLevel, useColors) +} + // resetCounters resets the rate limiting counters func (l *Logger) resetCounters() { l.logCount.Store(0) @@ -128,6 +155,21 @@ func (l *Logger) DisableColors() { l.useColors = false } +// EnableDebug forces debug logs to be shown regardless of level +func (l *Logger) EnableDebug() { + l.debugMode.Store(true) +} + +// DisableDebug stops forcing debug logs +func (l *Logger) DisableDebug() { + l.debugMode.Store(false) +} + +// IsDebugEnabled returns true if debug mode is enabled +func (l *Logger) IsDebugEnabled() bool { + return l.debugMode.Load() +} + // writeMessage writes a formatted log message directly to the writer func (l *Logger) writeMessage(level int, message string, rawMode bool) { var logLine string @@ -217,8 +259,9 @@ func (l *Logger) checkRateLimit(level int) bool { // log handles the core logging logic with level filtering func (l *Logger) log(level int, format string, args ...any) { - // First check normal level filtering - if level < l.level { + // Check if we should log this message + // Either level is high enough OR (it's a debug message AND debug mode is enabled) + if level < l.level && !(level == LevelDebug && l.debugMode.Load()) { return } @@ -326,50 +369,69 @@ func (l *Logger) Server(format string, args ...any) { l.log(LevelServer, format, args...) } -// Default global logger -var defaultLogger = New(LevelInfo, true) +// Global helper functions that use the global logger -// Debug logs a debug message to the default logger +// Debug logs a debug message to the global logger func Debug(format string, args ...any) { - defaultLogger.Debug(format, args...) + GetLogger().Debug(format, args...) } -// Info logs an informational message to the default logger +// Info logs an informational message to the global logger func Info(format string, args ...any) { - defaultLogger.Info(format, args...) + GetLogger().Info(format, args...) } -// Warning logs a warning message to the default logger +// Warning logs a warning message to the global logger func Warning(format string, args ...any) { - defaultLogger.Warning(format, args...) + GetLogger().Warning(format, args...) } -// Error logs an error message to the default logger +// Error logs an error message to the global logger func Error(format string, args ...any) { - defaultLogger.Error(format, args...) + GetLogger().Error(format, args...) } -// Fatal logs a fatal error message to the default logger and exits +// Fatal logs a fatal error message to the global logger and exits func Fatal(format string, args ...any) { - defaultLogger.Fatal(format, args...) + GetLogger().Fatal(format, args...) } -// Server logs a server message to the default logger +// Server logs a server message to the global logger func Server(format string, args ...any) { - defaultLogger.Server(format, args...) + GetLogger().Server(format, args...) } -// LogRaw logs a raw message to the default logger +// LogRaw logs a raw message to the global logger func LogRaw(format string, args ...any) { - defaultLogger.LogRaw(format, args...) + GetLogger().LogRaw(format, args...) } -// SetLevel changes the minimum log level of the default logger +// SetLevel changes the minimum log level of the global logger func SetLevel(level int) { - defaultLogger.SetLevel(level) + GetLogger().SetLevel(level) } -// SetOutput changes the output destination of the default logger +// SetOutput changes the output destination of the global logger func SetOutput(w io.Writer) { - defaultLogger.SetOutput(w) + GetLogger().SetOutput(w) +} + +// TimeFormat returns the current time format of the global logger +func TimeFormat() string { + return GetLogger().TimeFormat() +} + +// EnableDebug enables debug messages regardless of log level +func EnableDebug() { + GetLogger().EnableDebug() +} + +// DisableDebug disables forced debug messages +func DisableDebug() { + GetLogger().DisableDebug() +} + +// IsDebugEnabled returns true if debug mode is enabled +func IsDebugEnabled() bool { + return GetLogger().IsDebugEnabled() } diff --git a/core/watchers/api.go b/core/watchers/api.go index 7a69653..178a6b0 100644 --- a/core/watchers/api.go +++ b/core/watchers/api.go @@ -16,9 +16,9 @@ var ( ) // GetWatcherManager returns the global watcher manager, creating it if needed -func GetWatcherManager(log *logger.Logger, adaptive bool) *WatcherManager { +func GetWatcherManager(adaptive bool) *WatcherManager { globalManagerOnce.Do(func() { - globalManager = NewWatcherManager(log, adaptive) + globalManager = NewWatcherManager(adaptive) }) return globalManager } @@ -39,7 +39,7 @@ func WatchDirectory(config DirectoryWatcherConfig, manager *WatcherManager) (*Wa manager: manager, } - config.Log.Debug("Started watching directory: %s", config.Dir) + logger.Debug("Started watching directory: %s", config.Dir) return w, nil } @@ -58,12 +58,11 @@ func (w *Watcher) Close() error { // WatchLuaRouter sets up a watcher for a LuaRouter's routes directory; also updates // the LuaRunner so that the state can be rebuilt -func WatchLuaRouter(router *routers.LuaRouter, runner *runner.LuaRunner, routesDir string, log *logger.Logger) (*Watcher, error) { - manager := GetWatcherManager(log, true) // Use adaptive polling +func WatchLuaRouter(router *routers.LuaRouter, runner *runner.LuaRunner, routesDir string) (*Watcher, error) { + manager := GetWatcherManager(true) - // Create LuaRunner refresh callback runnerRefresh := func() error { - log.Debug("Refreshing LuaRunner state due to file change") + logger.Debug("Refreshing LuaRunner state due to file change") runner.NotifyFileChanged("") return nil } @@ -73,7 +72,6 @@ func WatchLuaRouter(router *routers.LuaRouter, runner *runner.LuaRunner, routesD config := DirectoryWatcherConfig{ Dir: routesDir, Callback: combinedCallback, - Log: log, Recursive: true, } @@ -82,18 +80,17 @@ func WatchLuaRouter(router *routers.LuaRouter, runner *runner.LuaRunner, routesD return nil, err } - log.Info("Started watching Lua routes directory: %s", routesDir) + logger.Info("Started watching Lua routes directory: %s", routesDir) return watcher, nil } // WatchStaticRouter sets up a watcher for a StaticRouter's root directory -func WatchStaticRouter(router *routers.StaticRouter, staticDir string, log *logger.Logger) (*Watcher, error) { - manager := GetWatcherManager(log, true) // Use adaptive polling +func WatchStaticRouter(router *routers.StaticRouter, staticDir string) (*Watcher, error) { + manager := GetWatcherManager(true) config := DirectoryWatcherConfig{ Dir: staticDir, Callback: router.Refresh, - Log: log, Recursive: true, } @@ -102,13 +99,13 @@ func WatchStaticRouter(router *routers.StaticRouter, staticDir string, log *logg return nil, err } - log.Info("Started watching static files directory: %s", staticDir) + logger.Info("Started watching static files directory: %s", staticDir) return watcher, nil } // WatchLuaModules sets up watchers for Lua module directories -func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger.Logger) ([]*Watcher, error) { - manager := GetWatcherManager(log, true) // Use adaptive polling +func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string) ([]*Watcher, error) { + manager := GetWatcherManager(true) watchers := make([]*Watcher, 0, len(libDirs)) for _, dir := range libDirs { @@ -116,11 +113,11 @@ func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger. dirCopy := dir // Capture for closure callback := func() error { - log.Debug("Detected changes in Lua module directory: %s", dirCopy) + logger.Debug("Detected changes in Lua module directory: %s", dirCopy) // Reload modules from this directory if err := luaRunner.ReloadAllModules(); err != nil { - log.Warning("Error reloading modules: %v", err) + logger.Warning("Error reloading modules: %v", err) } return nil @@ -129,7 +126,6 @@ func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger. config := DirectoryWatcherConfig{ Dir: dir, Callback: callback, - Log: log, Recursive: true, } @@ -143,7 +139,7 @@ func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger. } watchers = append(watchers, watcher) - log.Info("Started watching Lua modules directory: %s", dir) + logger.Info("Started watching Lua modules directory: %s", dir) } return watchers, nil diff --git a/core/watchers/dir.go b/core/watchers/dir.go index 9b7d43a..190380a 100644 --- a/core/watchers/dir.go +++ b/core/watchers/dir.go @@ -31,7 +31,6 @@ type DirectoryWatcher struct { // Configuration callback func() error - log *logger.Logger debounceTime time.Duration recursive bool @@ -49,9 +48,6 @@ type DirectoryWatcherConfig struct { // Callback function to call when changes are detected Callback func() error - // Logger instance - Log *logger.Logger - // Debounce time (0 means use default) DebounceTime time.Duration @@ -70,7 +66,6 @@ func NewDirectoryWatcher(config DirectoryWatcherConfig) (*DirectoryWatcher, erro dir: config.Dir, files: make(map[string]FileInfo), callback: config.Callback, - log: config.Log, debounceTime: debounceTime, recursive: config.Recursive, } @@ -217,15 +212,15 @@ func (w *DirectoryWatcher) notifyChange() { // logDebug logs a debug message with the watcher's directory prefix func (w *DirectoryWatcher) logDebug(format string, args ...any) { - w.log.Debug("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) + logger.Debug("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) } // logWarning logs a warning message with the watcher's directory prefix func (w *DirectoryWatcher) logWarning(format string, args ...any) { - w.log.Warning("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) + logger.Warning("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) } // logError logs an error message with the watcher's directory prefix func (w *DirectoryWatcher) logError(format string, args ...any) { - w.log.Error("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) + logger.Error("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...)) } diff --git a/core/watchers/manager.go b/core/watchers/manager.go index 39e64a4..e196aa1 100644 --- a/core/watchers/manager.go +++ b/core/watchers/manager.go @@ -29,22 +29,18 @@ type WatcherManager struct { done chan struct{} ticker *time.Ticker - // Logger - log *logger.Logger - // Wait group for shutdown coordination wg sync.WaitGroup } // NewWatcherManager creates a new watcher manager -func NewWatcherManager(log *logger.Logger, adaptive bool) *WatcherManager { +func NewWatcherManager(adaptive bool) *WatcherManager { manager := &WatcherManager{ watchers: make(map[string]*DirectoryWatcher), pollInterval: defaultPollInterval, adaptive: adaptive, lastActivity: time.Now(), done: make(chan struct{}), - log: log, } // Start the polling loop @@ -71,7 +67,7 @@ func (m *WatcherManager) AddWatcher(watcher *DirectoryWatcher) { defer m.mu.Unlock() m.watchers[watcher.dir] = watcher - m.log.Debug("[WatcherManager] Added watcher for directory: %s", watcher.dir) + logger.Debug("[WatcherManager] Added watcher for directory: %s", watcher.dir) } // RemoveWatcher unregisters a directory watcher @@ -80,7 +76,7 @@ func (m *WatcherManager) RemoveWatcher(dir string) { defer m.mu.Unlock() delete(m.watchers, dir) - m.log.Debug("[WatcherManager] Removed watcher for directory: %s", dir) + logger.Debug("[WatcherManager] Removed watcher for directory: %s", dir) } // pollLoop is the main polling loop that checks all watched directories @@ -100,7 +96,7 @@ func (m *WatcherManager) pollLoop() { if m.pollInterval > defaultPollInterval { m.pollInterval = defaultPollInterval m.ticker.Reset(m.pollInterval) - m.log.Debug("[WatcherManager] Reset to base polling interval: %v", m.pollInterval) + logger.Debug("[WatcherManager] Reset to base polling interval: %v", m.pollInterval) } } else { // No activity, consider slowing down polling @@ -108,7 +104,7 @@ func (m *WatcherManager) pollLoop() { if m.pollInterval == defaultPollInterval && inactiveDuration > inactivityThreshold { m.pollInterval = extendedPollInterval m.ticker.Reset(m.pollInterval) - m.log.Debug("[WatcherManager] Extended polling interval to: %v after %v of inactivity", + logger.Debug("[WatcherManager] Extended polling interval to: %v after %v of inactivity", m.pollInterval, inactiveDuration.Round(time.Minute)) } } @@ -129,7 +125,7 @@ func (m *WatcherManager) checkAllDirectories() bool { for _, watcher := range m.watchers { changed, err := watcher.checkForChanges() if err != nil { - m.log.Error("[WatcherManager] Error checking directory %s: %v", watcher.dir, err) + logger.Error("[WatcherManager] Error checking directory %s: %v", watcher.dir, err) continue } diff --git a/moonshark.go b/moonshark.go index 6bc46b7..ef2236b 100644 --- a/moonshark.go +++ b/moonshark.go @@ -26,7 +26,7 @@ type WatcherConfig struct { } // initRouters sets up the Lua and static routers -func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaRouter, *routers.StaticRouter, error) { +func initRouters(routesDir, staticDir string) (*routers.LuaRouter, *routers.StaticRouter, error) { // Ensure directories exist if err := utils.EnsureDir(routesDir); err != nil { return nil, nil, fmt.Errorf("routes directory doesn't exist, and could not create it: %v", err) @@ -41,12 +41,12 @@ func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaR // Check if this is a compilation warning or a more serious error if errors.Is(err, routers.ErrRoutesCompilationErrors) { // Some routes failed to compile, but router is still usable - log.Warning("Some Lua routes failed to compile. Check logs for details.") + logger.Warning("Some Lua routes failed to compile. Check logs for details.") // Log details about each failed route if failedRoutes := luaRouter.ReportFailedRoutes(); len(failedRoutes) > 0 { for _, re := range failedRoutes { - log.Error("Route %s %s failed to compile: %v", re.Method, re.Path, re.Err) + logger.Error("Route %s %s failed to compile: %v", re.Method, re.Path, re.Err) } } } else { @@ -54,14 +54,14 @@ func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaR return nil, nil, fmt.Errorf("failed to initialize Lua router: %v", err) } } - log.Info("Lua router initialized with routes from %s", routesDir) + logger.Info("Lua router initialized with routes from %s", routesDir) // Initialize static file router - staticRouter, err := routers.NewStaticRouterWithLogger(staticDir, log) + staticRouter, err := routers.NewStaticRouter(staticDir) if err != nil { return nil, nil, fmt.Errorf("failed to initialize static router: %v", err) } - log.Info("Static router initialized with files from %s", staticDir) + logger.Info("Static router initialized with files from %s", staticDir) staticRouter.EnableDebugLog() return luaRouter, staticRouter, nil @@ -70,15 +70,15 @@ func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaR // setupWatchers initializes and starts all file watchers func setupWatchers(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, luaRunner *runner.LuaRunner, routesDir string, staticDir string, - libDirs []string, log *logger.Logger, config WatcherConfig) ([]func() error, error) { + libDirs []string, config WatcherConfig) ([]func() error, error) { var cleanupFuncs []func() error // Set up watcher for Lua routes if config.Routes { - luaRouterWatcher, err := watchers.WatchLuaRouter(luaRouter, luaRunner, routesDir, log) + luaRouterWatcher, err := watchers.WatchLuaRouter(luaRouter, luaRunner, routesDir) if err != nil { - log.Warning("Failed to watch routes directory: %v", err) + logger.Warning("Failed to watch routes directory: %v", err) } else { cleanupFuncs = append(cleanupFuncs, luaRouterWatcher.Close) } @@ -86,9 +86,9 @@ func setupWatchers(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRou // Set up watcher for static files if config.Static { - staticWatcher, err := watchers.WatchStaticRouter(staticRouter, staticDir, log) + staticWatcher, err := watchers.WatchStaticRouter(staticRouter, staticDir) if err != nil { - log.Warning("Failed to watch static directory: %v", err) + logger.Warning("Failed to watch static directory: %v", err) } else { cleanupFuncs = append(cleanupFuncs, staticWatcher.Close) } @@ -96,15 +96,15 @@ func setupWatchers(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRou // Set up watchers for Lua modules libraries if config.Modules && len(libDirs) > 0 { - moduleWatchers, err := watchers.WatchLuaModules(luaRunner, libDirs, log) + moduleWatchers, err := watchers.WatchLuaModules(luaRunner, libDirs) if err != nil { - log.Warning("Failed to watch Lua module directories: %v", err) + logger.Warning("Failed to watch Lua module directories: %v", err) } else { for _, watcher := range moduleWatchers { w := watcher // Capture variable for closure cleanupFuncs = append(cleanupFuncs, w.Close) } - log.Info("File watchers active for %d Lua module directories", len(moduleWatchers)) + logger.Info("File watchers active for %d Lua module directories", len(moduleWatchers)) } } @@ -112,33 +112,38 @@ func setupWatchers(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRou } func main() { - // Initialize logger - log := logger.New(logger.LevelDebug, true) + // Initialize global logger with debug level + logger.InitGlobalLogger(logger.LevelDebug, true) - log.Server("Starting Moonshark server") + logger.Server("Starting Moonshark server") // Load configuration from config.lua cfg, err := config.Load("config.lua") if err != nil { - log.Warning("Failed to load config.lua: %v", err) - log.Info("Using default configuration") + logger.Warning("Failed to load config.lua: %v", err) + logger.Info("Using default configuration") cfg = config.New() } // Set log level from config switch cfg.GetString("log_level", "info") { - case "debug": - log.SetLevel(logger.LevelDebug) case "warn": - log.SetLevel(logger.LevelWarning) + logger.SetLevel(logger.LevelWarning) case "error": - log.SetLevel(logger.LevelError) + logger.SetLevel(logger.LevelError) case "server": - log.SetLevel(logger.LevelServer) + logger.SetLevel(logger.LevelServer) case "fatal": - log.SetLevel(logger.LevelFatal) + logger.SetLevel(logger.LevelFatal) default: - log.SetLevel(logger.LevelInfo) + logger.SetLevel(logger.LevelInfo) + } + + // Get debug mode setting + debugMode := cfg.GetBool("debug", false) + if debugMode { + logger.EnableDebug() // Force debug logs regardless of level + logger.Debug("Debug mode enabled") } // Get configuration values @@ -149,7 +154,7 @@ func main() { bufferSize := cfg.GetInt("buffer_size", 20) if err := utils.EnsureDir(overrideDir); err != nil { - log.Warning("Override directory doesn't exist, and could not create it: %v", err) + logger.Warning("Override directory doesn't exist, and could not create it: %v", err) overrideDir = "" // Disable overrides if directory can't be created } @@ -166,14 +171,14 @@ func main() { // Ensure lib directories exist for _, dir := range libDirs { if err := utils.EnsureDir(dir); err != nil { - log.Warning("Lib directory doesn't exist, and could not create it: %v", err) + logger.Warning("Lib directory doesn't exist, and could not create it: %v", err) } } // Initialize routers - luaRouter, staticRouter, err := initRouters(routesDir, staticDir, log) + luaRouter, staticRouter, err := initRouters(routesDir, staticDir) if err != nil { - log.Fatal("Router initialization failed: %v", err) + logger.Fatal("Router initialization failed: %v", err) } // Initialize Lua runner @@ -183,9 +188,9 @@ func main() { runner.WithDebugEnabled(), ) if err != nil { - log.Fatal("Failed to initialize Lua runner: %v", err) + logger.Fatal("Failed to initialize Lua runner: %v", err) } - log.Server("Lua runner initialized with buffer size %d", bufferSize) + logger.Server("Lua runner initialized with buffer size %d", bufferSize) defer luaRunner.Close() // Set up file watchers if enabled @@ -214,31 +219,29 @@ func main() { // Setup enabled watchers cleanupFuncs, err = setupWatchers(luaRouter, staticRouter, luaRunner, - routesDir, staticDir, libDirs, log, watcherConfig) + routesDir, staticDir, libDirs, watcherConfig) if err != nil { - log.Warning("Error setting up watchers: %v", err) + logger.Warning("Error setting up watchers: %v", err) } // Register cleanup functions defer func() { for _, cleanup := range cleanupFuncs { if err := cleanup(); err != nil { - log.Warning("Cleanup error: %v", err) + logger.Warning("Cleanup error: %v", err) } } }() httpLoggingEnabled := cfg.GetBool("http_logging_enabled", true) if httpLoggingEnabled { - log.Info("HTTP logging is enabled") + logger.Info("HTTP logging is enabled") } else { - log.Info("HTTP logging is disabled") + logger.Info("HTTP logging is disabled") } - debugMode := cfg.GetBool("debug", false) - // Create HTTP server - server := http.New(luaRouter, staticRouter, luaRunner, log, httpLoggingEnabled, debugMode, overrideDir, cfg) + server := http.New(luaRouter, staticRouter, luaRunner, httpLoggingEnabled, debugMode, overrideDir, cfg) // Handle graceful shutdown stop := make(chan os.Signal, 1) @@ -248,24 +251,24 @@ func main() { go func() { if err := server.ListenAndServe(fmt.Sprintf(":%d", port)); err != nil { if err.Error() != "http: Server closed" { - log.Error("Server error: %v", err) + logger.Error("Server error: %v", err) } } }() - log.Server("Server started on port %d", port) + logger.Server("Server started on port %d", port) // Wait for interrupt signal <-stop - log.Server("Shutdown signal received") + logger.Server("Shutdown signal received") // Gracefully shut down the server ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { - log.Error("Server shutdown error: %v", err) + logger.Error("Server shutdown error: %v", err) } - log.Server("Server stopped") + logger.Server("Server stopped") }