From af1ea0fa95bb9fec65439f2e41609529db292ace Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Thu, 15 Feb 2018 16:05:59 -0800 Subject: [PATCH] fn: ui no longer uses /stats (#776) Decommission /stats related code. --- api/agent/agent.go | 26 +++---- api/agent/stats.go | 176 +++---------------------------------------- api/server/server.go | 1 - api/server/stats.go | 11 --- 4 files changed, 19 insertions(+), 195 deletions(-) delete mode 100644 api/server/stats.go diff --git a/api/agent/agent.go b/api/agent/agent.go index 60cd3ec3b..4c950f8af 100644 --- a/api/agent/agent.go +++ b/api/agent/agent.go @@ -88,10 +88,6 @@ type Agent interface { // Close is not safe to be called from multiple threads. io.Closer - // Stats should be burned at the stake. adding so as to not ruffle feathers. - // TODO this should be derived from our metrics - Stats() Stats - // Return the http.Handler used to handle Prometheus metric requests PromHandler() http.Handler AddCallListener(fnext.CallListener) @@ -119,8 +115,6 @@ type agent struct { freezeIdleMsecs time.Duration ejectIdleMsecs time.Duration - stats // TODO kill me - // Prometheus HTTP handler promHandler http.Handler } @@ -242,7 +236,7 @@ func (a *agent) endStateTrackers(ctx context.Context, call *call) { } func (a *agent) submit(ctx context.Context, call *call) error { - a.stats.Enqueue(ctx, call.AppName, call.Path) + StatsEnqueue(ctx) a.startStateTrackers(ctx, call) defer a.endStateTrackers(ctx, call) @@ -262,7 +256,7 @@ func (a *agent) submit(ctx context.Context, call *call) error { } // decrement queued count, increment running count - a.stats.DequeueAndStart(ctx, call.AppName, call.Path) + StatsDequeueAndStart(ctx) // pass this error (nil or otherwise) to end directly, to store status, etc err = slot.exec(ctx, call) @@ -289,11 +283,11 @@ func transformTimeout(e error, isRetriable bool) error { // cases. Only timeouts can be a simple dequeue while other cases are actual errors. func (a *agent) handleStatsDequeue(ctx context.Context, call *call, err error) { if err == context.DeadlineExceeded { - a.stats.Dequeue(ctx, call.AppName, call.Path) - IncrementTooBusy(ctx) + StatsDequeue(ctx) + StatsIncrementTooBusy(ctx) } else { - a.stats.DequeueAndFail(ctx, call.AppName, call.Path) - IncrementErrors(ctx) + StatsDequeueAndFail(ctx) + StatsIncrementErrors(ctx) } } @@ -301,15 +295,15 @@ func (a *agent) handleStatsDequeue(ctx context.Context, call *call, err error) { func (a *agent) handleStatsEnd(ctx context.Context, call *call, err error) { if err == nil { // decrement running count, increment completed count - a.stats.Complete(ctx, call.AppName, call.Path) + StatsComplete(ctx) } else { // decrement running count, increment failed count - a.stats.Failed(ctx, call.AppName, call.Path) + StatsFailed(ctx) // increment the timeout or errors count, as appropriate if err == context.DeadlineExceeded { - IncrementTimedout(ctx) + StatsIncrementTimedout(ctx) } else { - IncrementErrors(ctx) + StatsIncrementErrors(ctx) } } } diff --git a/api/agent/stats.go b/api/agent/stats.go index 5246645b7..909407fe8 100644 --- a/api/agent/stats.go +++ b/api/agent/stats.go @@ -3,208 +3,50 @@ package agent import ( "context" "github.com/fnproject/fn/api/common" - "sync" ) -// TODO this should expose: -// * hot containers active -// * memory used / available - -// stats is the top-level struct containing composite and individial statistics all routes in all apps -// an instance of this struc is maintained in memory to keep a record of the current stats since the server was started -// access must be synchronized using the Mutex -type stats struct { - mu sync.Mutex - // composite statistics for all routes in all apps - queue uint64 - running uint64 - complete uint64 - failed uint64 - // statistics for individual apps, keyed by appname - apps map[string]appStats -} - -// appStats holds statistics for the routes in an individual app, keyed by the path of the route -// instances of this struc are used to maintain an in-memory record of the current stats -// access must be synchronized using the Mutex on the parent stats -type appStats struct { - routes map[string]*routeStats -} - -// routeStats holds statistics for an individual route -// instances of this struc are used to maintain an in-memory record of the current stats -// access must be synchronized using the Mutex on the parent stats -type routeStats struct { - queue uint64 - running uint64 - complete uint64 - failed uint64 -} - -// Stats is the top-level struct containing composite and individial statistics all routes in all apps -// an instance of this struc is created when converting the current stats to JSON -type Stats struct { - Queue uint64 - Running uint64 - Complete uint64 - Failed uint64 - // statistics for individual apps, keyed by appname - Apps map[string]AppStats -} - -// AppStats holds statistics for the routes in an individual app, keyed by the path of the route -// instances of this struc are used when converting the current stats to JSON -type AppStats struct { - Routes map[string]*RouteStats -} - -// RouteStats holds statistics for an individual route -// instances of this struc are used when converting the current stats to JSON -type RouteStats struct { - Queue uint64 - Running uint64 - Complete uint64 - Failed uint64 -} - -// return the stats corresponding to the specified app name and route path, creating a new stats if one does not already exist -func (s *stats) getStatsForRoute(app string, path string) *routeStats { - if s.apps == nil { - s.apps = make(map[string]appStats) - } - thisAppStats, appFound := s.apps[app] - if !appFound { - thisAppStats = appStats{routes: make(map[string]*routeStats)} - s.apps[app] = thisAppStats - } - thisRouteStats, pathFound := thisAppStats.routes[path] - if !pathFound { - thisRouteStats = &routeStats{} - thisAppStats.routes[path] = thisRouteStats - } - return thisRouteStats -} - -func (s *stats) Enqueue(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.queue++ - fstats.queue++ - - s.mu.Unlock() - +func StatsEnqueue(ctx context.Context) { common.IncrementGauge(ctx, queuedMetricName) common.IncrementCounter(ctx, callsMetricName) } // Call when a function has been queued but cannot be started because of an error -func (s *stats) Dequeue(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.queue-- - fstats.queue-- - - s.mu.Unlock() - +func StatsDequeue(ctx context.Context) { common.DecrementGauge(ctx, queuedMetricName) } -func (s *stats) DequeueAndStart(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.queue-- - s.running++ - fstats.queue-- - fstats.running++ - - s.mu.Unlock() - +func StatsDequeueAndStart(ctx context.Context) { common.DecrementGauge(ctx, queuedMetricName) common.IncrementGauge(ctx, runningMetricName) } -func (s *stats) Complete(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.running-- - s.complete++ - fstats.running-- - fstats.complete++ - - s.mu.Unlock() - +func StatsComplete(ctx context.Context) { common.DecrementGauge(ctx, runningMetricName) common.IncrementCounter(ctx, completedMetricName) } -func (s *stats) Failed(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.running-- - s.failed++ - fstats.running-- - fstats.failed++ - - s.mu.Unlock() - +func StatsFailed(ctx context.Context) { common.DecrementGauge(ctx, runningMetricName) common.IncrementCounter(ctx, failedMetricName) } -func (s *stats) DequeueAndFail(ctx context.Context, app string, path string) { - s.mu.Lock() - - fstats := s.getStatsForRoute(app, path) - s.queue-- - s.failed++ - fstats.queue-- - fstats.failed++ - - s.mu.Unlock() - +func StatsDequeueAndFail(ctx context.Context) { common.DecrementGauge(ctx, queuedMetricName) common.IncrementCounter(ctx, failedMetricName) } -func IncrementTimedout(ctx context.Context) { +func StatsIncrementTimedout(ctx context.Context) { common.IncrementCounter(ctx, timedoutMetricName) } -func IncrementErrors(ctx context.Context) { +func StatsIncrementErrors(ctx context.Context) { common.IncrementCounter(ctx, errorsMetricName) } -func IncrementTooBusy(ctx context.Context) { +func StatsIncrementTooBusy(ctx context.Context) { common.IncrementCounter(ctx, serverBusyMetricName) } -func (s *stats) Stats() Stats { - // this creates a Stats from a stats - // stats is the internal struc which is continuously updated, and access is controlled using its Mutex - // Stats is a deep copy for external use, and can be converted to JSON - var stats Stats - s.mu.Lock() - stats.Running = s.running - stats.Complete = s.complete - stats.Queue = s.queue - stats.Failed = s.failed - stats.Apps = make(map[string]AppStats) - for appname, thisAppStats := range s.apps { - newAppStats := AppStats{Routes: make(map[string]*RouteStats)} - stats.Apps[appname] = newAppStats - for path, thisRouteStats := range thisAppStats.routes { - newAppStats.Routes[path] = &RouteStats{Queue: thisRouteStats.queue, Running: thisRouteStats.running, Complete: thisRouteStats.complete, Failed: thisRouteStats.failed} - } - } - s.mu.Unlock() - return stats -} - const ( queuedMetricName = "queued" callsMetricName = "calls" diff --git a/api/server/server.go b/api/server/server.go index e4ce49a0b..21d7578f4 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -435,7 +435,6 @@ func (s *Server) bindHandlers(ctx context.Context) { engine.GET("/", handlePing) engine.GET("/version", handleVersion) // TODO: move the following under v1 - engine.GET("/stats", s.handleStats) engine.GET("/metrics", s.handlePrometheusMetrics) profilerSetup(engine, "/debug") diff --git a/api/server/stats.go b/api/server/stats.go deleted file mode 100644 index f51d7104e..000000000 --- a/api/server/stats.go +++ /dev/null @@ -1,11 +0,0 @@ -package server - -import ( - "net/http" - - "github.com/gin-gonic/gin" -) - -func (s *Server) handleStats(c *gin.Context) { - c.JSON(http.StatusOK, s.agent.Stats()) -}