mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-21 07:51:28 +02:00
fix(access_log): fix slice out-of-bound panic on log rotation
This commit is contained in:
@@ -94,6 +94,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var bytesPool = synk.GetUnsizedBytesPool()
|
var bytesPool = synk.GetUnsizedBytesPool()
|
||||||
|
var sizedPool = synk.GetSizedBytesPool()
|
||||||
|
|
||||||
func NewAccessLogger(parent task.Parent, cfg AnyConfig) (AccessLogger, error) {
|
func NewAccessLogger(parent task.Parent, cfg AnyConfig) (AccessLogger, error) {
|
||||||
writers, err := cfg.Writers()
|
writers, err := cfg.Writers()
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ package accesslog
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"slices"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
gperr "github.com/yusing/goutils/errs"
|
|
||||||
"github.com/yusing/goutils/mockable"
|
"github.com/yusing/goutils/mockable"
|
||||||
strutils "github.com/yusing/goutils/strings"
|
strutils "github.com/yusing/goutils/strings"
|
||||||
)
|
)
|
||||||
@@ -164,31 +163,14 @@ func rotateLogFileByPolicy(file supportRotate, config *Retention, result *Rotate
|
|||||||
|
|
||||||
// Read each line and write it to the beginning of the file
|
// Read each line and write it to the beginning of the file
|
||||||
writePos := int64(0)
|
writePos := int64(0)
|
||||||
buf := bytesPool.Get()
|
|
||||||
defer func() {
|
|
||||||
bytesPool.Put(buf)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// in reverse order to keep the order of the lines (from old to new)
|
// in reverse order to keep the order of the lines (from old to new)
|
||||||
for i := len(linesToKeep) - 1; i >= 0; i-- {
|
for i := len(linesToKeep) - 1; i >= 0; i-- {
|
||||||
line := linesToKeep[i]
|
line := linesToKeep[i]
|
||||||
n := line.Size
|
n := line.Size
|
||||||
if cap(buf) < int(n) {
|
|
||||||
buf = slices.Grow(buf, int(n)-cap(buf))
|
|
||||||
}
|
|
||||||
buf = buf[:n]
|
|
||||||
|
|
||||||
// Read the line from its original position
|
if err := fileContentMove(file, line.Pos, writePos, int(n)); err != nil {
|
||||||
if _, err := file.ReadAt(buf, line.Pos); err != nil {
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write it to the new position
|
|
||||||
if _, err := file.WriteAt(buf, writePos); err != nil {
|
|
||||||
return false, err
|
|
||||||
} else if n < line.Size {
|
|
||||||
return false, gperr.Errorf("%w, writing %d bytes, only %d written", io.ErrShortWrite, line.Size, n)
|
|
||||||
}
|
|
||||||
writePos += n
|
writePos += n
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +181,34 @@ func rotateLogFileByPolicy(file supportRotate, config *Retention, result *Rotate
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileContentMove moves the content of the file from the source position to the destination position.
|
||||||
|
//
|
||||||
|
// this is only used for moving from the back to the front of the file.
|
||||||
|
func fileContentMove(file supportRotate, srcPos, dstPos int64, size int) error {
|
||||||
|
buf := sizedPool.GetSized(size)
|
||||||
|
defer sizedPool.Put(buf)
|
||||||
|
|
||||||
|
// Read the line from its original position
|
||||||
|
nRead, err := file.ReadAt(buf, srcPos)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if nRead != size {
|
||||||
|
return fmt.Errorf("%w, reading %d bytes, only %d read", io.ErrShortBuffer, size, nRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write it to the new position
|
||||||
|
nWritten, err := file.WriteAt(buf, dstPos)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if nWritten != size {
|
||||||
|
return fmt.Errorf("%w, writing %d bytes, only %d written", io.ErrShortWrite, size, nWritten)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// rotateLogFileBySize rotates the log file by size.
|
// rotateLogFileBySize rotates the log file by size.
|
||||||
// It returns the result of the rotation and an error if any.
|
// It returns the result of the rotation and an error if any.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user