@@ -2,16 +2,18 @@ package main
2
2
3
3
import (
4
4
"context"
5
- "github.com/fsnotify/fsnotify"
6
- "github.com/go-kit/kit/log"
7
- "github.com/go-kit/kit/log/level"
8
- "github.com/oklog/run"
9
5
"math"
10
6
"os"
11
7
"os/exec"
12
8
"sync"
9
+ "sync/atomic"
13
10
"syscall"
14
11
"time"
12
+
13
+ "github.com/fsnotify/fsnotify"
14
+ "github.com/go-kit/kit/log"
15
+ "github.com/go-kit/kit/log/level"
16
+ "github.com/oklog/run"
15
17
)
16
18
17
19
const (
@@ -26,14 +28,15 @@ var (
26
28
logger log.Logger
27
29
cmd * exec.Cmd
28
30
mutex sync.Mutex
29
- restartTimes int
30
- timer * time.Timer
31
+ restartTimes int32
32
+ timerCtx context.Context
33
+ timerCancel context.CancelFunc
31
34
)
32
35
33
36
func main () {
34
37
logger = log .NewLogfmtLogger (os .Stdout )
35
38
36
- timer = time . NewTimer ( 0 )
39
+ timerCtx , timerCancel = context . WithCancel ( context . Background () )
37
40
38
41
var g run.Group
39
42
{
@@ -57,6 +60,9 @@ func main() {
57
60
start ()
58
61
// Wait for the fluent bit exit.
59
62
wait ()
63
+
64
+ timerCtx , timerCancel = context .WithCancel (context .Background ())
65
+
60
66
// After the fluent bit exit, fluent bit watcher restarts it with an exponential
61
67
// back-off delay (1s, 2s, 4s, ...), that is capped at five minutes.
62
68
backoff ()
@@ -97,11 +103,13 @@ func main() {
97
103
continue
98
104
}
99
105
106
+ _ = level .Info (logger ).Log ("msg" , "Config file changed, stopping Fluent Bit" )
107
+
100
108
// After the config file changed, it should stop the fluent bit,
101
109
// and resets the restart backoff timer.
102
110
stop ()
103
111
resetTimer ()
104
- _ = level .Info (logger ).Log ("msg" , "Config file changed, stop Fluent Bit" )
112
+ _ = level .Info (logger ).Log ("msg" , "Config file changed, stopped Fluent Bit" )
105
113
case <- watcher .Errors :
106
114
_ = level .Error (logger ).Log ("msg" , "Watcher stopped" )
107
115
return nil
@@ -124,13 +132,7 @@ func main() {
124
132
125
133
// Inspired by https://github.com/jimmidyson/configmap-reload
126
134
func isValidEvent (event fsnotify.Event ) bool {
127
- if event .Op & fsnotify .Create != fsnotify .Create {
128
- return false
129
- }
130
- //if filepath.Base(event.Name) != "..data" {
131
- // return false
132
- //}
133
- return true
135
+ return event .Op & fsnotify .Create == fsnotify .Create
134
136
}
135
137
136
138
func start () {
@@ -155,17 +157,19 @@ func start() {
155
157
}
156
158
157
159
func wait () {
158
-
160
+ mutex . Lock ()
159
161
if cmd == nil {
162
+ mutex .Unlock ()
160
163
return
161
164
}
165
+ mutex .Unlock ()
162
166
163
167
startTime := time .Now ()
164
168
_ = level .Error (logger ).Log ("msg" , "Fluent bit exited" , "error" , cmd .Wait ())
165
169
// Once the fluent bit has executed for 10 minutes without any problems,
166
170
// it should resets the restart backoff timer.
167
- if time .Now (). Sub (startTime ) >= ResetTime {
168
- restartTimes = 0
171
+ if time .Since (startTime ) >= ResetTime {
172
+ atomic . StoreInt32 ( & restartTimes , 0 )
169
173
}
170
174
171
175
mutex .Lock ()
@@ -175,16 +179,32 @@ func wait() {
175
179
176
180
func backoff () {
177
181
178
- delayTime := time .Duration (math .Pow (2 , float64 (restartTimes ))) * time .Second
182
+ delayTime := time .Duration (math .Pow (2 , float64 (atomic . LoadInt32 ( & restartTimes ) ))) * time .Second
179
183
if delayTime >= MaxDelayTime {
180
184
delayTime = MaxDelayTime
181
185
}
182
- timer .Reset (delayTime )
186
+
187
+ _ = level .Info (logger ).Log ("msg" , "backoff" , "delay" , delayTime )
183
188
184
189
startTime := time .Now ()
185
- <- timer .C
186
- _ = level .Info (logger ).Log ("msg" , "delay" , "actual" , time .Now ().Sub (startTime ), "expected" , delayTime )
187
- restartTimes = restartTimes + 1
190
+
191
+ timer := time .NewTimer (delayTime )
192
+ defer timer .Stop ()
193
+
194
+ select {
195
+ case <- timerCtx .Done ():
196
+ _ = level .Info (logger ).Log ("msg" , "context cancel" , "actual" , time .Since (startTime ), "expected" , delayTime )
197
+
198
+ atomic .StoreInt32 (& restartTimes , 0 )
199
+
200
+ return
201
+ case <- timer .C :
202
+ _ = level .Info (logger ).Log ("msg" , "backoff timer done" , "actual" , time .Since (startTime ), "expected" , delayTime )
203
+
204
+ atomic .AddInt32 (& restartTimes , 1 )
205
+
206
+ return
207
+ }
188
208
}
189
209
190
210
func stop () {
@@ -193,6 +213,7 @@ func stop() {
193
213
defer mutex .Unlock ()
194
214
195
215
if cmd == nil || cmd .Process == nil {
216
+ _ = level .Info (logger ).Log ("msg" , "Fluent Bit not running. No process to stop." )
196
217
return
197
218
}
198
219
@@ -204,12 +225,6 @@ func stop() {
204
225
}
205
226
206
227
func resetTimer () {
207
-
208
- if timer != nil {
209
- if ! timer .Stop () {
210
- <- timer .C
211
- }
212
- timer .Reset (0 )
213
- }
214
- restartTimes = 0
228
+ timerCancel ()
229
+ atomic .StoreInt32 (& restartTimes , 0 )
215
230
}
0 commit comments