forked from subchen/go-log
/
always_new_file_writer.go
84 lines (67 loc) · 1.42 KB
/
always_new_file_writer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package log
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"sort"
"strings"
"time"
)
// AlwaysNewFileWriter create new log for every process
type AlwaysNewFileWriter struct {
Name string
MaxCount int
file *os.File
}
// Write implements io.Writer
func (w *AlwaysNewFileWriter) Write(p []byte) (n int, err error) {
if w.file == nil {
if err = w.openFile(); err != nil {
return
}
}
return w.file.Write(p)
}
func (w *AlwaysNewFileWriter) openFile() (err error) {
name := fmt.Sprintf("%s.%s", w.Name, time.Now().Format("20060102_150405"))
// remove symbol link if exist
os.Remove(w.Name)
// create symbol
err = os.Symlink(path.Base(name), w.Name)
if err != nil {
return err
}
w.file, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644)
if err != nil {
return err
}
if w.MaxCount > 0 {
go w.cleanFiles()
}
return nil
}
// clean old files
func (w *AlwaysNewFileWriter) cleanFiles() {
dir := path.Dir(w.Name)
fileList, err := ioutil.ReadDir(dir)
if err != nil {
return
}
prefix := path.Base(w.Name) + "."
var matches []string
for _, f := range fileList {
if !f.IsDir() && strings.HasPrefix(f.Name(), prefix) {
matches = append(matches, f.Name())
}
}
if len(matches) > w.MaxCount {
sort.Sort(sort.Reverse(sort.StringSlice(matches)))
fmt.Println(matches)
for _, f := range matches[w.MaxCount:] {
file := filepath.Join(dir, f)
os.Remove(file)
}
}
}