mirror of
https://gitlab.com/ric_harvey/MailHog.git
synced 2024-11-24 14:54:03 +00:00
123 lines
2.3 KiB
Go
123 lines
2.3 KiB
Go
|
package appenders
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/ian-kent/go-log/layout"
|
||
|
"github.com/ian-kent/go-log/levels"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type rollingFileAppender struct {
|
||
|
Appender
|
||
|
layout layout.Layout
|
||
|
MaxFileSize int64
|
||
|
MaxBackupIndex int
|
||
|
|
||
|
filename string
|
||
|
file *os.File
|
||
|
append bool
|
||
|
writeMutex sync.Mutex
|
||
|
|
||
|
bytesWritten int64
|
||
|
}
|
||
|
|
||
|
func RollingFile(filename string, append bool) *rollingFileAppender {
|
||
|
a := &rollingFileAppender{
|
||
|
layout: layout.Default(),
|
||
|
MaxFileSize: 104857600,
|
||
|
MaxBackupIndex: 1,
|
||
|
append: append,
|
||
|
bytesWritten: 0,
|
||
|
}
|
||
|
err := a.SetFilename(filename)
|
||
|
if err != nil {
|
||
|
fmt.Printf("Error opening file: %s\n", err)
|
||
|
return nil
|
||
|
}
|
||
|
return a
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) Close() {
|
||
|
if a.file != nil {
|
||
|
a.file.Close()
|
||
|
a.file = nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) Write(level levels.LogLevel, message string, args ...interface{}) {
|
||
|
m := a.Layout().Format(level, message, args...)
|
||
|
if !strings.HasSuffix(m, "\n") {
|
||
|
m += "\n"
|
||
|
}
|
||
|
|
||
|
a.writeMutex.Lock()
|
||
|
a.file.Write([]byte(m))
|
||
|
|
||
|
a.bytesWritten += int64(len(m))
|
||
|
if a.bytesWritten >= a.MaxFileSize {
|
||
|
a.bytesWritten = 0
|
||
|
a.rotateFile()
|
||
|
}
|
||
|
|
||
|
a.writeMutex.Unlock()
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) Layout() layout.Layout {
|
||
|
return a.layout
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) SetLayout(layout layout.Layout) {
|
||
|
a.layout = layout
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) Filename() string {
|
||
|
return a.filename
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) SetFilename(filename string) error {
|
||
|
if a.filename != filename || a.file == nil {
|
||
|
a.closeFile()
|
||
|
a.filename = filename
|
||
|
err := a.openFile()
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (a *rollingFileAppender) rotateFile() {
|
||
|
a.closeFile()
|
||
|
|
||
|
lastFile := a.filename + "." + strconv.Itoa(a.MaxBackupIndex)
|
||
|
if _, err := os.Stat(lastFile); err == nil {
|
||
|
os.Remove(lastFile)
|
||
|
}
|
||
|
|
||
|
for n := a.MaxBackupIndex; n > 0; n-- {
|
||
|
f1 := a.filename + "." + strconv.Itoa(n)
|
||
|
f2 := a.filename + "." + strconv.Itoa(n+1)
|
||
|
os.Rename(f1, f2)
|
||
|
}
|
||
|
|
||
|
os.Rename(a.filename, a.filename+".1")
|
||
|
|
||
|
a.openFile()
|
||
|
}
|
||
|
func (a *rollingFileAppender) closeFile() {
|
||
|
if a.file != nil {
|
||
|
a.file.Close()
|
||
|
a.file = nil
|
||
|
}
|
||
|
}
|
||
|
func (a *rollingFileAppender) openFile() error {
|
||
|
mode := os.O_WRONLY | os.O_APPEND | os.O_CREATE
|
||
|
if !a.append {
|
||
|
mode = os.O_WRONLY | os.O_CREATE
|
||
|
}
|
||
|
f, err := os.OpenFile(a.filename, mode, 0666)
|
||
|
a.file = f
|
||
|
return err
|
||
|
}
|