@@ -23,13 +23,14 @@ func SetDefaultWriter(w *Writer) { defaultWriter = w }
23
23
// tk 为整点间隔单位
24
24
// tkSStop 为日志切割停止信号
25
25
type Writer struct {
26
- buf chan string
27
- signal chan struct {}
28
- f * os.File
29
- nextTheTime time.Time
30
- filepath string
31
- tk time.Duration
32
- tkStop chan struct {}
26
+ buf chan string // 日志数据缓冲
27
+ rotateSignal chan struct {} // 日志切割信号
28
+ f * os.File // 当前落盘日志文件指针
29
+ nextTheTime time.Time // 当前日志所在整点时间
30
+ filepath string // 默认日志文件地址
31
+ tk time.Duration // 日志切割间隔整点时间
32
+ tkStop chan struct {} // 日志切割停止信号
33
+ syncFileBuf chan * os.File // 需要异步关闭的文件指针
33
34
}
34
35
35
36
// Clone 复制一个新的Writer
@@ -64,19 +65,17 @@ func (f WriterOptionFunc) Apply(w *Writer) {
64
65
// file 文件名
65
66
// tk 日志切割的间隔整点时间单位
66
67
// cacheMax 缓存的最大值
67
- // TODO: Writer 的配置项做成Options方式处理
68
+ // Writer 的配置项做成Options方式处理
68
69
func NewWriter (file string , tk time.Duration , cacheMax int64 ) (w * Writer ) {
69
70
// 路径转换(相对路径转绝对路径)
70
- if ! filepath .IsAbs (file ) {
71
- var err error
72
- file , err = filepath .Abs (file )
73
- if err != nil {
74
- panic (err )
75
- }
71
+ var err error
72
+ file , err = filepath .Abs (file ) //绝对路径会直接返回绝对路径
73
+ if err != nil {
74
+ panic (err )
76
75
}
77
76
78
77
firstTheTime := NextTheTime (time .Now (), tk )
79
- firstFile := GenLogFilepath (file , firstTheTime )
78
+ firstFile := GenLogFilepath (file , firstTheTime , tk )
80
79
f , err := os .OpenFile (firstFile , os .O_WRONLY | os .O_APPEND | os .O_CREATE , 0666 )
81
80
if err != nil {
82
81
panic (err )
@@ -87,17 +86,19 @@ func NewWriter(file string, tk time.Duration, cacheMax int64) (w *Writer) {
87
86
}
88
87
89
88
w = & Writer {
90
- buf : make (chan string , cacheMax ),
91
- signal : make (chan struct {}),
92
- f : f ,
93
- nextTheTime : firstTheTime ,
94
- filepath : file ,
95
- tk : tk ,
96
- tkStop : make (chan struct {}),
89
+ buf : make (chan string , cacheMax ),
90
+ rotateSignal : make (chan struct {}),
91
+ f : f ,
92
+ nextTheTime : firstTheTime ,
93
+ filepath : file ,
94
+ tk : tk ,
95
+ tkStop : make (chan struct {}),
96
+ syncFileBuf : make (chan * os.File , 128 ),
97
97
}
98
98
99
99
go w .run ()
100
100
go w .rotate ()
101
+ go w .syncSync ()
101
102
102
103
return
103
104
}
@@ -106,7 +107,6 @@ func NewWriter(file string, tk time.Duration, cacheMax int64) (w *Writer) {
106
107
// io.Writer interface的实现
107
108
func (w * Writer ) Write (p []byte ) (n int , err error ) {
108
109
w .buf <- string (p )
109
- // TODO: whether n,err have been used by zap
110
110
return
111
111
}
112
112
@@ -125,61 +125,67 @@ func (w *Writer) run() {
125
125
case b , ok := <- w .buf :
126
126
if ! ok {
127
127
w .tkStop <- struct {}{}
128
- w .f .Sync ()
128
+ w .f .Sync () // TODO: 检查logger.Sync()
129
129
w .f .Close ()
130
130
return
131
131
}
132
- // TODO: check json repeated key
132
+ // check json repeated key
133
133
fmt .Println ("准备写入文件的日志内容:" , b )
134
134
bm := make (map [string ]interface {}, 0 )
135
135
err := json .Unmarshal ([]byte (b ), & bm )
136
136
if err != nil {
137
137
fmt .Println (err )
138
138
}
139
139
140
- fmt .Println ("准备写入文件的日志内容,json->map:" , bm ) //TODO: delete
141
140
bb , err := json .Marshal (bm )
142
141
if err != nil {
143
142
fmt .Println (err )
144
143
}
145
- fmt .Println ("当前日志写入的文件名" , w .f .Name ()) //TODO: delete
146
144
// w.f.WriteString(b)
147
145
w .f .WriteString (string (bb ) + "\n " )
148
- case <- w .signal :
149
- w . f . Sync ()
150
- w .f . Close ()
146
+ case <- w .rotateSignal :
147
+ // 异步化处理文件同步、关闭
148
+ w .syncFileBuf <- w . f
151
149
// replace os.File
152
- fmt .Println ("收到替换信号,当前日志文件:" , w .f .Name ())
153
- fmt .Println ("收到替换信号,w.nextTheTime:" , w .nextTheTime .Format (time .RFC3339 ))
154
- newFile := GenLogFilepath (w .filepath , w .nextTheTime )
155
- fmt .Println ("收到替换信号,newFile生成的文件名:" , newFile )
150
+ newFile := GenLogFilepath (w .filepath , w .nextTheTime , w .tk )
156
151
var err error
157
152
w .f , err = os .OpenFile (newFile , os .O_WRONLY | os .O_APPEND | os .O_CREATE , 0666 )
158
153
if err != nil {
159
154
fmt .Println (err )
160
155
}
161
- fmt .Println ("收到替换信号,已替换替换的日志文件名:" , w .f .Name ())
162
156
}
163
157
}
164
158
}
165
159
166
- // rotate
160
+ // rotate
167
161
// 定时发送日志切割信号
168
162
// 监听切割终止信号
169
163
func (w * Writer ) rotate () {
170
164
for {
171
165
t := time .NewTimer (w .nextTheTime .Sub (time .Now ()))
172
166
select {
173
167
case <- w .tkStop :
168
+ close (w .syncFileBuf ) // 通知异步任务关闭
174
169
return
175
170
case <- t .C :
176
171
// change nextTheTime
177
- fmt .Println ("发送替换日志文件信号时间,NextTheTime前:" , w .nextTheTime .Format (time .RFC3339 )) // TODO: delete
178
172
w .nextTheTime = NextTheTime (w .nextTheTime , w .tk )
179
- fmt .Println ("发送替换日志文件信号时间,NextTheTime后:" , w .nextTheTime .Format (time .RFC3339 )) // TODO: delete
180
173
// it's about time to repalce os.File.
181
- w .signal <- struct {}{}
174
+ w .rotateSignal <- struct {}{}
182
175
}
183
176
184
177
}
185
178
}
179
+
180
+ func (w * Writer ) syncSync () {
181
+ for {
182
+ select {
183
+ case f , ok := <- w .syncFileBuf :
184
+ if ! ok {
185
+ return
186
+ }
187
+ f .Sync ()
188
+ f .Close ()
189
+ }
190
+ }
191
+ }
0 commit comments