add step list for server creation
All checks were successful
Release and Deploy / build (push) Successful in 9m5s
Release and Deploy / deploy (push) Successful in 26s

This commit is contained in:
Fran Jurmanović
2025-09-18 22:24:51 +02:00
parent 901dbe697e
commit 4004d83411
80 changed files with 950 additions and 2554 deletions

View File

@@ -15,7 +15,6 @@ var (
timeFormat = "2006-01-02 15:04:05.000"
)
// BaseLogger provides the core logging functionality
type BaseLogger struct {
file *os.File
logger *log.Logger
@@ -23,7 +22,6 @@ type BaseLogger struct {
initialized bool
}
// LogLevel represents different logging levels
type LogLevel string
const (
@@ -34,28 +32,23 @@ const (
LogLevelPanic LogLevel = "PANIC"
)
// Initialize creates a new base logger instance
func InitializeBase(tp string) (*BaseLogger, error) {
return newBaseLogger(tp)
}
func newBaseLogger(tp string) (*BaseLogger, error) {
// Ensure logs directory exists
if err := os.MkdirAll("logs", 0755); err != nil {
return nil, fmt.Errorf("failed to create logs directory: %v", err)
}
// Open log file with date in name
logPath := filepath.Join("logs", fmt.Sprintf("acc-server-%s-%s.log", time.Now().Format("2006-01-02"), tp))
file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
return nil, fmt.Errorf("failed to open log file: %v", err)
}
// Create multi-writer for both file and console
multiWriter := io.MultiWriter(file, os.Stdout)
// Create base logger
logger := &BaseLogger{
file: file,
logger: log.New(multiWriter, "", 0),
@@ -65,13 +58,11 @@ func newBaseLogger(tp string) (*BaseLogger, error) {
return logger, nil
}
// GetBaseLogger creates and returns a new base logger instance
func GetBaseLogger(tp string) *BaseLogger {
baseLogger, _ := InitializeBase(tp)
return baseLogger
}
// Close closes the log file
func (bl *BaseLogger) Close() error {
bl.mu.Lock()
defer bl.mu.Unlock()
@@ -82,7 +73,6 @@ func (bl *BaseLogger) Close() error {
return nil
}
// Log writes a log entry with the specified level
func (bl *BaseLogger) Log(level LogLevel, format string, v ...interface{}) {
if bl == nil || !bl.initialized {
return
@@ -91,14 +81,11 @@ func (bl *BaseLogger) Log(level LogLevel, format string, v ...interface{}) {
bl.mu.RLock()
defer bl.mu.RUnlock()
// Get caller info (skip 2 frames: this function and the calling Log function)
_, file, line, _ := runtime.Caller(2)
file = filepath.Base(file)
// Format message
msg := fmt.Sprintf(format, v...)
// Format final log line
logLine := fmt.Sprintf("[%s] [%s] [%s:%d] %s",
time.Now().Format(timeFormat),
string(level),
@@ -110,7 +97,6 @@ func (bl *BaseLogger) Log(level LogLevel, format string, v ...interface{}) {
bl.logger.Println(logLine)
}
// LogWithCaller writes a log entry with custom caller depth
func (bl *BaseLogger) LogWithCaller(level LogLevel, callerDepth int, format string, v ...interface{}) {
if bl == nil || !bl.initialized {
return
@@ -119,14 +105,11 @@ func (bl *BaseLogger) LogWithCaller(level LogLevel, callerDepth int, format stri
bl.mu.RLock()
defer bl.mu.RUnlock()
// Get caller info with custom depth
_, file, line, _ := runtime.Caller(callerDepth)
file = filepath.Base(file)
// Format message
msg := fmt.Sprintf(format, v...)
// Format final log line
logLine := fmt.Sprintf("[%s] [%s] [%s:%d] %s",
time.Now().Format(timeFormat),
string(level),
@@ -138,7 +121,6 @@ func (bl *BaseLogger) LogWithCaller(level LogLevel, callerDepth int, format stri
bl.logger.Println(logLine)
}
// IsInitialized returns whether the base logger is initialized
func (bl *BaseLogger) IsInitialized() bool {
if bl == nil {
return false
@@ -148,19 +130,16 @@ func (bl *BaseLogger) IsInitialized() bool {
return bl.initialized
}
// RecoverAndLog recovers from panics and logs them
func RecoverAndLog() {
baseLogger := GetBaseLogger("panic")
if baseLogger != nil && baseLogger.IsInitialized() {
if r := recover(); r != nil {
// Get stack trace
buf := make([]byte, 4096)
n := runtime.Stack(buf, false)
stackTrace := string(buf[:n])
baseLogger.LogWithCaller(LogLevelPanic, 2, "Recovered from panic: %v\nStack Trace:\n%s", r, stackTrace)
// Re-panic to maintain original behavior if needed
panic(r)
}
}

View File

@@ -6,12 +6,10 @@ import (
"sync"
)
// DebugLogger handles debug-level logging
type DebugLogger struct {
base *BaseLogger
}
// NewDebugLogger creates a new debug logger instance
func NewDebugLogger() *DebugLogger {
base, _ := InitializeBase("debug")
return &DebugLogger{
@@ -19,14 +17,12 @@ func NewDebugLogger() *DebugLogger {
}
}
// Log writes a debug-level log entry
func (dl *DebugLogger) Log(format string, v ...interface{}) {
if dl.base != nil {
dl.base.Log(LogLevelDebug, format, v...)
}
}
// LogWithContext writes a debug-level log entry with additional context
func (dl *DebugLogger) LogWithContext(context string, format string, v ...interface{}) {
if dl.base != nil {
contextualFormat := fmt.Sprintf("[%s] %s", context, format)
@@ -34,7 +30,6 @@ func (dl *DebugLogger) LogWithContext(context string, format string, v ...interf
}
}
// LogFunction logs function entry and exit for debugging
func (dl *DebugLogger) LogFunction(functionName string, args ...interface{}) {
if dl.base != nil {
if len(args) > 0 {
@@ -45,21 +40,18 @@ func (dl *DebugLogger) LogFunction(functionName string, args ...interface{}) {
}
}
// LogVariable logs variable values for debugging
func (dl *DebugLogger) LogVariable(varName string, value interface{}) {
if dl.base != nil {
dl.base.Log(LogLevelDebug, "VARIABLE [%s]: %+v", varName, value)
}
}
// LogState logs application state information
func (dl *DebugLogger) LogState(component string, state interface{}) {
if dl.base != nil {
dl.base.Log(LogLevelDebug, "STATE [%s]: %+v", component, state)
}
}
// LogSQL logs SQL queries for debugging
func (dl *DebugLogger) LogSQL(query string, args ...interface{}) {
if dl.base != nil {
if len(args) > 0 {
@@ -70,7 +62,6 @@ func (dl *DebugLogger) LogSQL(query string, args ...interface{}) {
}
}
// LogMemory logs memory usage information
func (dl *DebugLogger) LogMemory() {
if dl.base != nil {
var m runtime.MemStats
@@ -80,32 +71,27 @@ func (dl *DebugLogger) LogMemory() {
}
}
// LogGoroutines logs current number of goroutines
func (dl *DebugLogger) LogGoroutines() {
if dl.base != nil {
dl.base.Log(LogLevelDebug, "GOROUTINES: %d active", runtime.NumGoroutine())
}
}
// LogTiming logs timing information for performance debugging
func (dl *DebugLogger) LogTiming(operation string, duration interface{}) {
if dl.base != nil {
dl.base.Log(LogLevelDebug, "TIMING [%s]: %v", operation, duration)
}
}
// Helper function to convert bytes to kilobytes
func bToKb(b uint64) uint64 {
return b / 1024
}
// Global debug logger instance
var (
debugLogger *DebugLogger
debugOnce sync.Once
)
// GetDebugLogger returns the global debug logger instance
func GetDebugLogger() *DebugLogger {
debugOnce.Do(func() {
debugLogger = NewDebugLogger()
@@ -113,47 +99,38 @@ func GetDebugLogger() *DebugLogger {
return debugLogger
}
// Debug logs a debug-level message using the global debug logger
func Debug(format string, v ...interface{}) {
GetDebugLogger().Log(format, v...)
}
// DebugWithContext logs a debug-level message with context using the global debug logger
func DebugWithContext(context string, format string, v ...interface{}) {
GetDebugLogger().LogWithContext(context, format, v...)
}
// DebugFunction logs function entry and exit using the global debug logger
func DebugFunction(functionName string, args ...interface{}) {
GetDebugLogger().LogFunction(functionName, args...)
}
// DebugVariable logs variable values using the global debug logger
func DebugVariable(varName string, value interface{}) {
GetDebugLogger().LogVariable(varName, value)
}
// DebugState logs application state information using the global debug logger
func DebugState(component string, state interface{}) {
GetDebugLogger().LogState(component, state)
}
// DebugSQL logs SQL queries using the global debug logger
func DebugSQL(query string, args ...interface{}) {
GetDebugLogger().LogSQL(query, args...)
}
// DebugMemory logs memory usage information using the global debug logger
func DebugMemory() {
GetDebugLogger().LogMemory()
}
// DebugGoroutines logs current number of goroutines using the global debug logger
func DebugGoroutines() {
GetDebugLogger().LogGoroutines()
}
// DebugTiming logs timing information using the global debug logger
func DebugTiming(operation string, duration interface{}) {
GetDebugLogger().LogTiming(operation, duration)
}

View File

@@ -6,12 +6,10 @@ import (
"sync"
)
// ErrorLogger handles error-level logging
type ErrorLogger struct {
base *BaseLogger
}
// NewErrorLogger creates a new error logger instance
func NewErrorLogger() *ErrorLogger {
base, _ := InitializeBase("error")
return &ErrorLogger{
@@ -19,14 +17,12 @@ func NewErrorLogger() *ErrorLogger {
}
}
// Log writes an error-level log entry
func (el *ErrorLogger) Log(format string, v ...interface{}) {
if el.base != nil {
el.base.Log(LogLevelError, format, v...)
}
}
// LogWithContext writes an error-level log entry with additional context
func (el *ErrorLogger) LogWithContext(context string, format string, v ...interface{}) {
if el.base != nil {
contextualFormat := fmt.Sprintf("[%s] %s", context, format)
@@ -34,7 +30,6 @@ func (el *ErrorLogger) LogWithContext(context string, format string, v ...interf
}
}
// LogError logs an error object with optional message
func (el *ErrorLogger) LogError(err error, message ...string) {
if el.base != nil && err != nil {
if len(message) > 0 {
@@ -45,7 +40,6 @@ func (el *ErrorLogger) LogError(err error, message ...string) {
}
}
// LogWithStackTrace logs an error with stack trace
func (el *ErrorLogger) LogWithStackTrace(format string, v ...interface{}) {
if el.base != nil {
// Get stack trace
@@ -58,7 +52,6 @@ func (el *ErrorLogger) LogWithStackTrace(format string, v ...interface{}) {
}
}
// LogFatal logs a fatal error and exits the program
func (el *ErrorLogger) LogFatal(format string, v ...interface{}) {
if el.base != nil {
el.base.Log(LogLevelError, "[FATAL] "+format, v...)
@@ -66,13 +59,11 @@ func (el *ErrorLogger) LogFatal(format string, v ...interface{}) {
}
}
// Global error logger instance
var (
errorLogger *ErrorLogger
errorOnce sync.Once
)
// GetErrorLogger returns the global error logger instance
func GetErrorLogger() *ErrorLogger {
errorOnce.Do(func() {
errorLogger = NewErrorLogger()
@@ -80,27 +71,22 @@ func GetErrorLogger() *ErrorLogger {
return errorLogger
}
// Error logs an error-level message using the global error logger
func Error(format string, v ...interface{}) {
GetErrorLogger().Log(format, v...)
}
// ErrorWithContext logs an error-level message with context using the global error logger
func ErrorWithContext(context string, format string, v ...interface{}) {
GetErrorLogger().LogWithContext(context, format, v...)
}
// LogError logs an error object using the global error logger
func LogError(err error, message ...string) {
GetErrorLogger().LogError(err, message...)
}
// ErrorWithStackTrace logs an error with stack trace using the global error logger
func ErrorWithStackTrace(format string, v ...interface{}) {
GetErrorLogger().LogWithStackTrace(format, v...)
}
// Fatal logs a fatal error and exits the program using the global error logger
func Fatal(format string, v ...interface{}) {
GetErrorLogger().LogFatal(format, v...)
}

View File

@@ -5,12 +5,10 @@ import (
"sync"
)
// InfoLogger handles info-level logging
type InfoLogger struct {
base *BaseLogger
}
// NewInfoLogger creates a new info logger instance
func NewInfoLogger() *InfoLogger {
base, _ := InitializeBase("info")
return &InfoLogger{
@@ -18,14 +16,12 @@ func NewInfoLogger() *InfoLogger {
}
}
// Log writes an info-level log entry
func (il *InfoLogger) Log(format string, v ...interface{}) {
if il.base != nil {
il.base.Log(LogLevelInfo, format, v...)
}
}
// LogWithContext writes an info-level log entry with additional context
func (il *InfoLogger) LogWithContext(context string, format string, v ...interface{}) {
if il.base != nil {
contextualFormat := fmt.Sprintf("[%s] %s", context, format)
@@ -33,55 +29,47 @@ func (il *InfoLogger) LogWithContext(context string, format string, v ...interfa
}
}
// LogStartup logs application startup information
func (il *InfoLogger) LogStartup(component string, message string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "STARTUP [%s]: %s", component, message)
}
}
// LogShutdown logs application shutdown information
func (il *InfoLogger) LogShutdown(component string, message string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "SHUTDOWN [%s]: %s", component, message)
}
}
// LogOperation logs general operation information
func (il *InfoLogger) LogOperation(operation string, details string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "OPERATION [%s]: %s", operation, details)
}
}
// LogStatus logs status changes or updates
func (il *InfoLogger) LogStatus(component string, status string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "STATUS [%s]: %s", component, status)
}
}
// LogRequest logs incoming requests
func (il *InfoLogger) LogRequest(method string, path string, userAgent string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "REQUEST [%s %s] User-Agent: %s", method, path, userAgent)
}
}
// LogResponse logs outgoing responses
func (il *InfoLogger) LogResponse(method string, path string, statusCode int, duration string) {
if il.base != nil {
il.base.Log(LogLevelInfo, "RESPONSE [%s %s] Status: %d, Duration: %s", method, path, statusCode, duration)
}
}
// Global info logger instance
var (
infoLogger *InfoLogger
infoOnce sync.Once
)
// GetInfoLogger returns the global info logger instance
func GetInfoLogger() *InfoLogger {
infoOnce.Do(func() {
infoLogger = NewInfoLogger()
@@ -89,42 +77,34 @@ func GetInfoLogger() *InfoLogger {
return infoLogger
}
// Info logs an info-level message using the global info logger
func Info(format string, v ...interface{}) {
GetInfoLogger().Log(format, v...)
}
// InfoWithContext logs an info-level message with context using the global info logger
func InfoWithContext(context string, format string, v ...interface{}) {
GetInfoLogger().LogWithContext(context, format, v...)
}
// InfoStartup logs application startup information using the global info logger
func InfoStartup(component string, message string) {
GetInfoLogger().LogStartup(component, message)
}
// InfoShutdown logs application shutdown information using the global info logger
func InfoShutdown(component string, message string) {
GetInfoLogger().LogShutdown(component, message)
}
// InfoOperation logs general operation information using the global info logger
func InfoOperation(operation string, details string) {
GetInfoLogger().LogOperation(operation, details)
}
// InfoStatus logs status changes or updates using the global info logger
func InfoStatus(component string, status string) {
GetInfoLogger().LogStatus(component, status)
}
// InfoRequest logs incoming requests using the global info logger
func InfoRequest(method string, path string, userAgent string) {
GetInfoLogger().LogRequest(method, path, userAgent)
}
// InfoResponse logs outgoing responses using the global info logger
func InfoResponse(method string, path string, statusCode int, duration string) {
GetInfoLogger().LogResponse(method, path, statusCode, duration)
}

View File

@@ -6,12 +6,10 @@ import (
)
var (
// Legacy logger for backward compatibility
logger *Logger
once sync.Once
)
// Logger maintains backward compatibility with existing code
type Logger struct {
base *BaseLogger
errorLogger *ErrorLogger
@@ -20,8 +18,6 @@ type Logger struct {
debugLogger *DebugLogger
}
// Initialize creates or gets the singleton logger instance
// This maintains backward compatibility with existing code
func Initialize() (*Logger, error) {
var err error
once.Do(func() {
@@ -31,13 +27,11 @@ func Initialize() (*Logger, error) {
}
func newLogger() (*Logger, error) {
// Initialize the base logger
baseLogger, err := InitializeBase("log")
if err != nil {
return nil, err
}
// Create the legacy logger wrapper
logger := &Logger{
base: baseLogger,
errorLogger: GetErrorLogger(),
@@ -49,7 +43,6 @@ func newLogger() (*Logger, error) {
return logger, nil
}
// Close closes the logger
func (l *Logger) Close() error {
if l.base != nil {
return l.base.Close()
@@ -57,7 +50,6 @@ func (l *Logger) Close() error {
return nil
}
// Legacy methods for backward compatibility
func (l *Logger) log(level, format string, v ...interface{}) {
if l.base != nil {
l.base.LogWithCaller(LogLevel(level), 3, format, v...)
@@ -94,13 +86,10 @@ func (l *Logger) Panic(format string) {
}
}
// Global convenience functions for backward compatibility
// These are now implemented in individual logger files to avoid redeclaration
func LegacyInfo(format string, v ...interface{}) {
if logger != nil {
logger.Info(format, v...)
} else {
// Fallback to direct logger if legacy logger not initialized
GetInfoLogger().Log(format, v...)
}
}
@@ -109,7 +98,6 @@ func LegacyError(format string, v ...interface{}) {
if logger != nil {
logger.Error(format, v...)
} else {
// Fallback to direct logger if legacy logger not initialized
GetErrorLogger().Log(format, v...)
}
}
@@ -118,7 +106,6 @@ func LegacyWarn(format string, v ...interface{}) {
if logger != nil {
logger.Warn(format, v...)
} else {
// Fallback to direct logger if legacy logger not initialized
GetWarnLogger().Log(format, v...)
}
}
@@ -127,7 +114,6 @@ func LegacyDebug(format string, v ...interface{}) {
if logger != nil {
logger.Debug(format, v...)
} else {
// Fallback to direct logger if legacy logger not initialized
GetDebugLogger().Log(format, v...)
}
}
@@ -136,55 +122,42 @@ func Panic(format string) {
if logger != nil {
logger.Panic(format)
} else {
// Fallback to direct logger if legacy logger not initialized
GetErrorLogger().LogFatal(format)
}
}
// Enhanced logging convenience functions
// These provide direct access to specialized logging functions
// LogStartup logs application startup information
func LogStartup(component string, message string) {
GetInfoLogger().LogStartup(component, message)
}
// LogShutdown logs application shutdown information
func LogShutdown(component string, message string) {
GetInfoLogger().LogShutdown(component, message)
}
// LogOperation logs general operation information
func LogOperation(operation string, details string) {
GetInfoLogger().LogOperation(operation, details)
}
// LogRequest logs incoming HTTP requests
func LogRequest(method string, path string, userAgent string) {
GetInfoLogger().LogRequest(method, path, userAgent)
}
// LogResponse logs outgoing HTTP responses
func LogResponse(method string, path string, statusCode int, duration string) {
GetInfoLogger().LogResponse(method, path, statusCode, duration)
}
// LogSQL logs SQL queries for debugging
func LogSQL(query string, args ...interface{}) {
GetDebugLogger().LogSQL(query, args...)
}
// LogMemory logs memory usage information
func LogMemory() {
GetDebugLogger().LogMemory()
}
// LogTiming logs timing information for performance debugging
func LogTiming(operation string, duration interface{}) {
GetDebugLogger().LogTiming(operation, duration)
}
// GetLegacyLogger returns the legacy logger instance for backward compatibility
func GetLegacyLogger() *Logger {
if logger == nil {
logger, _ = Initialize()
@@ -192,21 +165,17 @@ func GetLegacyLogger() *Logger {
return logger
}
// InitializeLogging initializes all logging components
func InitializeLogging() error {
// Initialize legacy logger for backward compatibility
_, err := Initialize()
if err != nil {
return fmt.Errorf("failed to initialize legacy logger: %v", err)
}
// Pre-initialize all logger types to ensure separate log files
GetErrorLogger()
GetWarnLogger()
GetInfoLogger()
GetDebugLogger()
// Log successful initialization
Info("Logging system initialized successfully")
return nil

View File

@@ -5,12 +5,10 @@ import (
"sync"
)
// WarnLogger handles warn-level logging
type WarnLogger struct {
base *BaseLogger
}
// NewWarnLogger creates a new warn logger instance
func NewWarnLogger() *WarnLogger {
base, _ := InitializeBase("warn")
return &WarnLogger{
@@ -18,14 +16,12 @@ func NewWarnLogger() *WarnLogger {
}
}
// Log writes a warn-level log entry
func (wl *WarnLogger) Log(format string, v ...interface{}) {
if wl.base != nil {
wl.base.Log(LogLevelWarn, format, v...)
}
}
// LogWithContext writes a warn-level log entry with additional context
func (wl *WarnLogger) LogWithContext(context string, format string, v ...interface{}) {
if wl.base != nil {
contextualFormat := fmt.Sprintf("[%s] %s", context, format)
@@ -33,7 +29,6 @@ func (wl *WarnLogger) LogWithContext(context string, format string, v ...interfa
}
}
// LogDeprecation logs a deprecation warning
func (wl *WarnLogger) LogDeprecation(feature string, alternative string) {
if wl.base != nil {
if alternative != "" {
@@ -44,27 +39,23 @@ func (wl *WarnLogger) LogDeprecation(feature string, alternative string) {
}
}
// LogConfiguration logs configuration-related warnings
func (wl *WarnLogger) LogConfiguration(setting string, message string) {
if wl.base != nil {
wl.base.Log(LogLevelWarn, "CONFIG WARNING [%s]: %s", setting, message)
}
}
// LogPerformance logs performance-related warnings
func (wl *WarnLogger) LogPerformance(operation string, threshold string, actual string) {
if wl.base != nil {
wl.base.Log(LogLevelWarn, "PERFORMANCE WARNING [%s]: exceeded threshold %s, actual: %s", operation, threshold, actual)
}
}
// Global warn logger instance
var (
warnLogger *WarnLogger
warnOnce sync.Once
)
// GetWarnLogger returns the global warn logger instance
func GetWarnLogger() *WarnLogger {
warnOnce.Do(func() {
warnLogger = NewWarnLogger()
@@ -72,27 +63,22 @@ func GetWarnLogger() *WarnLogger {
return warnLogger
}
// Warn logs a warn-level message using the global warn logger
func Warn(format string, v ...interface{}) {
GetWarnLogger().Log(format, v...)
}
// WarnWithContext logs a warn-level message with context using the global warn logger
func WarnWithContext(context string, format string, v ...interface{}) {
GetWarnLogger().LogWithContext(context, format, v...)
}
// WarnDeprecation logs a deprecation warning using the global warn logger
func WarnDeprecation(feature string, alternative string) {
GetWarnLogger().LogDeprecation(feature, alternative)
}
// WarnConfiguration logs configuration-related warnings using the global warn logger
func WarnConfiguration(setting string, message string) {
GetWarnLogger().LogConfiguration(setting, message)
}
// WarnPerformance logs performance-related warnings using the global warn logger
func WarnPerformance(operation string, threshold string, actual string) {
GetWarnLogger().LogPerformance(operation, threshold, actual)
}