From 9adfae11a26fcf860e4b0c5eb6928b198bc57644 Mon Sep 17 00:00:00 2001 From: Tyler Treat Date: Fri, 23 Jun 2017 10:03:01 -0500 Subject: [PATCH] Add reload count to server for monitoring --- server/monitor.go | 2 ++ server/reload.go | 10 ++++++++-- server/reload_test.go | 30 ++++++++++++++++++++++++++++++ server/server.go | 9 +++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/server/monitor.go b/server/monitor.go index e76d86f4..7cc05977 100644 --- a/server/monitor.go +++ b/server/monitor.go @@ -399,6 +399,7 @@ type Varz struct { SlowConsumers int64 `json:"slow_consumers"` Subscriptions uint32 `json:"subscriptions"` HTTPReqStats map[string]uint64 `json:"http_req_stats"` + Reloaded uint64 `json:"reloaded"` } func myUptime(d time.Duration) string { @@ -478,6 +479,7 @@ func (s *Server) HandleVarz(w http.ResponseWriter, r *http.Request) { v.OutBytes = atomic.LoadInt64(&s.outBytes) v.SlowConsumers = atomic.LoadInt64(&s.slowConsumers) v.Subscriptions = s.sl.Count() + v.Reloaded = s.reloaded s.httpReqStats[VarzPath]++ // Need a copy here since s.httpReqStas can change while doing // the marshaling down below. diff --git a/server/reload.go b/server/reload.go index c14da1c1..cfc3b8f2 100644 --- a/server/reload.go +++ b/server/reload.go @@ -249,14 +249,20 @@ func (s *Server) Reload() error { if err != nil { s.mu.Unlock() // TODO: Dump previous good config to a .bak file? - return fmt.Errorf("Config reload failed: %s", err) + return err } s.mu.Unlock() // Apply flags over config file settings. newOpts = MergeOptions(newOpts, FlagSnapshot) processOptions(newOpts) - return s.reloadOptions(newOpts) + err = s.reloadOptions(newOpts) + if err == nil { + s.mu.Lock() + s.reloaded++ + s.mu.Unlock() + } + return err } // reloadOptions reloads the server config with the provided options. If an diff --git a/server/reload_test.go b/server/reload_test.go index 94c602ba..4b6c83a7 100644 --- a/server/reload_test.go +++ b/server/reload_test.go @@ -19,9 +19,15 @@ import ( // not start with a config file. func TestConfigReloadNoConfigFile(t *testing.T) { server := New(&Options{}) + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } if server.Reload() == nil { t.Fatal("Expected Reload to return an error") } + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } } // Ensure Reload returns an error when attempting to change an option which @@ -30,6 +36,10 @@ func TestConfigReloadUnsupported(t *testing.T) { server, opts, config := newServerWithSymlinkConfig(t, "tmp.conf", "./configs/reload/test.conf") defer os.Remove(config) + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } + golden := &Options{ ConfigFile: config, Host: "0.0.0.0", @@ -75,6 +85,10 @@ func TestConfigReloadUnsupported(t *testing.T) { t.Fatalf("Options are incorrect.\nexpected: %+v\ngot: %+v", golden, opts) } + + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } } // Ensure Reload returns an error when reloading from a bad config file. @@ -82,6 +96,10 @@ func TestConfigReloadInvalidConfig(t *testing.T) { server, opts, config := newServerWithSymlinkConfig(t, "tmp.conf", "./configs/reload/test.conf") defer os.Remove(config) + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } + golden := &Options{ ConfigFile: config, Host: "0.0.0.0", @@ -127,6 +145,10 @@ func TestConfigReloadInvalidConfig(t *testing.T) { t.Fatalf("Options are incorrect.\nexpected: %+v\ngot: %+v", golden, opts) } + + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } } // Ensure Reload returns nil and the config is changed on success. @@ -134,6 +156,10 @@ func TestConfigReload(t *testing.T) { server, opts, config := newServerWithSymlinkConfig(t, "tmp.conf", "./configs/reload/test.conf") defer os.Remove(config) + if reloaded := server.NumReloads(); reloaded != 0 { + t.Fatalf("Reloaded is incorrect.\nexpected: 0\ngot: %d", reloaded) + } + golden := &Options{ ConfigFile: config, Host: "0.0.0.0", @@ -205,6 +231,10 @@ func TestConfigReload(t *testing.T) { if !updated.Cluster.NoAdvertise { t.Fatal("Expected NoAdvertise to be true") } + + if reloaded := server.NumReloads(); reloaded != 1 { + t.Fatalf("Reloaded is incorrect.\nexpected: 1\ngot: %d", reloaded) + } } // Ensure Reload supports TLS config changes. Test this by starting a server diff --git a/server/server.go b/server/server.go index cec881e3..eba6c327 100644 --- a/server/server.go +++ b/server/server.go @@ -79,6 +79,7 @@ type Server struct { grRunning bool grWG sync.WaitGroup // to wait on various go routines cproto int64 // number of clients supporting async INFO + reloaded uint64 // number of times server config has been reloaded logging struct { sync.RWMutex logger Logger @@ -918,6 +919,14 @@ func (s *Server) NumSubscriptions() uint32 { return subs } +// NumReloads returns the number of times the server config has been reloaded. +func (s *Server) NumReloads() uint64 { + s.mu.Lock() + reloaded := s.reloaded + s.mu.Unlock() + return reloaded +} + // Addr will return the net.Addr object for the current listener. func (s *Server) Addr() net.Addr { s.mu.Lock()