From a5ad3664038a3dd225b5c14b3adc181fb4dd61a6 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 30 Aug 2023 18:33:22 +0530 Subject: [PATCH 1/9] fixes file name for consul --- logging/logfile.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/logging/logfile.go b/logging/logfile.go index bc7b38d91c26..7f8e9db6d82f 100644 --- a/logging/logfile.go +++ b/logging/logfile.go @@ -60,10 +60,8 @@ func (l *LogFile) fileNamePattern() string { } func (l *LogFile) openNew() error { - fileNamePattern := l.fileNamePattern() - createTime := now() - newfileName := fmt.Sprintf(fileNamePattern, strconv.FormatInt(createTime.UnixNano(), 10)) + newfileName := l.fileName newfilePath := filepath.Join(l.logPath, newfileName) // Try creating a file. We truncate the file because we are the only authority to write the logs @@ -79,12 +77,28 @@ func (l *LogFile) openNew() error { return nil } +func (l *LogFile) renameCurrentFile() error { + fileNamePattern := l.fileNamePattern() + + createTime := now() + // Current file is consul.log always + currentFilePath := filepath.Join(l.logPath, l.fileName) + + oldFileName := fmt.Sprintf(fileNamePattern, strconv.FormatInt(createTime.UnixNano(), 10)) + oldFilePath := filepath.Join(l.logPath, oldFileName) + + return os.Rename(currentFilePath, oldFilePath) +} + func (l *LogFile) rotate() error { // Get the time from the last point of contact timeElapsed := time.Since(l.LastCreated) // Rotate if we hit the byte file limit or the time limit if (l.BytesWritten >= int64(l.MaxBytes) && (l.MaxBytes > 0)) || timeElapsed >= l.duration { l.FileInfo.Close() + if err := l.renameCurrentFile(); err != nil { + return err + } if err := l.pruneFiles(); err != nil { return err } From 24e7b9b9602b83dd67096a61b9305a37c6d77801 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 30 Aug 2023 18:46:10 +0530 Subject: [PATCH 2/9] added log file --- .changelog/18617.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/18617.txt diff --git a/.changelog/18617.txt b/.changelog/18617.txt new file mode 100644 index 000000000000..1f840d836dee --- /dev/null +++ b/.changelog/18617.txt @@ -0,0 +1,4 @@ +```release-note:improvement +log: Currently consul logs files like this consul-{timestamp}.log. This change makes sure that there is always +consul.log file with the latest logs in it. +``` \ No newline at end of file From e72ce965cc1ababc0edb137e465a833ffe65e2bf Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Thu, 31 Aug 2023 21:30:36 +0530 Subject: [PATCH 3/9] added tests for rename method --- logging/logfile_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/logging/logfile_test.go b/logging/logfile_test.go index ae9d8fb1b0cd..26c23439f20b 100644 --- a/logging/logfile_test.go +++ b/logging/logfile_test.go @@ -51,6 +51,22 @@ func TestLogFile_openNew(t *testing.T) { require.Contains(t, string(content), msg) } +func TestLogFile_renameCurrentFile(t *testing.T) { + logFile := LogFile{ + fileName: "consul.log", + logPath: testutil.TempDir(t, ""), + duration: defaultRotateDuration, + } + err := logFile.openNew() + require.NoError(t, err) + + err = logFile.renameCurrentFile() + require.NoError(t, err) + + _, err = os.ReadFile(logFile.FileInfo.Name()) + require.Contains(t, err.Error(), "no such file or directory") +} + func TestLogFile_Rotation_MaxBytes(t *testing.T) { tempDir := testutil.TempDir(t, "LogWriterBytes") logFile := LogFile{ From 898bd1e01c7784dc5170ab4ceaf49a77b3303b66 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Thu, 31 Aug 2023 23:05:13 +0530 Subject: [PATCH 4/9] append instead of trunc --- logging/logfile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/logfile.go b/logging/logfile.go index 7f8e9db6d82f..88ae350d3268 100644 --- a/logging/logfile.go +++ b/logging/logfile.go @@ -65,7 +65,7 @@ func (l *LogFile) openNew() error { newfilePath := filepath.Join(l.logPath, newfileName) // 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) + filePointer, err := os.OpenFile(newfilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0640) if err != nil { return err } From 72685db1d191525e1e013ef366599219d1ea309f Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Thu, 31 Aug 2023 23:21:57 +0530 Subject: [PATCH 5/9] fix file truncate issue --- logging/logfile.go | 11 ++++++++--- logging/logfile_bsd.go | 16 ++++++++++++++++ logging/logfile_linux.go | 17 +++++++++++++++++ logging/logfile_windows.go | 14 ++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 logging/logfile_bsd.go create mode 100644 logging/logfile_linux.go create mode 100644 logging/logfile_windows.go diff --git a/logging/logfile.go b/logging/logfile.go index 88ae350d3268..a4d48da2d631 100644 --- a/logging/logfile.go +++ b/logging/logfile.go @@ -60,19 +60,24 @@ func (l *LogFile) fileNamePattern() string { } func (l *LogFile) openNew() error { - createTime := now() newfileName := l.fileName newfilePath := filepath.Join(l.logPath, newfileName) - // Try creating a file. We truncate the file because we are the only authority to write the logs + // 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 } l.FileInfo = filePointer + stat, err := filePointer.Stat() + if err != nil { + return err + } // New file, new bytes tracker, new creation time :) - l.LastCreated = createTime + l.LastCreated = l.createTime(stat) l.BytesWritten = 0 return nil } diff --git a/logging/logfile_bsd.go b/logging/logfile_bsd.go new file mode 100644 index 000000000000..593da2bcc8bc --- /dev/null +++ b/logging/logfile_bsd.go @@ -0,0 +1,16 @@ +//go:build darwin || freebsd || netbsd || openbsd +// +build darwin freebsd netbsd openbsd + +package logging + +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) +} diff --git a/logging/logfile_linux.go b/logging/logfile_linux.go new file mode 100644 index 000000000000..712d434b000d --- /dev/null +++ b/logging/logfile_linux.go @@ -0,0 +1,17 @@ +//go:build dragonfly || linux || solaris +// +build dragonfly linux solaris + +package logging + +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 +} diff --git a/logging/logfile_windows.go b/logging/logfile_windows.go new file mode 100644 index 000000000000..688a8351cdbe --- /dev/null +++ b/logging/logfile_windows.go @@ -0,0 +1,14 @@ +package logging + +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() +} From c52fb47f12b90bfd0582282ddca378379e081bcb Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Thu, 31 Aug 2023 23:27:27 +0530 Subject: [PATCH 6/9] added changelog --- .changelog/18631.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/18631.txt diff --git a/.changelog/18631.txt b/.changelog/18631.txt new file mode 100644 index 000000000000..564e1765bacb --- /dev/null +++ b/.changelog/18631.txt @@ -0,0 +1,3 @@ +```release-note:bug +agent: Fixed an issue that could cause previous log lines to be overwritten +``` \ No newline at end of file From 43d1e7f8688daac96b407c9d52f062d322cd4a73 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Thu, 31 Aug 2023 23:49:07 +0530 Subject: [PATCH 7/9] fix for build destros ci --- logging/logfile_bsd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/logfile_bsd.go b/logging/logfile_bsd.go index 593da2bcc8bc..d81d065be1ce 100644 --- a/logging/logfile_bsd.go +++ b/logging/logfile_bsd.go @@ -12,5 +12,5 @@ import ( 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) + return time.Unix(int64(createTime.Sec), int64(createTime.Nsec)) } From 1ca89431d739f9c42465b1250ae3d41ae8888739 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Fri, 1 Sep 2023 09:55:13 +0530 Subject: [PATCH 8/9] removed changelog --- .changelog/18631.txt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .changelog/18631.txt diff --git a/.changelog/18631.txt b/.changelog/18631.txt deleted file mode 100644 index 564e1765bacb..000000000000 --- a/.changelog/18631.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -agent: Fixed an issue that could cause previous log lines to be overwritten -``` \ No newline at end of file From 2e3332a5e4c48bbfd97a48474bfa717cf7ee55d6 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Fri, 1 Sep 2023 11:12:43 +0530 Subject: [PATCH 9/9] solaris --- logging/logfile_linux.go | 4 ++-- logging/logfile_solaris.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 logging/logfile_solaris.go diff --git a/logging/logfile_linux.go b/logging/logfile_linux.go index 712d434b000d..6cdacfe80e22 100644 --- a/logging/logfile_linux.go +++ b/logging/logfile_linux.go @@ -1,5 +1,5 @@ -//go:build dragonfly || linux || solaris -// +build dragonfly linux solaris +//go:build dragonfly || linux +// +build dragonfly linux package logging diff --git a/logging/logfile_solaris.go b/logging/logfile_solaris.go new file mode 100644 index 000000000000..b64610cc38fc --- /dev/null +++ b/logging/logfile_solaris.go @@ -0,0 +1,17 @@ +//go:build solaris +// +build solaris + +package logging + +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 +}