2021-09-16 10:16:07 +03:00
//go:build !windows
2017-08-11 13:04:58 +03:00
// +build !windows
package integration
import (
"bufio"
"net/http"
"os"
2019-11-14 18:40:05 +03:00
"strings"
2017-08-11 13:04:58 +03:00
"syscall"
2024-01-09 19:00:07 +03:00
"testing"
2017-08-11 13:04:58 +03:00
"time"
2022-11-21 20:36:05 +03:00
"github.com/rs/zerolog/log"
2024-01-09 19:00:07 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/integration/try"
2017-08-11 13:04:58 +03:00
)
2022-11-21 20:36:05 +03:00
const traefikTestAccessLogFileRotated = traefikTestAccessLogFile + ".rotated"
2021-11-25 13:10:06 +03:00
2020-05-11 13:06:07 +03:00
// Log rotation integration test suite.
2017-08-11 13:04:58 +03:00
type LogRotationSuite struct { BaseSuite }
2024-09-13 12:40:04 +03:00
func TestLogRotationSuite ( t * testing . T ) {
2024-01-09 19:00:07 +03:00
suite . Run ( t , new ( LogRotationSuite ) )
2021-11-25 13:10:06 +03:00
}
2018-01-11 12:04:03 +03:00
2024-01-09 19:00:07 +03:00
func ( s * LogRotationSuite ) SetupSuite ( ) {
s . BaseSuite . SetupSuite ( )
os . Remove ( traefikTestAccessLogFile )
os . Remove ( traefikTestLogFile )
os . Remove ( traefikTestAccessLogFileRotated )
s . createComposeProject ( "access_log" )
s . composeUp ( )
}
func ( s * LogRotationSuite ) TearDownSuite ( ) {
s . BaseSuite . TearDownSuite ( )
2021-11-25 13:10:06 +03:00
generatedFiles := [ ] string {
traefikTestLogFile ,
traefikTestAccessLogFile ,
traefikTestAccessLogFileRotated ,
}
for _ , filename := range generatedFiles {
if err := os . Remove ( filename ) ; err != nil {
2022-11-21 20:36:05 +03:00
log . Warn ( ) . Err ( err ) . Send ( )
2021-11-25 13:10:06 +03:00
}
}
2018-01-11 12:04:03 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * LogRotationSuite ) TestAccessLogRotation ( ) {
2017-08-11 13:04:58 +03:00
// Start Traefik
2024-01-30 18:28:05 +03:00
cmd , _ := s . cmdTraefik ( withConfigFile ( "fixtures/access_log/access_log_base.toml" ) )
2024-01-09 19:00:07 +03:00
defer s . displayTraefikLogFile ( traefikTestLogFile )
2018-02-05 11:48:03 +03:00
2017-08-11 13:04:58 +03:00
// Verify Traefik started ok
2024-01-09 19:00:07 +03:00
s . verifyEmptyErrorLog ( "traefik.log" )
2017-08-11 13:04:58 +03:00
2024-01-09 19:00:07 +03:00
s . waitForTraefik ( "server1" )
2017-08-11 13:04:58 +03:00
// Make some requests
2018-01-11 12:04:03 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2018-01-11 12:04:03 +03:00
req . Host = "frontend1.docker.local"
err = try . Request ( req , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) , try . HasBody ( ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
// Rename access log
2021-11-25 13:10:06 +03:00
err = os . Rename ( traefikTestAccessLogFile , traefikTestAccessLogFileRotated )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
// in the midst of the requests, issue SIGUSR1 signal to server process
err = cmd . Process . Signal ( syscall . SIGUSR1 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
// continue issuing requests
2018-01-11 12:04:03 +03:00
err = try . Request ( req , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) , try . HasBody ( ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2018-01-11 12:04:03 +03:00
err = try . Request ( req , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) , try . HasBody ( ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
// Verify access.log.rotated output as expected
2024-01-09 19:00:07 +03:00
s . logAccessLogFile ( traefikTestAccessLogFileRotated )
lineCount := s . verifyLogLines ( traefikTestAccessLogFileRotated , 0 , true )
assert . GreaterOrEqual ( s . T ( ) , lineCount , 1 )
2017-08-11 13:04:58 +03:00
2017-10-06 10:20:13 +03:00
// make sure that the access log file is at least created before we do assertions on it
err = try . Do ( 1 * time . Second , func ( ) error {
_ , err := os . Stat ( traefikTestAccessLogFile )
return err
} )
2024-01-09 19:00:07 +03:00
assert . NoError ( s . T ( ) , err , "access log file was not created in time" )
2017-10-06 10:20:13 +03:00
2017-08-11 13:04:58 +03:00
// Verify access.log output as expected
2024-01-09 19:00:07 +03:00
s . logAccessLogFile ( traefikTestAccessLogFile )
lineCount = s . verifyLogLines ( traefikTestAccessLogFile , lineCount , true )
assert . Equal ( s . T ( ) , 3 , lineCount )
2017-08-11 13:04:58 +03:00
2024-01-09 19:00:07 +03:00
s . verifyEmptyErrorLog ( traefikTestLogFile )
2017-08-11 13:04:58 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * LogRotationSuite ) logAccessLogFile ( fileName string ) {
2021-03-04 22:08:03 +03:00
output , err := os . ReadFile ( fileName )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2024-01-10 12:47:44 +03:00
log . Info ( ) . Msgf ( "Contents of file %s\n%s" , fileName , string ( output ) )
2017-10-06 10:20:13 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * LogRotationSuite ) verifyEmptyErrorLog ( name string ) {
2017-08-11 13:04:58 +03:00
err := try . Do ( 5 * time . Second , func ( ) error {
2021-03-04 22:08:03 +03:00
traefikLog , e2 := os . ReadFile ( name )
2017-08-11 13:04:58 +03:00
if e2 != nil {
return e2
}
2024-01-09 19:00:07 +03:00
assert . Empty ( s . T ( ) , string ( traefikLog ) )
2017-08-11 13:04:58 +03:00
return nil
} )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * LogRotationSuite ) verifyLogLines ( fileName string , countInit int , accessLog bool ) int {
2017-08-11 13:04:58 +03:00
rotated , err := os . Open ( fileName )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-08-11 13:04:58 +03:00
rotatedLog := bufio . NewScanner ( rotated )
count := countInit
for rotatedLog . Scan ( ) {
line := rotatedLog . Text ( )
if accessLog {
if len ( line ) > 0 {
2019-11-14 18:40:05 +03:00
if ! strings . Contains ( line , "/api/rawdata" ) {
2024-01-09 19:00:07 +03:00
s . CheckAccessLogFormat ( line , count )
2019-11-14 18:40:05 +03:00
count ++
}
2017-08-11 13:04:58 +03:00
}
2019-11-14 18:40:05 +03:00
} else {
count ++
2017-08-11 13:04:58 +03:00
}
}
return count
}