package logging import ( "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" ) // BenchmarkLogging_Optimized benchmark le logger optimisé func BenchmarkLogging_Optimized(b *testing.B) { logger, err := NewOptimizedLogger("production", "INFO") require.NoError(b, err) defer logger.Sync() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { logger.Info("test message", zap.String("key", "value"), zap.Int("count", 42), ) } }) } // BenchmarkLogging_Standard benchmark le logger standard (pour comparaison) func BenchmarkLogging_Standard(b *testing.B) { logger, err := NewLogger("production", "INFO") require.NoError(b, err) defer logger.Sync() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { logger.Info("test message", zap.String("key", "value"), zap.Int("count", 42), ) } }) } // TestOptimizedLogger_Performance teste que le logger optimisé atteint < 1ms par log func TestOptimizedLogger_Performance(t *testing.T) { logger, err := NewOptimizedLogger("production", "INFO") require.NoError(t, err) defer logger.Sync() iterations := 1000 start := time.Now() for i := 0; i < iterations; i++ { logger.Info("test message", zap.String("key", "value"), zap.Int("iteration", i), ) } // Sync pour s'assurer que tous les logs sont écrits // Note: Sync() peut retourner une erreur sur stdout/stderr sur certains systèmes, c'est OK _ = logger.Sync() duration := time.Since(start) avgDuration := duration / time.Duration(iterations) // Vérifier que la moyenne est < 1ms par log assert.Less(t, avgDuration, 1*time.Millisecond, "Average log time should be < 1ms, got %v", avgDuration) } // TestOptimizedLogger_HighLoad teste la performance avec 10K logs/seconde func TestOptimizedLogger_HighLoad(t *testing.T) { logger, err := NewOptimizedLogger("production", "INFO") require.NoError(t, err) defer logger.Sync() duration := 1 * time.Second iteration := 0 done := make(chan struct{}) // Goroutine qui envoie des logs rapidement go func() { endTime := time.Now().Add(duration) for time.Now().Before(endTime) { logger.Info("high load test", zap.String("test", "high_load"), zap.Int("iteration", iteration), ) iteration++ } close(done) }() // Attendre la fin <-done // Sync pour s'assurer que tous les logs sont écrits // Note: Sync() peut retourner une erreur sur stdout/stderr sur certains systèmes, c'est OK _ = logger.Sync() // Le système devrait pouvoir gérer cette charge sans bloquer // Avec sampling activé, certains logs peuvent être filtrés, c'est normal // On vérifie juste qu'il n'y a pas eu de panique et que le système répond } // TestOptimizedLogger_Sampling teste que le sampling fonctionne correctement func TestOptimizedLogger_Sampling(t *testing.T) { logger, err := NewOptimizedLogger("production", "INFO") require.NoError(t, err) defer logger.Sync() // Envoyer beaucoup de logs rapidement // Avec sampling Initial:100, Thereafter:100, on devrait voir une réduction après 100 logs for i := 0; i < 500; i++ { logger.Info("sampling test", zap.Int("iteration", i), ) } // Sync pour s'assurer que tous les logs sont écrits // Note: Sync() peut retourner une erreur sur stdout/stderr sur certains systèmes, c'est OK _ = logger.Sync() // Le sampling devrait être actif sans erreur // On vérifie juste que ça ne panique pas et que le logger fonctionne } // TestOptimizedLogger_Concurrent teste que le logger peut gérer des logs concurrents func TestOptimizedLogger_Concurrent(t *testing.T) { logger, err := NewOptimizedLogger("production", "INFO") require.NoError(t, err) defer logger.Sync() goroutines := 10 logsPerGoroutine := 100 done := make(chan struct{}, goroutines) for i := 0; i < goroutines; i++ { go func(id int) { for j := 0; j < logsPerGoroutine; j++ { logger.Info("concurrent test", zap.Int("goroutine", id), zap.Int("iteration", j), ) } done <- struct{}{} }(i) } // Attendre que toutes les goroutines terminent for i := 0; i < goroutines; i++ { <-done } // Sync pour s'assurer que tous les logs sont écrits // Note: Sync() peut retourner une erreur sur stdout/stderr sur certains systèmes, c'est OK _ = logger.Sync() // Le logger devrait gérer les logs concurrents sans problème // On vérifie juste qu'il n'y a pas eu de panique } // TestOptimizedLogger_WithRotation teste le logger optimisé avec rotation func TestOptimizedLogger_WithRotation(t *testing.T) { tmpDir := t.TempDir() logFile := tmpDir + "/optimized.log" logger, err := NewOptimizedLoggerWithRotation("production", logFile, "INFO") require.NoError(t, err) defer logger.Sync() // Envoyer des logs for i := 0; i < 100; i++ { logger.Info("optimized rotation test", zap.Int("iteration", i), ) } // Sync pour s'assurer que tous les logs sont écrits err = logger.Sync() require.NoError(t, err) // Vérifier que le fichier existe et contient des données // (le buffering async peut prendre un peu de temps) time.Sleep(200 * time.Millisecond) // Le logger devrait fonctionner avec rotation assert.NoError(t, err) } // BenchmarkLogging_OptimizedWithRotation benchmark le logger optimisé avec rotation func BenchmarkLogging_OptimizedWithRotation(b *testing.B) { tmpDir := b.TempDir() logFile := tmpDir + "/bench.log" logger, err := NewOptimizedLoggerWithRotation("production", logFile, "INFO") require.NoError(b, err) defer logger.Sync() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { logger.Info("benchmark message", zap.String("key", "value"), zap.Int("count", 42), ) } }) }