summaryrefslogtreecommitdiff
path: root/internal/io/dlog
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2021-09-28 21:11:50 +0300
committerPaul Buetow <paul@buetow.org>2021-10-02 12:26:36 +0300
commit609921f9c783941eaa9019a92b78ec45b49d681c (patch)
treec4fc6b20404d0f922dc2825e4624be8c04479cbf /internal/io/dlog
parentfcaa94c7453efa0d74e330128c0f5c2cde8f11b3 (diff)
can have daily and normal file log rotation
Diffstat (limited to 'internal/io/dlog')
-rw-r--r--internal/io/dlog/dlog.go14
-rw-r--r--internal/io/dlog/loggers/factory.go8
-rw-r--r--internal/io/dlog/loggers/file.go117
-rw-r--r--internal/io/dlog/loggers/fout.go4
-rw-r--r--internal/io/dlog/strategy.go22
5 files changed, 78 insertions, 87 deletions
diff --git a/internal/io/dlog/dlog.go b/internal/io/dlog/dlog.go
index 49b405d..49533a5 100644
--- a/internal/io/dlog/dlog.go
+++ b/internal/io/dlog/dlog.go
@@ -36,19 +36,21 @@ func Start(ctx context.Context, wg *sync.WaitGroup, sourceProcess source, logLev
Common.FatalPanic("Logger already started")
}
+ strategy := loggers.GetStrategy(config.Common.LogStrategy)
level := newLevel(logLevel)
+
switch sourceProcess {
case CLIENT:
// This is a DTail client process running.
impl := loggers.FOUT
- Client = New(CLIENT, CLIENT, impl, level)
- Server = New(CLIENT, SERVER, impl, level)
+ Client = New(CLIENT, CLIENT, level, impl, strategy)
+ Server = New(CLIENT, SERVER, level, impl, strategy)
Common = Client
case SERVER:
// This is a DTail server process running.
impl := loggers.FILE
- Client = New(SERVER, CLIENT, impl, level)
- Server = New(SERVER, SERVER, impl, level)
+ Client = New(SERVER, CLIENT, level, impl, strategy)
+ Server = New(SERVER, SERVER, level, impl, strategy)
Common = Server
}
@@ -80,13 +82,13 @@ type DLog struct {
}
// New creates a new DTail logger.
-func New(sourceProcess, sourcePackage source, impl loggers.Impl, maxLevel level) *DLog {
+func New(sourceProcess, sourcePackage source, maxLevel level, impl loggers.Impl, strategy loggers.Strategy) *DLog {
hostname, err := os.Hostname()
if err != nil {
panic(err)
}
return &DLog{
- logger: loggers.Factory(sourceProcess.String(), impl),
+ logger: loggers.Factory(sourceProcess.String(), impl, strategy),
sourceProcess: sourceProcess,
sourcePackage: sourcePackage,
maxLevel: maxLevel,
diff --git a/internal/io/dlog/loggers/factory.go b/internal/io/dlog/loggers/factory.go
index 3eb29c5..8697dc4 100644
--- a/internal/io/dlog/loggers/factory.go
+++ b/internal/io/dlog/loggers/factory.go
@@ -17,11 +17,11 @@ const (
var factoryMap map[string]Logger
var factoryMutex sync.Mutex
-func Factory(name string, impl Impl) Logger {
+func Factory(name string, impl Impl, strategy Strategy) Logger {
factoryMutex.Lock()
defer factoryMutex.Unlock()
- id := fmt.Sprintf("name:%s,impl:%v", name, impl)
+ id := fmt.Sprintf("name:%s,fileBase:%s,impl:%v", name, strategy.FileBase, impl)
if factoryMap == nil {
factoryMap = make(map[string]Logger)
@@ -36,10 +36,10 @@ func Factory(name string, impl Impl) Logger {
singleton = newStdout()
factoryMap[id] = singleton
case FILE:
- singleton = newFile()
+ singleton = newFile(strategy)
factoryMap[id] = singleton
case FOUT:
- singleton = newFout()
+ singleton = newFout(strategy)
factoryMap[id] = singleton
}
}
diff --git a/internal/io/dlog/loggers/file.go b/internal/io/dlog/loggers/file.go
index 1c525c9..dcdd7d0 100644
--- a/internal/io/dlog/loggers/file.go
+++ b/internal/io/dlog/loggers/file.go
@@ -12,49 +12,54 @@ import (
"github.com/mimecast/dtail/internal/config"
)
+type fileWriter struct {
+}
+
type fileMessageBuf struct {
now time.Time
message string
}
type file struct {
- bufferCh chan *fileMessageBuf
- pauseCh chan struct{}
- resumeCh chan struct{}
- rotateCh chan struct{}
- flushCh chan struct{}
- lastDateStr string
- fd *os.File
- writer *bufio.Writer
- mutex sync.Mutex
- started bool
+ bufferCh chan *fileMessageBuf
+ pauseCh chan struct{}
+ resumeCh chan struct{}
+ rotateCh chan struct{}
+ flushCh chan struct{}
+ fd *os.File
+ writer *bufio.Writer
+ mutex sync.Mutex
+ started bool
+ lastFileName string
+ strategy Strategy
}
-func newFile() *file {
+func newFile(strategy Strategy) *file {
f := file{
bufferCh: make(chan *fileMessageBuf, runtime.NumCPU()*100),
pauseCh: make(chan struct{}),
resumeCh: make(chan struct{}),
rotateCh: make(chan struct{}),
flushCh: make(chan struct{}),
+ strategy: strategy,
}
- f.getWriter(time.Now().Format("20060102"))
+
return &f
}
-func (s *file) Start(ctx context.Context, wg *sync.WaitGroup) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
+func (f *file) Start(ctx context.Context, wg *sync.WaitGroup) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
// Logger already started from another Goroutine.
- if s.started {
+ if f.started {
wg.Done()
return
}
pause := func(ctx context.Context) {
select {
- case <-s.resumeCh:
+ case <-f.resumeCh:
return
case <-ctx.Done():
return
@@ -66,55 +71,61 @@ func (s *file) Start(ctx context.Context, wg *sync.WaitGroup) {
for {
select {
- case m := <-s.bufferCh:
- s.write(m)
- case <-s.pauseCh:
+ case m := <-f.bufferCh:
+ f.write(m)
+ case <-f.pauseCh:
pause(ctx)
- case <-s.flushCh:
- s.flush()
+ case <-f.flushCh:
+ f.flush()
case <-ctx.Done():
- s.flush()
- s.fd.Close()
+ f.flush()
+ f.fd.Close()
return
}
}
}()
- s.started = true
+ f.started = true
}
-func (s *file) Log(now time.Time, message string) {
- s.bufferCh <- &fileMessageBuf{now, message}
+func (f *file) Log(now time.Time, message string) {
+ f.bufferCh <- &fileMessageBuf{now, message}
}
-func (s *file) LogWithColors(now time.Time, message, coloredMessage string) {
+func (f *file) LogWithColors(now time.Time, message, coloredMessage string) {
panic("Colors not supported in file logger")
}
-func (s *file) Pause() { s.pauseCh <- struct{}{} }
-func (s *file) Resume() { s.resumeCh <- struct{}{} }
-func (s *file) Flush() { s.flushCh <- struct{}{} }
+func (f *file) Pause() { f.pauseCh <- struct{}{} }
+func (f *file) Resume() { f.resumeCh <- struct{}{} }
+func (f *file) Flush() { f.flushCh <- struct{}{} }
// TODO: Test that Rotate() actually works.
-func (s *file) Rotate() { s.rotateCh <- struct{}{} }
-func (file) SupportsColors() bool { return false }
+func (f *file) Rotate() { f.rotateCh <- struct{}{} }
+func (*file) SupportsColors() bool { return false }
-func (s *file) write(m *fileMessageBuf) {
+func (f *file) write(m *fileMessageBuf) {
select {
- case <-s.rotateCh:
- // Force re-opening the outfile.
- s.lastDateStr = ""
+ case <-f.rotateCh:
+ // Force re-opening the outfile next time in getWriter.
+ f.lastFileName = ""
default:
}
- writer := s.getWriter(m.now.Format("20060102"))
+ var writer *bufio.Writer
+ if f.strategy.Rotation == DailyRotation {
+ writer = f.getWriter(m.now.Format("20060102"))
+ } else {
+ writer = f.getWriter(f.strategy.FileBase)
+ }
+
writer.WriteString(m.message)
writer.WriteByte('\n')
}
-func (s *file) getWriter(dateStr string) *bufio.Writer {
- if s.lastDateStr == dateStr {
- return s.writer
+func (f *file) getWriter(name string) *bufio.Writer {
+ if f.lastFileName == name {
+ return f.writer
}
if _, err := os.Stat(config.Common.LogDir); os.IsNotExist(err) {
@@ -123,32 +134,32 @@ func (s *file) getWriter(dateStr string) *bufio.Writer {
}
}
- logFile := fmt.Sprintf("%s/%s.log", config.Common.LogDir, dateStr)
+ logFile := fmt.Sprintf("%s/%s.log", config.Common.LogDir, name)
newFd, err := os.OpenFile(logFile, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
if err != nil {
panic(err)
}
// Close old writer.
- if s.fd != nil {
- s.writer.Flush()
- s.fd.Close()
+ if f.fd != nil {
+ f.writer.Flush()
+ f.fd.Close()
}
- s.fd = newFd
- s.writer = bufio.NewWriterSize(s.fd, 1)
- s.lastDateStr = dateStr
+ f.fd = newFd
+ f.writer = bufio.NewWriterSize(f.fd, 1)
+ f.lastFileName = name
- return s.writer
+ return f.writer
}
-func (s *file) flush() {
- defer s.writer.Flush()
+func (f *file) flush() {
+ defer f.writer.Flush()
for {
select {
- case m := <-s.bufferCh:
- s.write(m)
+ case m := <-f.bufferCh:
+ f.write(m)
default:
return
}
diff --git a/internal/io/dlog/loggers/fout.go b/internal/io/dlog/loggers/fout.go
index 603dbe9..60c318d 100644
--- a/internal/io/dlog/loggers/fout.go
+++ b/internal/io/dlog/loggers/fout.go
@@ -12,8 +12,8 @@ type fout struct {
}
// Logs to both, a file and stdout
-func newFout() *fout {
- return &fout{file: newFile(), stdout: newStdout()}
+func newFout(strategy Strategy) *fout {
+ return &fout{file: newFile(strategy), stdout: newStdout()}
}
func (f *fout) Start(ctx context.Context, wg *sync.WaitGroup) {
diff --git a/internal/io/dlog/strategy.go b/internal/io/dlog/strategy.go
deleted file mode 100644
index 32d8298..0000000
--- a/internal/io/dlog/strategy.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package dlog
-
-import "github.com/mimecast/dtail/internal/config"
-
-// Strategy allows to specify a log rotation strategy.
-type Strategy int
-
-// Possible log strategies.
-const (
- NormalStrategy Strategy = iota
- DailyStrategy Strategy = iota
- StdoutStrategy Strategy = iota
-)
-
-func logStrategy() Strategy {
- switch config.Common.LogStrategy {
- case "daily":
- return DailyStrategy
- default:
- }
- return StdoutStrategy
-}