package logger import ( "context" "time" ) // contextKey is a custom type for context keys to avoid collisions type contextKey string const ( loggerKey contextKey = "logger" requestIDKey contextKey = "request_id" correlationIDKey contextKey = "correlation_id" serviceNameKey contextKey = "service_name" ) // ContextWithLogger creates a new context with the logger func ContextWithLogger(ctx context.Context, logger *Logger) context.Context { return context.WithValue(ctx, loggerKey, logger) } // LoggerFromContext retrieves the logger from context func LoggerFromContext(ctx context.Context) *Logger { if logger, ok := ctx.Value(loggerKey).(*Logger); ok { return logger } return globalLogger } // ContextWithRequestID creates a new context with the request ID func ContextWithRequestID(ctx context.Context, requestID string) context.Context { return context.WithValue(ctx, requestIDKey, requestID) } // RequestIDFromContext retrieves the request ID from context func RequestIDFromContext(ctx context.Context) string { if requestID, ok := ctx.Value(requestIDKey).(string); ok { return requestID } return "" } // ContextWithCorrelationID creates a new context with the correlation ID func ContextWithCorrelationID(ctx context.Context, correlationID string) context.Context { return context.WithValue(ctx, correlationIDKey, correlationID) } // CorrelationIDFromContext retrieves the correlation ID from context func CorrelationIDFromContext(ctx context.Context) string { if correlationID, ok := ctx.Value(correlationIDKey).(string); ok { return correlationID } return "" } // ContextWithServiceName creates a new context with the service name func ContextWithServiceName(ctx context.Context, serviceName string) context.Context { return context.WithValue(ctx, serviceNameKey, serviceName) } // ServiceNameFromContext retrieves the service name from context func ServiceNameFromContext(ctx context.Context) string { if serviceName, ok := ctx.Value(serviceNameKey).(string); ok { return serviceName } return "" } // WithContext returns a new logger with context values func (l *Logger) WithContext(ctx context.Context) *Logger { logger := l if requestID := RequestIDFromContext(ctx); requestID != "" { logger = logger.WithRequestID(requestID) } if correlationID := CorrelationIDFromContext(ctx); correlationID != "" { logger = logger.WithCorrelationID(correlationID) } if serviceName := ServiceNameFromContext(ctx); serviceName != "" { logger = logger.WithService(serviceName) } return logger } // DebugCtx logs a debug message with context func DebugCtx(ctx context.Context, msg string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).Debug(msg, fields...) } // DebugfCtx logs a formatted debug message with context func DebugfCtx(ctx context.Context, format string, args ...interface{}) { LoggerFromContext(ctx).WithContext(ctx).Debugf(format, args...) } // InfoCtx logs an info message with context func InfoCtx(ctx context.Context, msg string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).Info(msg, fields...) } // InfofCtx logs a formatted info message with context func InfofCtx(ctx context.Context, format string, args ...interface{}) { LoggerFromContext(ctx).WithContext(ctx).Infof(format, args...) } // WarnCtx logs a warning message with context func WarnCtx(ctx context.Context, msg string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).Warn(msg, fields...) } // WarnfCtx logs a formatted warning message with context func WarnfCtx(ctx context.Context, format string, args ...interface{}) { LoggerFromContext(ctx).WithContext(ctx).Warnf(format, args...) } // ErrorCtx logs an error message with context func ErrorCtx(ctx context.Context, msg string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).Error(msg, fields...) } // ErrorfCtx logs a formatted error message with context func ErrorfCtx(ctx context.Context, format string, args ...interface{}) { LoggerFromContext(ctx).WithContext(ctx).Errorf(format, args...) } // FatalCtx logs a fatal message with context and exits the program func FatalCtx(ctx context.Context, msg string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).Fatal(msg, fields...) } // FatalfCtx logs a formatted fatal message with context and exits the program func FatalfCtx(ctx context.Context, format string, args ...interface{}) { LoggerFromContext(ctx).WithContext(ctx).Fatalf(format, args...) } // LogDurationCtx logs the duration of an operation with context func LogDurationCtx(ctx context.Context, start time.Time, operation string, fields ...map[string]interface{}) { LoggerFromContext(ctx).WithContext(ctx).LogDuration(start, operation, fields...) }