Skip to content

Commit

Permalink
refactor: print logs to one file (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
lwb0214 authored Oct 20, 2024
1 parent 819b4a1 commit 17e6dd0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 54 deletions.
2 changes: 2 additions & 0 deletions logger/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type LogConfig struct {
FileFlushDuration time.Duration
RotateByHour bool
KeepHours uint // make sense when RotateByHour is T
OutputToOneFile bool
}

func initFromConfig(log *Logger,
Expand Down Expand Up @@ -44,6 +45,7 @@ func initFromConfig(log *Logger,
fb.SetFlushDuration(config.FileFlushDuration)
fb.SetRotateByHour(config.RotateByHour)
fb.SetKeepHours(config.KeepHours)
fb.OutputToOneFile(config.OutputToOneFile)
} else {
return fmt.Errorf("unknown log type: %s", config.Type)
}
Expand Down
118 changes: 67 additions & 51 deletions logger/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,18 @@ func (self *syncBuffer) write(b []byte) {
}

type FileBackend struct {
mu sync.Mutex
dir string // directory for log files
files [numSeverity]syncBuffer
flushInterval time.Duration
rotateNum int
maxSize uint64
fall bool
rotateByHour bool
lastCheck uint64
reg *regexp.Regexp // for rotatebyhour log del...
keepHours uint // keep how many hours old, only make sense when rotatebyhour is T
mu sync.Mutex
dir string // directory for log files
files [numSeverity]syncBuffer
flushInterval time.Duration
rotateNum int
maxSize uint64
fall bool
rotateByHour bool
lastCheck uint64
reg *regexp.Regexp // for rotatebyhour log del...
keepHours uint // keep how many hours old, only make sense when rotatebyhour is T
outputToOneFile bool
}

func (self *FileBackend) Flush() {
Expand All @@ -75,7 +76,6 @@ func (self *FileBackend) Flush() {
self.files[i].Flush()
self.files[i].Sync()
}

}

func (self *FileBackend) Close() {
Expand Down Expand Up @@ -123,7 +123,7 @@ func (self *FileBackend) rotateByHourDaemon() {
files, err := ioutil.ReadDir(self.dir)
if err == nil {
for _, file := range files {
// exactly match, then we
// exactly match, then remove
if file.Name() == self.reg.FindString(file.Name()) &&
shouldDel(file.Name(), self.keepHours) {
os.Remove(filepath.Join(self.dir, file.Name()))
Expand All @@ -138,35 +138,43 @@ func (self *FileBackend) monitorFiles() {
for range time.NewTicker(time.Second * 5).C {
for i := 0; i < numSeverity; i++ {
fileName := path.Join(self.dir, severityName[i]+".log")
if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) {
if f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
self.mu.Lock()
self.files[i].close()
self.files[i].Writer = bufio.NewWriterSize(f, bufferSize)
self.files[i].file = f
self.mu.Unlock()
}
}
self.monitorFile(fileName, &self.files[i])
}
}
}

func (self *FileBackend) monitorFile(fileName string, sb *syncBuffer) {
if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) {
if f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
self.mu.Lock()
sb.close()
sb.Writer = bufio.NewWriterSize(f, bufferSize)
sb.file = f
self.mu.Unlock()
}
}
}

func (self *FileBackend) Log(s Severity, msg []byte) {
self.mu.Lock()
switch s {
case FATAL:
self.files[FATAL].write(msg)
case ERROR:
self.files[ERROR].write(msg)
case WARNING:
self.files[WARNING].write(msg)
case INFO:
self.files[INFO].write(msg)
case DEBUG:
self.files[DEBUG].write(msg)
}
if self.fall && s < INFO {
self.files[INFO].write(msg)
if self.outputToOneFile {
self.files[ALL].write(msg)
} else {
switch s {
case FATAL:
self.files[FATAL].write(msg)
case ERROR:
self.files[ERROR].write(msg)
case WARNING:
self.files[WARNING].write(msg)
case INFO:
self.files[INFO].write(msg)
case DEBUG:
self.files[DEBUG].write(msg)
}
if self.fall && s < INFO {
self.files[INFO].write(msg)
}
}
self.mu.Unlock()
if s == FATAL {
Expand Down Expand Up @@ -203,6 +211,11 @@ func (self *FileBackend) SetFlushDuration(t time.Duration) {
self.flushInterval = time.Second
}
}

func (self *FileBackend) OutputToOneFile(flag bool) {
self.outputToOneFile = flag
}

func NewFileBackend(dir string) (*FileBackend, error) {
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, err
Expand All @@ -215,21 +228,9 @@ func NewFileBackend(dir string) (*FileBackend, error) {
if err != nil {
return nil, err
}

count := uint64(0)
stat, err := f.Stat()
if err == nil {
count = uint64(stat.Size())
}
fb.files[i] = syncBuffer{
Writer: bufio.NewWriterSize(f, bufferSize),
file: f,
filePath: fileName,
parent: &fb,
count: count,
}

fb.files[i] = newSyncBuffer(f, &fb, fileName)
}

// default
fb.flushInterval = time.Second * 3
fb.rotateNum = 20
Expand All @@ -238,7 +239,7 @@ func NewFileBackend(dir string) (*FileBackend, error) {
fb.lastCheck = 0
// init reg to match files
// ONLY cover this centry...
fb.reg = regexp.MustCompile("(INFO|ERROR|WARNING|DEBUG|FATAL)\\.log\\.20[0-9]{8}")
fb.reg = regexp.MustCompile("(INFO|ERROR|WARNING|DEBUG|FATAL|ALL)\\.log\\.20[0-9]{8}")
fb.keepHours = 24 * 7

go fb.flushDaemon()
Expand All @@ -247,6 +248,21 @@ func NewFileBackend(dir string) (*FileBackend, error) {
return &fb, nil
}

func newSyncBuffer(f *os.File, fb *FileBackend, fileName string) syncBuffer {
count := uint64(0)
stat, err := f.Stat()
if err == nil {
count = uint64(stat.Size())
}
return syncBuffer{
Writer: bufio.NewWriterSize(f, bufferSize),
file: f,
filePath: fileName,
parent: fb,
count: count,
}
}

func Rotate(rotateNum1 int, maxSize1 uint64) {
if fileback != nil {
fileback.Rotate(rotateNum1, maxSize1)
Expand Down
8 changes: 5 additions & 3 deletions logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const (
WARNING
INFO
DEBUG
ALL
)

var severityName = []string{
Expand All @@ -26,10 +27,11 @@ var severityName = []string{
WARNING: "WARNING",
INFO: "INFO",
DEBUG: "DEBUG",
ALL: "ALL",
}

const (
numSeverity = 5
numSeverity = 6
)

type Backend interface {
Expand All @@ -56,7 +58,7 @@ type Logger struct {
logToStderr bool
}

//resued buffer for fast format the output string
// resued buffer for fast format the output string
type buffer struct {
bytes.Buffer
tmp [64]byte
Expand Down Expand Up @@ -337,7 +339,7 @@ func (l *Logger) SetLogging(level interface{}, backend Backend) {
l.backend = backend
}

/////////////////////////////////////////////////////////////////
// ///////////////////////////////////////////////////////////////
// depth version, only a low level api
func (l *Logger) LogDepth(s Severity, depth int, format string, args ...interface{}) {
l.printfDepth(s, depth+1, format, args...)
Expand Down

0 comments on commit 17e6dd0

Please # to comment.