Add dynamic reading of config file support
diff --git a/README.md b/README.md
index a8915e6..681bf76 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@
 
 * setting defaults
 * reading from JSON, TOML, and YAML config files
+* live watching and re-reading of config files (optional)
 * reading from environment variables
 * reading from remote config systems (Etcd or Consul), and watching changes
 * reading from command line flags
@@ -78,7 +79,7 @@
 
 Here is an example of how to use Viper to search for and read a configuration file.
 None of the specific paths are required, but at least one path should be provided
-where a configuration file is expected. 
+where a configuration file is expected.
 
 ```go
 viper.SetConfigName("config") // name of config file (without extension)
@@ -91,6 +92,26 @@
 }
 ```
 
+### Watching and re-reading config files
+
+Viper supports the ability to have your application live read a config file while running.
+
+Gone are the days of needing to restart a server to have a config take effect,
+viper powered applications can read an update to a config file while running and
+not miss a beat.
+
+Simply tell the viper instance to watchConfig. 
+Optionally you can provide a function for Viper to run each time a change occurs.
+
+**Make sure you add all of the configPaths prior to calling `WatchConfig()`**
+
+```go
+		viper.WatchConfig()
+		viper.OnConfigChange(func(e fsnotify.Event) {
+			fmt.Println("Config file changed:", e.Name)
+		})
+```
+
 ### Reading Config from io.Reader
 
 Viper predefines many configuration sources such as files, environment
@@ -286,15 +307,15 @@
 go func(){
 	for {
 	    time.Sleep(time.Second * 5) // delay after each request
-	
+
 	    // currently, only tested with etcd support
 	    err := runtime_viper.WatchRemoteConfig()
 	    if err != nil {
 	        log.Errorf("unable to read remote config: %v", err)
 	        continue
 	    }
-	
-	    // unmarshal new config into our runtime config struct. you can also use channel 
+
+	    // unmarshal new config into our runtime config struct. you can also use channel
 	    // to implement a signal to notify the system of the changes
 	    runtime_viper.Unmarshal(&runtime_conf)
 	}
diff --git a/viper.go b/viper.go
index af6e5ed..20c12ec 100644
--- a/viper.go
+++ b/viper.go
@@ -24,6 +24,7 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"log"
 	"os"
 	"path/filepath"
 	"reflect"
@@ -35,6 +36,7 @@
 	"github.com/spf13/cast"
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/spf13/pflag"
+	"gopkg.in/fsnotify.v1"
 )
 
 var v *Viper
@@ -151,6 +153,8 @@
 	env            map[string]string
 	aliases        map[string]string
 	typeByDefValue bool
+
+	onConfigChange func(fsnotify.Event)
 }
 
 // Returns an initialized Viper instance.
@@ -219,6 +223,52 @@
 // Universally supported remote providers.
 var SupportedRemoteProviders []string = []string{"etcd", "consul"}
 
+func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
+func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
+	v.onConfigChange = run
+}
+
+func WatchConfig() { v.WatchConfig() }
+func (v *Viper) WatchConfig() {
+	go func() {
+		watcher, err := fsnotify.NewWatcher()
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer watcher.Close()
+
+		done := make(chan bool)
+		go func() {
+			for {
+				select {
+				case event := <-watcher.Events:
+					if event.Op&fsnotify.Write == fsnotify.Write {
+						err := v.ReadInConfig()
+						if err != nil {
+							log.Println("error:", err)
+						}
+						v.onConfigChange(event)
+					}
+				case err := <-watcher.Errors:
+					log.Println("error:", err)
+				}
+			}
+		}()
+
+		if v.configFile != "" {
+			watcher.Add(v.configFile)
+		} else {
+			for _, x := range v.configPaths {
+				err = watcher.Add(x)
+				if err != nil {
+					log.Fatal(err)
+				}
+			}
+		}
+		<-done
+	}()
+}
+
 // Explicitly define the path, name and extension of the config file
 // Viper will use this and not check any of the config paths
 func SetConfigFile(in string) { v.SetConfigFile(in) }