-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrotate.go
122 lines (96 loc) · 2.18 KB
/
rotate.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package rotateFile
import (
"os"
"sync"
"time"
)
type TSuffix string
const (
// 文件名后缀的格式
SuffixHour TSuffix = "06010215"
SuffixDay TSuffix = "060102"
SuffixMonth TSuffix = "0601"
// Log类文件的Flag
LogFlag = os.O_WRONLY | os.O_CREATE | os.O_APPEND
// Log Mode
LogMode = 0666
)
type Rotate struct {
file *os.File
suffixType string
orgFilename string
// 文件的打开属性
flag int
mode os.FileMode
// 文件名锁,保护下面几个属性
filenameMu sync.Mutex
destFilename string
destKey string // 目标文件的key值,用以区分
}
func Open(filename string) *Rotate {
return &Rotate{
flag: LogFlag,
mode: LogMode,
orgFilename: filename,
suffixType: string(SuffixHour), // 默认按小时
}
}
var nowFunc = time.Now
func (f *Rotate) SetSuffix(suffixType TSuffix) {
f.suffixType = string(suffixType)
}
func (f *Rotate) SetFlag(flag int) {
f.flag = flag
}
func (f *Rotate) SetMode(mode os.FileMode) {
f.mode = mode
}
// ResetFile 重新打开文件操作对象
// 通常不需要调用该方法
// 如果Write方法写入失败,可以尝试重建File对象
func (f *Rotate) ResetFile() error {
now := nowFunc()
f.filenameMu.Lock()
defer f.filenameMu.Unlock()
key := now.Format(f.suffixType)
name := f.orgFilename + "." + key
// 创建新的文件对象
file, err := os.OpenFile(name, f.flag, f.mode)
if err != nil {
f.filenameMu.Unlock()
return err
}
// 关闭旧对象
if f.file != nil {
f.file.Close()
}
f.file, f.destFilename, f.destKey = file, name, key
return nil
}
func (f *Rotate) Write(b []byte) (n int, err error) {
now := nowFunc()
f.filenameMu.Lock()
key := now.Format(f.suffixType)
if key != f.destKey {
if f.file != nil {
f.file.Close()
}
// 新文件名
name := f.orgFilename + "." + key
// 创建新的文件对象
f.file, err = os.OpenFile(name, f.flag, f.mode)
if err != nil {
f.filenameMu.Unlock()
return n, err
}
f.destFilename, f.destKey = name, key
}
f.filenameMu.Unlock()
return f.file.Write(b)
}
func (f *Rotate) WriteString(s string) (n int, err error) {
return f.Write([]byte(s))
}
func (f *Rotate) Close() error {
return f.file.Close()
}