@@ -15,6 +15,7 @@ import (
1515 "syscall"
1616 "time"
1717
18+ "github.com/influxdata/tail/watch"
1819 "github.com/influxdata/telegraf"
1920 "github.com/influxdata/telegraf/agent"
2021 "github.com/influxdata/telegraf/config"
@@ -27,6 +28,7 @@ import (
2728 "github.com/influxdata/telegraf/plugins/outputs"
2829 _ "github.com/influxdata/telegraf/plugins/outputs/all"
2930 _ "github.com/influxdata/telegraf/plugins/processors/all"
31+ "gopkg.in/tomb.v1"
3032)
3133
3234type sliceFlags []string
@@ -53,7 +55,7 @@ var fTestWait = flag.Int("test-wait", 0, "wait up to this many seconds for servi
5355
5456var fConfigs sliceFlags
5557var fConfigDirs sliceFlags
56-
58+ var fWatchConfig = flag . String ( "watch-config" , "" , "Monitoring config changes [notify, poll]" )
5759var fVersion = flag .Bool ("version" , false , "display the version and exit" )
5860var fSampleConfig = flag .Bool ("sample-config" , false ,
5961 "print out full sample configuration" )
@@ -115,6 +117,15 @@ func reloadLoop(
115117 signals := make (chan os.Signal , 1 )
116118 signal .Notify (signals , os .Interrupt , syscall .SIGHUP ,
117119 syscall .SIGTERM , syscall .SIGINT )
120+ if * fWatchConfig != "" {
121+ for _ , fConfig := range fConfigs {
122+ if _ , err := os .Stat (fConfig ); err == nil {
123+ go watchLocalConfig (signals , fConfig )
124+ } else {
125+ log .Printf ("W! Cannot watch config %s: %s" , fConfig , err )
126+ }
127+ }
128+ }
118129 go func () {
119130 select {
120131 case sig := <- signals :
@@ -136,6 +147,46 @@ func reloadLoop(
136147 }
137148}
138149
150+ func watchLocalConfig (signals chan os.Signal , fConfig string ) {
151+ var mytomb tomb.Tomb
152+ var watcher watch.FileWatcher
153+ if * fWatchConfig == "poll" {
154+ watcher = watch .NewPollingFileWatcher (fConfig )
155+ } else {
156+ watcher = watch .NewInotifyFileWatcher (fConfig )
157+ }
158+ changes , err := watcher .ChangeEvents (& mytomb , 0 )
159+ if err != nil {
160+ log .Printf ("E! Error watching config: %s\n " , err )
161+ return
162+ }
163+ log .Println ("I! Config watcher started" )
164+ select {
165+ case <- changes .Modified :
166+ log .Println ("I! Config file modified" )
167+ case <- changes .Deleted :
168+ // deleted can mean moved. wait a bit a check existence
169+ <- time .After (time .Second )
170+ if _ , err := os .Stat (fConfig ); err == nil {
171+ log .Println ("I! Config file overwritten" )
172+ } else {
173+ log .Println ("W! Config file deleted" )
174+ if err := watcher .BlockUntilExists (& mytomb ); err != nil {
175+ log .Printf ("E! Cannot watch for config: %s\n " , err .Error ())
176+ return
177+ }
178+ log .Println ("I! Config file appeared" )
179+ }
180+ case <- changes .Truncated :
181+ log .Println ("I! Config file truncated" )
182+ case <- mytomb .Dying ():
183+ log .Println ("I! Config watcher ended" )
184+ return
185+ }
186+ mytomb .Done ()
187+ signals <- syscall .SIGHUP
188+ }
189+
139190func runAgent (ctx context.Context ,
140191 inputFilters []string ,
141192 outputFilters []string ,
0 commit comments