Skip to content

Commit

Permalink
move the rotatewriter to the utils
Browse files Browse the repository at this point in the history
  • Loading branch information
otherview committed May 9, 2024
1 parent 7593495 commit e5593f5
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 21 deletions.
6 changes: 3 additions & 3 deletions api/api_request_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ import (
"time"

"github.com/ethereum/go-ethereum/log"
"github.com/otherview/filerotatewriter"
"github.com/vechain/thor/v2/api/utils/rotatewriter"
)

// RequestLogger logs requests to an output
type RequestLogger struct {
enabled bool
writerChan chan entry
stopChan chan bool
outputWriter filerotatewriter.FileRotateWriter
outputWriter rotatewriter.RotateWriter
}

func NewRequestLogger(enabled bool, fileRotate filerotatewriter.FileRotateWriter) *RequestLogger {
func NewRequestLogger(enabled bool, fileRotate rotatewriter.RotateWriter) *RequestLogger {
return &RequestLogger{
enabled: enabled,
outputWriter: fileRotate,
Expand Down
2 changes: 1 addition & 1 deletion api/api_request_logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/stretchr/testify/assert"
)

// MockWriter implements filerotatewriter.FileRotateWriter interface
// MockWriter implements rotatewriter.RotateWriter interface
type MockWriter struct {
Messages []string
lock sync.RWMutex
Expand Down
127 changes: 127 additions & 0 deletions api/utils/rotatewriter/rotate_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package rotatewriter

import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"time"
)

type RotateWriter interface {
Start() error
Write(p []byte) (int, error)
}

type Writer struct {
dirPath string
fileBaseName string
maxFileSize int64
maxNumFiles int
currentFile *os.File
currentSize int64
numFilesRotated int
}

func (w *Writer) Start() error {
// Open the current log file
err := w.openNextFile()
if err != nil {
return fmt.Errorf("unable to open next file")
}

return nil
}

func (w *Writer) Write(p []byte) (int, error) {
if w.currentFile == nil {
return 0, io.ErrClosedPipe
}

// Rotate the log file if it exceeds the maximum file size
if w.currentSize+int64(len(p)) > w.maxFileSize {
err := w.rotateLogFile()
if err != nil {
return 0, err
}
}

// Write the log message to the current log file
n, err := w.currentFile.Write(p)
w.currentSize += int64(n)
return n, err
}

func (w *Writer) openNextFile() error {
if w.currentFile != nil {
err := w.currentFile.Close()
if err != nil {
fmt.Println(err)
}
}

w.currentSize = 0
w.numFilesRotated = 0

// Construct the file name for the next log file
timestamp := time.Now().Format("2006-01-02T15-04-05")
filename := w.fileBaseName + "-" + timestamp + ".log"
filePath := filepath.Join(w.dirPath, filename)

_, err := os.Stat(filePath)
if err == nil { // File exists, append ms
timestamp = time.Now().Format("2006-01-02T15-04-05.000")
filename = w.fileBaseName + "-" + timestamp + ".log"
filePath = filepath.Join(w.dirPath, filename)
}

// Open the next log file
file, err := os.Create(filePath)
if err != nil {
return err
}

w.currentFile = file
return nil
}

func (w *Writer) rotateLogFile() error {
err := w.openNextFile()
if err != nil {
return err
}

w.numFilesRotated++

// Delete old log files if the maximum number of files has been exceeded
if w.maxNumFiles > 0 && w.numFilesRotated >= w.maxNumFiles {
err = w.deleteOldLogFiles()
if err != nil {
return err
}
}

return nil
}

func (w *Writer) deleteOldLogFiles() error {
// List all log files in the directory
files, err := filepath.Glob(filepath.Join(w.dirPath, w.fileBaseName+"-*.log"))
if err != nil {
return err
}

// Sort the log files by name (oldest first)
sort.Strings(files)

// Delete the oldest log files
for i := 0; i < len(files)-w.maxNumFiles+1; i++ {
err := os.Remove(files[i])
if err != nil {
return err
}
}

return nil
}
55 changes: 55 additions & 0 deletions api/utils/rotatewriter/rotate_writer_builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package rotatewriter

import "fmt"

type BuilderOptionsFunc func(*Writer) error

func New(opts ...BuilderOptionsFunc) (RotateWriter, error) {
r := &Writer{
dirPath: "",
fileBaseName: "",
maxFileSize: 0,
maxNumFiles: 0,
currentFile: nil,
currentSize: 0,
numFilesRotated: 0,
}
for _, opt := range opts {
if err := opt(r); err != nil {
return nil, err
}
}
if r.dirPath == "" || r.fileBaseName == "" || r.maxFileSize == 0 || r.maxNumFiles == 0 {
return nil, fmt.Errorf("missing base setting(s)")
}

return r, nil
}

func WithMaxNumberFiles(i int) BuilderOptionsFunc {
return func(w *Writer) error {
w.maxNumFiles = i
return nil
}
}

func WithFileMaxSize(i int64) BuilderOptionsFunc {
return func(w *Writer) error {
w.maxFileSize = i
return nil
}
}

func WithFileBaseName(s string) BuilderOptionsFunc {
return func(w *Writer) error {
w.fileBaseName = s
return nil
}
}

func WithDir(s string) BuilderOptionsFunc {
return func(w *Writer) error {
w.dirPath = s
return nil // TODO check if dir is writable
}
}
59 changes: 59 additions & 0 deletions api/utils/rotatewriter/rotate_writer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package rotatewriter

import (
"math/rand"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewRotatingLogWriter(t *testing.T) {
temp, err := os.MkdirTemp("", "*")
require.NoError(t, err)

// Create a rotating log writer with a maximum size of 1 MB
writer, err := New(
WithDir(temp),
WithFileBaseName("derp"),
WithFileMaxSize(1024*1024),
WithMaxNumberFiles(5),
)
assert.Nil(t, err)

require.NoError(t, writer.Start())

createdFile := writer.(*Writer).currentFile.Name()

// Use the rotating log writer with the standard log package
data := make([]byte, 1024*1024)
rand.Read(data) //nolint: gosec,staticcheck
_, err = writer.Write(data)
assert.Nil(t, err)

// Use the rotating log writer with the standard log package
rand.Read(data) //nolint: gosec,staticcheck
_, err = writer.Write(data)
assert.Nil(t, err)

assert.NotEqual(t, createdFile, writer.(*Writer).currentFile.Name())

// make sure the milliseconds dont colide
createdFile = writer.(*Writer).currentFile.Name()
// Use the rotating log writer with the standard log package
rand.Read(data) //nolint: gosec,staticcheck
_, err = writer.Write(data)
assert.Nil(t, err)

assert.NotEqual(t, createdFile, writer.(*Writer).currentFile.Name())
}

func TestStdoutWriter(t *testing.T) {
writer := StdoutWriter()
data := make([]byte, 1024*1024)
rand.Read(data) //nolint: gosec,staticcheck
i, err := writer.Write(data)
assert.Nil(t, err)
assert.Equal(t, len(data), i)
}
19 changes: 19 additions & 0 deletions api/utils/rotatewriter/stdout_rotate_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package rotatewriter

import "fmt"

type StdoutWriterImpl struct {
}

func (s StdoutWriterImpl) Start() error {
return nil
}

func (s StdoutWriterImpl) Write(p []byte) (int, error) {
fmt.Println(string(p))
return len(p), nil
}

func StdoutWriter() RotateWriter { // TODO add in io streams
return &StdoutWriterImpl{}
}
4 changes: 2 additions & 2 deletions cmd/thor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/inconshreveable/log15"
"github.com/mattn/go-isatty"
"github.com/otherview/filerotatewriter"
"github.com/pborman/uuid"
"github.com/pkg/errors"
"github.com/vechain/thor/v2/api"
"github.com/vechain/thor/v2/api/utils/rotatewriter"
"github.com/vechain/thor/v2/bft"
"github.com/vechain/thor/v2/cmd/thor/node"
"github.com/vechain/thor/v2/cmd/thor/optimizer"
Expand Down Expand Up @@ -282,7 +282,7 @@ func soloAction(ctx *cli.Context) error {
var mainDB *muxdb.MuxDB
var logDB *logdb.LogDB
var instanceDir string
var fileRotateWriter filerotatewriter.FileRotateWriter
var fileRotateWriter rotatewriter.RotateWriter
var err error

if ctx.Bool(persistFlag.Name) {
Expand Down
18 changes: 9 additions & 9 deletions cmd/thor/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/inconshreveable/log15"
"github.com/mattn/go-tty"
"github.com/otherview/filerotatewriter"
"github.com/pkg/errors"
"github.com/vechain/thor/v2/api/doc"
"github.com/vechain/thor/v2/api/utils/rotatewriter"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/cmd/thor/node"
"github.com/vechain/thor/v2/co"
Expand Down Expand Up @@ -348,24 +348,24 @@ func suggestFDCache() int {
return n
}

func openFileRotate(ctx *cli.Context, instanceDir string) (filerotatewriter.FileRotateWriter, error) {
func openFileRotate(ctx *cli.Context, instanceDir string) (rotatewriter.RotateWriter, error) {
// Max of 10 files with 10Mb each
// files will be rotated after that maximum
if ctx.Bool(apiLogsEnabledFlag.Name) {
return filerotatewriter.New(
filerotatewriter.WithDir(instanceDir),
filerotatewriter.WithFileBaseName("request-logs"),
filerotatewriter.WithFileMaxSize(ctx.Int64(apiLogsMaxFileSizeFlag.Name)),
filerotatewriter.WithMaxNumberFiles(ctx.Int(apiLogsMaxFileCountFlag.Name)),
return rotatewriter.New(
rotatewriter.WithDir(instanceDir),
rotatewriter.WithFileBaseName("request-logs"),
rotatewriter.WithFileMaxSize(ctx.Int64(apiLogsMaxFileSizeFlag.Name)),
rotatewriter.WithMaxNumberFiles(ctx.Int(apiLogsMaxFileCountFlag.Name)),
)
}

return nil, nil
}

func openMemFileRotate(ctx *cli.Context) filerotatewriter.FileRotateWriter {
func openMemFileRotate(ctx *cli.Context) rotatewriter.RotateWriter {
if ctx.Bool(apiLogsEnabledFlag.Name) {
return filerotatewriter.StdoutWriter()
return rotatewriter.StdoutWriter()
}

return nil
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ require (
github.com/mattn/go-isatty v0.0.3
github.com/mattn/go-sqlite3 v1.14.9
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a
github.com/otherview/filerotatewriter v0.0.0-20240509103702-a305c09fd53a
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib v1.0.0
github.com/qianbin/directcache v0.9.7
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.7.2
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a
github.com/vechain/go-ecvrf v0.0.0-20220525125849-96fa0442e765
golang.org/x/crypto v0.21.0
Expand Down
5 changes: 1 addition & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/otherview/filerotatewriter v0.0.0-20240509103702-a305c09fd53a h1:c8RixuoF5WMDhEHqXRT3kxoomiHmhSxxoxJDL0rzxkg=
github.com/otherview/filerotatewriter v0.0.0-20240509103702-a305c09fd53a/go.mod h1:9JtXzZqdljunuU1JIxWUdzVB8w+ZX0Y3ncShN0/xFrE=
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c h1:MUyE44mTvnI5A0xrxIxaMqoWFzPfQvtE2IWUollMDMs=
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
Expand All @@ -134,9 +132,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/vechain/go-ecvrf v0.0.0-20220525125849-96fa0442e765 h1:jvr+TSivjObZmOKVdqlgeLtRhaDG27gE39PMuE2IJ24=
github.com/vechain/go-ecvrf v0.0.0-20220525125849-96fa0442e765/go.mod h1:cwnTMgAVzMb30xMKnGI1LdU1NjMiPllYb7i3ibj/fzE=
github.com/vechain/go-ethereum v1.8.15-0.20240308194045-2f457f0512c5 h1:LNy+K6nqSdUBg/Eot8uXLRc0D63zKFhUCAEjvZmLzQA=
Expand Down

0 comments on commit e5593f5

Please sign in to comment.