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