prevent active log from being overwritten when agent starts (#11386)
This commit is contained in:
parent
ecc7a288ec
commit
b463715a98
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
agent: Fixed an issue that could cause previous log lines to be overwritten
|
||||
```
|
|
@ -62,18 +62,23 @@ func (l *logFile) fileNamePattern() string {
|
|||
}
|
||||
|
||||
func (l *logFile) openNew() error {
|
||||
createTime := now()
|
||||
newfilePath := filepath.Join(l.logPath, l.fileName)
|
||||
// Try creating a file. We truncate the file because we are the only authority to write the logs
|
||||
filePointer, err := os.OpenFile(newfilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0640)
|
||||
|
||||
// Try creating or opening the active log file. Since the active log file
|
||||
// always has the same name, append log entries to prevent overwriting
|
||||
// previous log data.
|
||||
filePointer, err := os.OpenFile(newfilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0640)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stat, err := filePointer.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.FileInfo = filePointer
|
||||
// New file, new bytes tracker, new creation time :)
|
||||
l.LastCreated = createTime
|
||||
l.BytesWritten = 0
|
||||
l.BytesWritten = stat.Size()
|
||||
l.LastCreated = l.createTime(stat)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
//go:build darwin || freebsd || netbsd || openbsd
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (l *logFile) createTime(stat os.FileInfo) time.Time {
|
||||
stat_t := stat.Sys().(*syscall.Stat_t)
|
||||
createTime := stat_t.Ctimespec
|
||||
return time.Unix(createTime.Sec, createTime.Nsec)
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
//go:build dragonfly || linux || solaris
|
||||
// +build dragonfly linux solaris
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (l *logFile) createTime(stat os.FileInfo) time.Time {
|
||||
stat_t := stat.Sys().(*syscall.Stat_t)
|
||||
createTime := stat_t.Ctim
|
||||
// Sec and Nsec are int32 in 32-bit architectures.
|
||||
return time.Unix(int64(createTime.Sec), int64(createTime.Nsec)) //nolint:unconvert
|
||||
}
|
|
@ -50,13 +50,33 @@ func TestLogFile_openNew(t *testing.T) {
|
|||
require.NoError(err)
|
||||
defer os.Remove(tempDir)
|
||||
|
||||
logFile := logFile{fileName: testFileName, logPath: tempDir, duration: testDuration}
|
||||
filt := LevelFilter()
|
||||
filt.MinLevel = logutils.LogLevel("INFO")
|
||||
logFile := logFile{
|
||||
logFilter: filt,
|
||||
fileName: testFileName,
|
||||
logPath: tempDir,
|
||||
MaxBytes: testBytes,
|
||||
duration: 24 * time.Hour,
|
||||
}
|
||||
require.NoError(logFile.openNew())
|
||||
|
||||
_, err = ioutil.ReadFile(logFile.FileInfo.Name())
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal(logFile.FileInfo.Name(), filepath.Join(tempDir, testFileName))
|
||||
|
||||
// Check if create time and bytes written are kept when opening the active
|
||||
// log file again.
|
||||
bytesWritten, err := logFile.Write([]byte("test"))
|
||||
require.NoError(err)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
require.NoError(logFile.openNew())
|
||||
|
||||
timeDelta := time.Now().Sub(logFile.LastCreated)
|
||||
require.GreaterOrEqual(timeDelta, 2*time.Second)
|
||||
require.Equal(logFile.BytesWritten, int64(bytesWritten))
|
||||
}
|
||||
|
||||
func TestLogFile_byteRotation(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (l *logFile) createTime(stat os.FileInfo) time.Time {
|
||||
// Use `ModTime` as an approximation if the exact create time is not
|
||||
// available.
|
||||
// On Windows, the file create time is not updated after the active log
|
||||
// rotates, so use `ModTime` as an approximation as well.
|
||||
return stat.ModTime()
|
||||
}
|
Loading…
Reference in New Issue