From 976b91a77d05d8d5854995cc62c0f97156479264 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Sat, 11 Aug 2018 17:00:37 -0700 Subject: [PATCH] fn: API stats and tags reoorganization (#1171) Make sure we can apply extra tags if RegisterAPIViews() is provided with such tags. Deduplicate path/method/status and always apply these default tags to appropriate views. --- api/common/stats_utils.go | 21 +++++++++++----- api/server/gin_middlewares.go | 47 ++++++++++++++++++++++++++--------- api/server/stats.go | 26 ------------------- cmd/fnserver/main.go | 3 +-- 4 files changed, 51 insertions(+), 46 deletions(-) delete mode 100644 api/server/stats.go diff --git a/api/common/stats_utils.go b/api/common/stats_utils.go index 84c253500..c99b9d416 100644 --- a/api/common/stats_utils.go +++ b/api/common/stats_utils.go @@ -8,11 +8,16 @@ import ( ) func CreateView(measure stats.Measure, agg *view.Aggregation, tagKeys []string) *view.View { + keys := makeKeys(tagKeys) + return CreateViewWithTags(measure, agg, keys) +} + +func CreateViewWithTags(measure stats.Measure, agg *view.Aggregation, tags []tag.Key) *view.View { return &view.View{ Name: measure.Name(), Description: measure.Description(), Measure: measure, - TagKeys: makeKeys(tagKeys), + TagKeys: tags, Aggregation: agg, } } @@ -21,14 +26,18 @@ func MakeMeasure(name string, desc string, unit string) *stats.Int64Measure { return stats.Int64(name, desc, unit) } +func MakeKey(name string) tag.Key { + key, err := tag.NewKey(name) + if err != nil { + logrus.WithError(err).Fatalf("Cannot create tag %s", name) + } + return key +} + func makeKeys(names []string) []tag.Key { tagKeys := make([]tag.Key, len(names)) for i, name := range names { - key, err := tag.NewKey(name) - if err != nil { - logrus.Fatal(err) - } - tagKeys[i] = key + tagKeys[i] = MakeKey(name) } return tagKeys } diff --git a/api/server/gin_middlewares.go b/api/server/gin_middlewares.go index 86a2faef2..26e360959 100644 --- a/api/server/gin_middlewares.go +++ b/api/server/gin_middlewares.go @@ -15,12 +15,23 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "go.opencensus.io/stats" + "go.opencensus.io/stats/view" "go.opencensus.io/tag" "go.opencensus.io/trace" "strconv" "time" ) +var ( + pathKey = common.MakeKey("path") + methodKey = common.MakeKey("method") + statusKey = common.MakeKey("status") + + apiRequestCountMeasure = common.MakeMeasure("api/request_count", "Count of API requests started", stats.UnitDimensionless) + apiResponseCountMeasure = common.MakeMeasure("api/response_count", "API response count", stats.UnitDimensionless) + apiLatencyMeasure = common.MakeMeasure("api/latency", "Latency distribution of API requests", stats.UnitMilliseconds) +) + func optionalCorsWrap(r *gin.Engine) { // By default no CORS are allowed unless one // or more Origins are defined by the API_CORS @@ -78,19 +89,31 @@ func traceWrap(c *gin.Context) { c.Next() } +func RegisterAPIViews(tagKeys []string, dist []float64) { + + // default tags for request and response + reqTags := []tag.Key{pathKey, methodKey} + respTags := []tag.Key{pathKey, methodKey, statusKey} + + // add extra tags if not already in default tags for req/resp + for _, key := range tagKeys { + if key != "path" && key != "method" && key != "status" { + reqTags = append(reqTags, common.MakeKey(key)) + respTags = append(respTags, common.MakeKey(key)) + } + } + + err := view.Register( + common.CreateViewWithTags(apiRequestCountMeasure, view.Count(), reqTags), + common.CreateViewWithTags(apiResponseCountMeasure, view.Count(), respTags), + common.CreateViewWithTags(apiLatencyMeasure, view.Distribution(dist...), respTags), + ) + if err != nil { + logrus.WithError(err).Fatal("cannot register view") + } +} + func apiMetricsWrap(s *Server) { - pathKey, err := tag.NewKey("path") - if err != nil { - logrus.Fatal(err) - } - methodKey, err := tag.NewKey("method") - if err != nil { - logrus.Fatal(err) - } - statusKey, err := tag.NewKey("status") - if err != nil { - logrus.Fatal(err) - } measure := func(engine *gin.Engine) func(*gin.Context) { var routes gin.RoutesInfo diff --git a/api/server/stats.go b/api/server/stats.go deleted file mode 100644 index 06f8c8c6f..000000000 --- a/api/server/stats.go +++ /dev/null @@ -1,26 +0,0 @@ -package server - -import ( - "github.com/fnproject/fn/api/common" - - "github.com/sirupsen/logrus" - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" -) - -var ( - apiRequestCountMeasure = common.MakeMeasure("api/request_count", "Count of API requests started", stats.UnitDimensionless) - apiResponseCountMeasure = common.MakeMeasure("api/response_count", "API response count", stats.UnitDimensionless) - apiLatencyMeasure = common.MakeMeasure("api/latency", "Latency distribution of API requests", stats.UnitMilliseconds) -) - -func RegisterAPIViews(tagKeys []string, dist []float64) { - err := view.Register( - common.CreateView(apiRequestCountMeasure, view.Count(), tagKeys), - common.CreateView(apiResponseCountMeasure, view.Count(), tagKeys), - common.CreateView(apiLatencyMeasure, view.Distribution(dist...), tagKeys), - ) - if err != nil { - logrus.WithError(err).Fatal("cannot register view") - } -} diff --git a/cmd/fnserver/main.go b/cmd/fnserver/main.go index 538e951c6..f7ed970fe 100644 --- a/cmd/fnserver/main.go +++ b/cmd/fnserver/main.go @@ -26,7 +26,6 @@ func main() { func registerViews() { keys := []string{"fn_appname", "fn_path"} - apiKeys := []string{"path", "method", "status"} latencyDist := []float64{1, 10, 50, 100, 250, 500, 1000, 10000, 60000, 120000} @@ -51,5 +50,5 @@ func registerViews() { // Register s3 log views s3.RegisterViews(keys, latencyDist) - server.RegisterAPIViews(apiKeys, latencyDist) + server.RegisterAPIViews([]string{}, latencyDist) }