From 66dd791d36bc5a994e41d2b9c826a63ab646521c Mon Sep 17 00:00:00 2001 From: dprotaso Date: Mon, 12 Jul 2021 20:31:24 -0400 Subject: [PATCH 1/3] move knative.dev/pkg/source to eventing/pkg/metrics/source --- pkg/adapter/v2/cloudevents.go | 2 +- pkg/adapter/v2/cloudevents_test.go | 5 +- pkg/adapter/v2/main.go | 2 +- pkg/adapter/v2/main_message.go | 2 +- pkg/adapter/v2/main_message_test.go | 6 +- pkg/metrics/metrics.go | 6 + pkg/metrics/source/stats_reporter.go | 160 ++++++++++++++++++++++ pkg/metrics/source/stats_reporter_test.go | 97 +++++++++++++ 8 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 pkg/metrics/source/stats_reporter.go create mode 100644 pkg/metrics/source/stats_reporter_test.go diff --git a/pkg/adapter/v2/cloudevents.go b/pkg/adapter/v2/cloudevents.go index 169e1fd69d2..8d9302fc729 100644 --- a/pkg/adapter/v2/cloudevents.go +++ b/pkg/adapter/v2/cloudevents.go @@ -29,8 +29,8 @@ import ( "github.com/cloudevents/sdk-go/v2/protocol/http" "go.opencensus.io/plugin/ochttp" "knative.dev/eventing/pkg/adapter/v2/util/crstatusevent" + "knative.dev/eventing/pkg/metrics/source" duckv1 "knative.dev/pkg/apis/duck/v1" - "knative.dev/pkg/source" "knative.dev/pkg/tracing/propagation/tracecontextb3" ) diff --git a/pkg/adapter/v2/cloudevents_test.go b/pkg/adapter/v2/cloudevents_test.go index f911eb71160..e1b737bb09b 100644 --- a/pkg/adapter/v2/cloudevents_test.go +++ b/pkg/adapter/v2/cloudevents_test.go @@ -25,10 +25,9 @@ import ( cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/cloudevents/sdk-go/v2/protocol/http" - duckv1 "knative.dev/pkg/apis/duck/v1" - "knative.dev/pkg/source" - "knative.dev/eventing/pkg/adapter/v2/test" + "knative.dev/eventing/pkg/metrics/source" + duckv1 "knative.dev/pkg/apis/duck/v1" ) type mockReporter struct { diff --git a/pkg/adapter/v2/main.go b/pkg/adapter/v2/main.go index 1079a6a25fb..63d777f880a 100644 --- a/pkg/adapter/v2/main.go +++ b/pkg/adapter/v2/main.go @@ -31,6 +31,7 @@ import ( "go.opencensus.io/stats/view" "go.uber.org/zap" + "knative.dev/eventing/pkg/metrics/source" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/controller" "knative.dev/pkg/injection" @@ -40,7 +41,6 @@ import ( "knative.dev/pkg/profiling" "knative.dev/pkg/reconciler" "knative.dev/pkg/signals" - "knative.dev/pkg/source" "knative.dev/eventing/pkg/adapter/v2/util/crstatusevent" ) diff --git a/pkg/adapter/v2/main_message.go b/pkg/adapter/v2/main_message.go index b798967b47d..2675e7a64c5 100644 --- a/pkg/adapter/v2/main_message.go +++ b/pkg/adapter/v2/main_message.go @@ -26,11 +26,11 @@ import ( "github.com/kelseyhightower/envconfig" "go.opencensus.io/stats/view" "go.uber.org/zap" + "knative.dev/eventing/pkg/metrics/source" "knative.dev/pkg/logging" "knative.dev/pkg/metrics" "knative.dev/pkg/profiling" "knative.dev/pkg/signals" - "knative.dev/pkg/source" "knative.dev/eventing/pkg/kncloudevents" ) diff --git a/pkg/adapter/v2/main_message_test.go b/pkg/adapter/v2/main_message_test.go index 6e547c6644d..3e93f24f128 100644 --- a/pkg/adapter/v2/main_message_test.go +++ b/pkg/adapter/v2/main_message_test.go @@ -22,12 +22,12 @@ import ( "testing" "go.opencensus.io/stats/view" - _ "knative.dev/pkg/client/injection/kube/client/fake" + "knative.dev/eventing/pkg/kncloudevents" + "knative.dev/eventing/pkg/metrics/source" "knative.dev/pkg/leaderelection" "knative.dev/pkg/metrics" - "knative.dev/pkg/source" - "knative.dev/eventing/pkg/kncloudevents" + _ "knative.dev/pkg/client/injection/kube/client/fake" ) type myAdapterBindings struct{} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 5148211cb06..23723883162 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -62,4 +62,10 @@ const ( // ContainerName is the container for which the metric is reported. LabelContainerName = metricskey.ContainerName + + // LabelResponseError is the label for client error. For HTTP, A non-2xx status code doesn't cause an error. + LabelResponseError = metricskey.LabelResponseError + + // LabelResponseTimeout is the label timeout. + LabelResponseTimeout = metricskey.LabelResponseTimeout ) diff --git a/pkg/metrics/source/stats_reporter.go b/pkg/metrics/source/stats_reporter.go new file mode 100644 index 00000000000..68d94e47464 --- /dev/null +++ b/pkg/metrics/source/stats_reporter.go @@ -0,0 +1,160 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "context" + + "go.opencensus.io/stats/view" + eventingmetrics "knative.dev/eventing/pkg/metrics" + "knative.dev/pkg/metrics" + + "go.opencensus.io/stats" + "go.opencensus.io/tag" +) + +var ( + // eventCountM is a counter which records the number of events sent by the source. + eventCountM = stats.Int64( + "event_count", + "Number of events sent", + stats.UnitDimensionless, + ) + + // retryEventCountM is a counter which records the number of events sent by the source in retries. + retryEventCountM = stats.Int64( + "retry_event_count", + "Number of retry events sent", + stats.UnitDimensionless, + ) + // Create the tag keys that will be used to add tags to our measurements. + // Tag keys must conform to the restrictions described in + // go.opencensus.io/tag/validate.go. Currently those restrictions are: + // - length between 1 and 255 inclusive + namespaceKey = tag.MustNewKey(eventingmetrics.LabelNamespaceName) + eventSourceKey = tag.MustNewKey(eventingmetrics.LabelEventSource) + eventTypeKey = tag.MustNewKey(eventingmetrics.LabelEventType) + sourceNameKey = tag.MustNewKey(eventingmetrics.LabelName) + sourceResourceGroupKey = tag.MustNewKey(eventingmetrics.LabelResourceGroup) + responseCodeKey = tag.MustNewKey(eventingmetrics.LabelResponseCode) + responseCodeClassKey = tag.MustNewKey(eventingmetrics.LabelResponseCodeClass) + responseError = tag.MustNewKey(eventingmetrics.LabelResponseError) + responseTimeout = tag.MustNewKey(eventingmetrics.LabelResponseTimeout) +) + +// ReportArgs defines the arguments for reporting metrics. +type ReportArgs struct { + Namespace string + EventType string + EventSource string + Name string + ResourceGroup string + Error string + Timeout bool +} + +func init() { + register() +} + +// StatsReporter defines the interface for sending source metrics. +type StatsReporter interface { + // ReportEventCount captures the event count. It records one per call. + ReportEventCount(args *ReportArgs, responseCode int) error + ReportRetryEventCount(args *ReportArgs, responseCode int) error +} + +var _ StatsReporter = (*reporter)(nil) + +// reporter holds cached metric objects to report source metrics. +type reporter struct { + ctx context.Context +} + +// NewStatsReporter creates a reporter that collects and reports source metrics. +func NewStatsReporter() (StatsReporter, error) { + ctx, err := tag.New( + context.Background(), + ) + if err != nil { + return nil, err + } + return &reporter{ctx: ctx}, nil +} + +func (r *reporter) ReportEventCount(args *ReportArgs, responseCode int) error { + ctx, err := r.generateTag(args, responseCode) + if err != nil { + return err + } + metrics.Record(ctx, eventCountM.M(1)) + return nil +} + +func (r *reporter) ReportRetryEventCount(args *ReportArgs, responseCode int) error { + ctx, err := r.generateTag(args, responseCode) + if err != nil { + return err + } + metrics.Record(ctx, retryEventCountM.M(1)) + return nil +} + +func (r *reporter) generateTag(args *ReportArgs, responseCode int) (context.Context, error) { + return tag.New( + r.ctx, + tag.Insert(namespaceKey, args.Namespace), + tag.Insert(eventSourceKey, args.EventSource), + tag.Insert(eventTypeKey, args.EventType), + tag.Insert(sourceNameKey, args.Name), + tag.Insert(sourceResourceGroupKey, args.ResourceGroup), + metrics.MaybeInsertIntTag(responseCodeKey, responseCode, responseCode > 0), + metrics.MaybeInsertStringTag(responseCodeClassKey, metrics.ResponseCodeClass(responseCode), responseCode > 0), + tag.Insert(responseError, args.Error), + metrics.MaybeInsertBoolTag(responseTimeout, args.Timeout, args.Error != "")) +} + +func register() { + tagKeys := []tag.Key{ + namespaceKey, + eventSourceKey, + eventTypeKey, + sourceNameKey, + sourceResourceGroupKey, + responseCodeKey, + responseCodeClassKey, + responseError, + responseTimeout} + + // Create view to see our measurements. + if err := view.Register( + &view.View{ + Description: eventCountM.Description(), + Measure: eventCountM, + Aggregation: view.Count(), + TagKeys: tagKeys, + }, + &view.View{ + Description: retryEventCountM.Description(), + Measure: retryEventCountM, + Aggregation: view.Count(), + TagKeys: tagKeys, + }, + ); err != nil { + panic(err) + } +} diff --git a/pkg/metrics/source/stats_reporter_test.go b/pkg/metrics/source/stats_reporter_test.go new file mode 100644 index 00000000000..2d9df40f87c --- /dev/null +++ b/pkg/metrics/source/stats_reporter_test.go @@ -0,0 +1,97 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "net/http" + "testing" + + "knative.dev/eventing/pkg/metrics" + "knative.dev/pkg/metrics/metricstest" + _ "knative.dev/pkg/metrics/testing" +) + +func TestStatsReporter(t *testing.T) { + setup() + + args := &ReportArgs{ + Namespace: "testns", + EventType: "dev.knative.event", + EventSource: "unit-test", + Name: "testsource", + ResourceGroup: "testresourcegroup", + } + + r, err := NewStatsReporter() + if err != nil { + t.Fatal("Failed to create a new reporter:", err) + } + + wantTags := map[string]string{ + metrics.LabelNamespaceName: "testns", + metrics.LabelEventType: "dev.knative.event", + metrics.LabelEventSource: "unit-test", + metrics.LabelName: "testsource", + metrics.LabelResourceGroup: "testresourcegroup", + metrics.LabelResponseCode: "202", + metrics.LabelResponseCodeClass: "2xx", + } + + retryWantTags := map[string]string{ + metrics.LabelNamespaceName: "testns", + metrics.LabelEventType: "dev.knative.event", + metrics.LabelEventSource: "unit-test", + metrics.LabelName: "testsource", + metrics.LabelResourceGroup: "testresourcegroup", + metrics.LabelResponseCode: "503", + metrics.LabelResponseCodeClass: "5xx", + } + + // test ReportEventCount and ReportRetryEventCount + expectSuccess(t, func() error { + return r.ReportEventCount(args, http.StatusAccepted) + }) + expectSuccess(t, func() error { + return r.ReportEventCount(args, http.StatusAccepted) + }) + expectSuccess(t, func() error { + return r.ReportRetryEventCount(args, http.StatusServiceUnavailable) + }) + expectSuccess(t, func() error { + return r.ReportRetryEventCount(args, http.StatusServiceUnavailable) + }) + metricstest.CheckCountData(t, "event_count", wantTags, 2) + metricstest.CheckCountData(t, "retry_event_count", retryWantTags, 2) +} + +func expectSuccess(t *testing.T, f func() error) { + t.Helper() + if err := f(); err != nil { + t.Error("Reporter expected success but got error:", err) + } +} + +func setup() { + resetMetrics() +} + +func resetMetrics() { + // OpenCensus metrics carry global state that need to be reset between unit tests. + metricstest.Unregister("event_count") + metricstest.Unregister("retry_event_count") + register() +} From 1ba0af65a7971bdfefab9be21208dc20a320bb59 Mon Sep 17 00:00:00 2001 From: dprotaso Date: Mon, 12 Jul 2021 20:33:14 -0400 Subject: [PATCH 2/3] run update-deps.sh --- vendor/knative.dev/pkg/source/doc.go | 18 -- .../knative.dev/pkg/source/source_labels.go | 29 ---- .../pkg/source/source_stats_reporter.go | 161 ------------------ vendor/modules.txt | 1 - 4 files changed, 209 deletions(-) delete mode 100644 vendor/knative.dev/pkg/source/doc.go delete mode 100644 vendor/knative.dev/pkg/source/source_labels.go delete mode 100644 vendor/knative.dev/pkg/source/source_stats_reporter.go diff --git a/vendor/knative.dev/pkg/source/doc.go b/vendor/knative.dev/pkg/source/doc.go deleted file mode 100644 index fc827c38a21..00000000000 --- a/vendor/knative.dev/pkg/source/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package source holds utilities for Source developers. -package source diff --git a/vendor/knative.dev/pkg/source/source_labels.go b/vendor/knative.dev/pkg/source/source_labels.go deleted file mode 100644 index f40f71275f8..00000000000 --- a/vendor/knative.dev/pkg/source/source_labels.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package source - -const ( - sourceControllerName = "sources.knative.dev/controller" - sourceName = "sources.knative.dev/name" -) - -func Labels(name, controllerAgentName string) map[string]string { - return map[string]string{ - sourceControllerName: controllerAgentName, - sourceName: name, - } -} diff --git a/vendor/knative.dev/pkg/source/source_stats_reporter.go b/vendor/knative.dev/pkg/source/source_stats_reporter.go deleted file mode 100644 index f343d9d75c8..00000000000 --- a/vendor/knative.dev/pkg/source/source_stats_reporter.go +++ /dev/null @@ -1,161 +0,0 @@ -/* -Copyright 2019 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package source - -import ( - "context" - - "go.opencensus.io/stats/view" - "knative.dev/pkg/metrics" - - "go.opencensus.io/stats" - "go.opencensus.io/tag" - "knative.dev/pkg/metrics/metricskey" -) - -var ( - // eventCountM is a counter which records the number of events sent by the source. - eventCountM = stats.Int64( - "event_count", - "Number of events sent", - stats.UnitDimensionless, - ) - - // retryEventCountM is a counter which records the number of events sent by the source in retries. - retryEventCountM = stats.Int64( - "retry_event_count", - "Number of retry events sent", - stats.UnitDimensionless, - ) - // Create the tag keys that will be used to add tags to our measurements. - // Tag keys must conform to the restrictions described in - // go.opencensus.io/tag/validate.go. Currently those restrictions are: - // - length between 1 and 255 inclusive - // - characters are printable US-ASCII - namespaceKey = tag.MustNewKey(metricskey.LabelNamespaceName) - eventSourceKey = tag.MustNewKey(metricskey.LabelEventSource) - eventTypeKey = tag.MustNewKey(metricskey.LabelEventType) - sourceNameKey = tag.MustNewKey(metricskey.LabelName) - sourceResourceGroupKey = tag.MustNewKey(metricskey.LabelResourceGroup) - responseCodeKey = tag.MustNewKey(metricskey.LabelResponseCode) - responseCodeClassKey = tag.MustNewKey(metricskey.LabelResponseCodeClass) - responseError = tag.MustNewKey(metricskey.LabelResponseError) - responseTimeout = tag.MustNewKey(metricskey.LabelResponseTimeout) -) - -// ReportArgs defines the arguments for reporting metrics. -type ReportArgs struct { - Namespace string - EventType string - EventSource string - Name string - ResourceGroup string - Error string - Timeout bool -} - -func init() { - register() -} - -// StatsReporter defines the interface for sending source metrics. -type StatsReporter interface { - // ReportEventCount captures the event count. It records one per call. - ReportEventCount(args *ReportArgs, responseCode int) error - ReportRetryEventCount(args *ReportArgs, responseCode int) error -} - -var _ StatsReporter = (*reporter)(nil) - -// reporter holds cached metric objects to report source metrics. -type reporter struct { - ctx context.Context -} - -// NewStatsReporter creates a reporter that collects and reports source metrics. -func NewStatsReporter() (StatsReporter, error) { - ctx, err := tag.New( - context.Background(), - ) - if err != nil { - return nil, err - } - return &reporter{ctx: ctx}, nil -} - -func (r *reporter) ReportEventCount(args *ReportArgs, responseCode int) error { - ctx, err := r.generateTag(args, responseCode) - if err != nil { - return err - } - metrics.Record(ctx, eventCountM.M(1)) - return nil -} - -func (r *reporter) ReportRetryEventCount(args *ReportArgs, responseCode int) error { - ctx, err := r.generateTag(args, responseCode) - if err != nil { - return err - } - metrics.Record(ctx, retryEventCountM.M(1)) - return nil -} - -func (r *reporter) generateTag(args *ReportArgs, responseCode int) (context.Context, error) { - return tag.New( - r.ctx, - tag.Insert(namespaceKey, args.Namespace), - tag.Insert(eventSourceKey, args.EventSource), - tag.Insert(eventTypeKey, args.EventType), - tag.Insert(sourceNameKey, args.Name), - tag.Insert(sourceResourceGroupKey, args.ResourceGroup), - metrics.MaybeInsertIntTag(responseCodeKey, responseCode, responseCode > 0), - metrics.MaybeInsertStringTag(responseCodeClassKey, metrics.ResponseCodeClass(responseCode), responseCode > 0), - tag.Insert(responseError, args.Error), - metrics.MaybeInsertBoolTag(responseTimeout, args.Timeout, args.Error != "")) -} - -func register() { - tagKeys := []tag.Key{ - namespaceKey, - eventSourceKey, - eventTypeKey, - sourceNameKey, - sourceResourceGroupKey, - responseCodeKey, - responseCodeClassKey, - responseError, - responseTimeout} - - // Create view to see our measurements. - if err := view.Register( - &view.View{ - Description: eventCountM.Description(), - Measure: eventCountM, - Aggregation: view.Count(), - TagKeys: tagKeys, - }, - &view.View{ - Description: retryEventCountM.Description(), - Measure: retryEventCountM, - Aggregation: view.Count(), - TagKeys: tagKeys, - }, - ); err != nil { - panic(err) - } -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1cc975635cd..f72c9344056 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1100,7 +1100,6 @@ knative.dev/pkg/reconciler knative.dev/pkg/reconciler/testing knative.dev/pkg/resolver knative.dev/pkg/signals -knative.dev/pkg/source knative.dev/pkg/system knative.dev/pkg/system/testing knative.dev/pkg/test From 2a9f5e519851ba6ec413b13b9b37eb35714e66cb Mon Sep 17 00:00:00 2001 From: dprotaso Date: Mon, 12 Jul 2021 22:57:02 -0400 Subject: [PATCH 3/3] use type aliases so we can do a non-breaking migration --- pkg/metrics/source/stats_reporter.go | 142 +-------------- pkg/metrics/source/stats_reporter_test.go | 97 ----------- vendor/knative.dev/pkg/source/doc.go | 18 ++ .../knative.dev/pkg/source/source_labels.go | 29 ++++ .../pkg/source/source_stats_reporter.go | 161 ++++++++++++++++++ vendor/modules.txt | 1 + 6 files changed, 213 insertions(+), 235 deletions(-) delete mode 100644 pkg/metrics/source/stats_reporter_test.go create mode 100644 vendor/knative.dev/pkg/source/doc.go create mode 100644 vendor/knative.dev/pkg/source/source_labels.go create mode 100644 vendor/knative.dev/pkg/source/source_stats_reporter.go diff --git a/pkg/metrics/source/stats_reporter.go b/pkg/metrics/source/stats_reporter.go index 68d94e47464..cc4d0fa97cc 100644 --- a/pkg/metrics/source/stats_reporter.go +++ b/pkg/metrics/source/stats_reporter.go @@ -16,145 +16,11 @@ limitations under the License. package source -import ( - "context" +import "knative.dev/pkg/source" - "go.opencensus.io/stats/view" - eventingmetrics "knative.dev/eventing/pkg/metrics" - "knative.dev/pkg/metrics" +type StatsReporter = source.StatsReporter +type ReportArgs = source.ReportArgs - "go.opencensus.io/stats" - "go.opencensus.io/tag" -) - -var ( - // eventCountM is a counter which records the number of events sent by the source. - eventCountM = stats.Int64( - "event_count", - "Number of events sent", - stats.UnitDimensionless, - ) - - // retryEventCountM is a counter which records the number of events sent by the source in retries. - retryEventCountM = stats.Int64( - "retry_event_count", - "Number of retry events sent", - stats.UnitDimensionless, - ) - // Create the tag keys that will be used to add tags to our measurements. - // Tag keys must conform to the restrictions described in - // go.opencensus.io/tag/validate.go. Currently those restrictions are: - // - length between 1 and 255 inclusive - namespaceKey = tag.MustNewKey(eventingmetrics.LabelNamespaceName) - eventSourceKey = tag.MustNewKey(eventingmetrics.LabelEventSource) - eventTypeKey = tag.MustNewKey(eventingmetrics.LabelEventType) - sourceNameKey = tag.MustNewKey(eventingmetrics.LabelName) - sourceResourceGroupKey = tag.MustNewKey(eventingmetrics.LabelResourceGroup) - responseCodeKey = tag.MustNewKey(eventingmetrics.LabelResponseCode) - responseCodeClassKey = tag.MustNewKey(eventingmetrics.LabelResponseCodeClass) - responseError = tag.MustNewKey(eventingmetrics.LabelResponseError) - responseTimeout = tag.MustNewKey(eventingmetrics.LabelResponseTimeout) -) - -// ReportArgs defines the arguments for reporting metrics. -type ReportArgs struct { - Namespace string - EventType string - EventSource string - Name string - ResourceGroup string - Error string - Timeout bool -} - -func init() { - register() -} - -// StatsReporter defines the interface for sending source metrics. -type StatsReporter interface { - // ReportEventCount captures the event count. It records one per call. - ReportEventCount(args *ReportArgs, responseCode int) error - ReportRetryEventCount(args *ReportArgs, responseCode int) error -} - -var _ StatsReporter = (*reporter)(nil) - -// reporter holds cached metric objects to report source metrics. -type reporter struct { - ctx context.Context -} - -// NewStatsReporter creates a reporter that collects and reports source metrics. func NewStatsReporter() (StatsReporter, error) { - ctx, err := tag.New( - context.Background(), - ) - if err != nil { - return nil, err - } - return &reporter{ctx: ctx}, nil -} - -func (r *reporter) ReportEventCount(args *ReportArgs, responseCode int) error { - ctx, err := r.generateTag(args, responseCode) - if err != nil { - return err - } - metrics.Record(ctx, eventCountM.M(1)) - return nil -} - -func (r *reporter) ReportRetryEventCount(args *ReportArgs, responseCode int) error { - ctx, err := r.generateTag(args, responseCode) - if err != nil { - return err - } - metrics.Record(ctx, retryEventCountM.M(1)) - return nil -} - -func (r *reporter) generateTag(args *ReportArgs, responseCode int) (context.Context, error) { - return tag.New( - r.ctx, - tag.Insert(namespaceKey, args.Namespace), - tag.Insert(eventSourceKey, args.EventSource), - tag.Insert(eventTypeKey, args.EventType), - tag.Insert(sourceNameKey, args.Name), - tag.Insert(sourceResourceGroupKey, args.ResourceGroup), - metrics.MaybeInsertIntTag(responseCodeKey, responseCode, responseCode > 0), - metrics.MaybeInsertStringTag(responseCodeClassKey, metrics.ResponseCodeClass(responseCode), responseCode > 0), - tag.Insert(responseError, args.Error), - metrics.MaybeInsertBoolTag(responseTimeout, args.Timeout, args.Error != "")) -} - -func register() { - tagKeys := []tag.Key{ - namespaceKey, - eventSourceKey, - eventTypeKey, - sourceNameKey, - sourceResourceGroupKey, - responseCodeKey, - responseCodeClassKey, - responseError, - responseTimeout} - - // Create view to see our measurements. - if err := view.Register( - &view.View{ - Description: eventCountM.Description(), - Measure: eventCountM, - Aggregation: view.Count(), - TagKeys: tagKeys, - }, - &view.View{ - Description: retryEventCountM.Description(), - Measure: retryEventCountM, - Aggregation: view.Count(), - TagKeys: tagKeys, - }, - ); err != nil { - panic(err) - } + return source.NewStatsReporter() } diff --git a/pkg/metrics/source/stats_reporter_test.go b/pkg/metrics/source/stats_reporter_test.go deleted file mode 100644 index 2d9df40f87c..00000000000 --- a/pkg/metrics/source/stats_reporter_test.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2021 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package source - -import ( - "net/http" - "testing" - - "knative.dev/eventing/pkg/metrics" - "knative.dev/pkg/metrics/metricstest" - _ "knative.dev/pkg/metrics/testing" -) - -func TestStatsReporter(t *testing.T) { - setup() - - args := &ReportArgs{ - Namespace: "testns", - EventType: "dev.knative.event", - EventSource: "unit-test", - Name: "testsource", - ResourceGroup: "testresourcegroup", - } - - r, err := NewStatsReporter() - if err != nil { - t.Fatal("Failed to create a new reporter:", err) - } - - wantTags := map[string]string{ - metrics.LabelNamespaceName: "testns", - metrics.LabelEventType: "dev.knative.event", - metrics.LabelEventSource: "unit-test", - metrics.LabelName: "testsource", - metrics.LabelResourceGroup: "testresourcegroup", - metrics.LabelResponseCode: "202", - metrics.LabelResponseCodeClass: "2xx", - } - - retryWantTags := map[string]string{ - metrics.LabelNamespaceName: "testns", - metrics.LabelEventType: "dev.knative.event", - metrics.LabelEventSource: "unit-test", - metrics.LabelName: "testsource", - metrics.LabelResourceGroup: "testresourcegroup", - metrics.LabelResponseCode: "503", - metrics.LabelResponseCodeClass: "5xx", - } - - // test ReportEventCount and ReportRetryEventCount - expectSuccess(t, func() error { - return r.ReportEventCount(args, http.StatusAccepted) - }) - expectSuccess(t, func() error { - return r.ReportEventCount(args, http.StatusAccepted) - }) - expectSuccess(t, func() error { - return r.ReportRetryEventCount(args, http.StatusServiceUnavailable) - }) - expectSuccess(t, func() error { - return r.ReportRetryEventCount(args, http.StatusServiceUnavailable) - }) - metricstest.CheckCountData(t, "event_count", wantTags, 2) - metricstest.CheckCountData(t, "retry_event_count", retryWantTags, 2) -} - -func expectSuccess(t *testing.T, f func() error) { - t.Helper() - if err := f(); err != nil { - t.Error("Reporter expected success but got error:", err) - } -} - -func setup() { - resetMetrics() -} - -func resetMetrics() { - // OpenCensus metrics carry global state that need to be reset between unit tests. - metricstest.Unregister("event_count") - metricstest.Unregister("retry_event_count") - register() -} diff --git a/vendor/knative.dev/pkg/source/doc.go b/vendor/knative.dev/pkg/source/doc.go new file mode 100644 index 00000000000..fc827c38a21 --- /dev/null +++ b/vendor/knative.dev/pkg/source/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package source holds utilities for Source developers. +package source diff --git a/vendor/knative.dev/pkg/source/source_labels.go b/vendor/knative.dev/pkg/source/source_labels.go new file mode 100644 index 00000000000..f40f71275f8 --- /dev/null +++ b/vendor/knative.dev/pkg/source/source_labels.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +const ( + sourceControllerName = "sources.knative.dev/controller" + sourceName = "sources.knative.dev/name" +) + +func Labels(name, controllerAgentName string) map[string]string { + return map[string]string{ + sourceControllerName: controllerAgentName, + sourceName: name, + } +} diff --git a/vendor/knative.dev/pkg/source/source_stats_reporter.go b/vendor/knative.dev/pkg/source/source_stats_reporter.go new file mode 100644 index 00000000000..f343d9d75c8 --- /dev/null +++ b/vendor/knative.dev/pkg/source/source_stats_reporter.go @@ -0,0 +1,161 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "context" + + "go.opencensus.io/stats/view" + "knative.dev/pkg/metrics" + + "go.opencensus.io/stats" + "go.opencensus.io/tag" + "knative.dev/pkg/metrics/metricskey" +) + +var ( + // eventCountM is a counter which records the number of events sent by the source. + eventCountM = stats.Int64( + "event_count", + "Number of events sent", + stats.UnitDimensionless, + ) + + // retryEventCountM is a counter which records the number of events sent by the source in retries. + retryEventCountM = stats.Int64( + "retry_event_count", + "Number of retry events sent", + stats.UnitDimensionless, + ) + // Create the tag keys that will be used to add tags to our measurements. + // Tag keys must conform to the restrictions described in + // go.opencensus.io/tag/validate.go. Currently those restrictions are: + // - length between 1 and 255 inclusive + // - characters are printable US-ASCII + namespaceKey = tag.MustNewKey(metricskey.LabelNamespaceName) + eventSourceKey = tag.MustNewKey(metricskey.LabelEventSource) + eventTypeKey = tag.MustNewKey(metricskey.LabelEventType) + sourceNameKey = tag.MustNewKey(metricskey.LabelName) + sourceResourceGroupKey = tag.MustNewKey(metricskey.LabelResourceGroup) + responseCodeKey = tag.MustNewKey(metricskey.LabelResponseCode) + responseCodeClassKey = tag.MustNewKey(metricskey.LabelResponseCodeClass) + responseError = tag.MustNewKey(metricskey.LabelResponseError) + responseTimeout = tag.MustNewKey(metricskey.LabelResponseTimeout) +) + +// ReportArgs defines the arguments for reporting metrics. +type ReportArgs struct { + Namespace string + EventType string + EventSource string + Name string + ResourceGroup string + Error string + Timeout bool +} + +func init() { + register() +} + +// StatsReporter defines the interface for sending source metrics. +type StatsReporter interface { + // ReportEventCount captures the event count. It records one per call. + ReportEventCount(args *ReportArgs, responseCode int) error + ReportRetryEventCount(args *ReportArgs, responseCode int) error +} + +var _ StatsReporter = (*reporter)(nil) + +// reporter holds cached metric objects to report source metrics. +type reporter struct { + ctx context.Context +} + +// NewStatsReporter creates a reporter that collects and reports source metrics. +func NewStatsReporter() (StatsReporter, error) { + ctx, err := tag.New( + context.Background(), + ) + if err != nil { + return nil, err + } + return &reporter{ctx: ctx}, nil +} + +func (r *reporter) ReportEventCount(args *ReportArgs, responseCode int) error { + ctx, err := r.generateTag(args, responseCode) + if err != nil { + return err + } + metrics.Record(ctx, eventCountM.M(1)) + return nil +} + +func (r *reporter) ReportRetryEventCount(args *ReportArgs, responseCode int) error { + ctx, err := r.generateTag(args, responseCode) + if err != nil { + return err + } + metrics.Record(ctx, retryEventCountM.M(1)) + return nil +} + +func (r *reporter) generateTag(args *ReportArgs, responseCode int) (context.Context, error) { + return tag.New( + r.ctx, + tag.Insert(namespaceKey, args.Namespace), + tag.Insert(eventSourceKey, args.EventSource), + tag.Insert(eventTypeKey, args.EventType), + tag.Insert(sourceNameKey, args.Name), + tag.Insert(sourceResourceGroupKey, args.ResourceGroup), + metrics.MaybeInsertIntTag(responseCodeKey, responseCode, responseCode > 0), + metrics.MaybeInsertStringTag(responseCodeClassKey, metrics.ResponseCodeClass(responseCode), responseCode > 0), + tag.Insert(responseError, args.Error), + metrics.MaybeInsertBoolTag(responseTimeout, args.Timeout, args.Error != "")) +} + +func register() { + tagKeys := []tag.Key{ + namespaceKey, + eventSourceKey, + eventTypeKey, + sourceNameKey, + sourceResourceGroupKey, + responseCodeKey, + responseCodeClassKey, + responseError, + responseTimeout} + + // Create view to see our measurements. + if err := view.Register( + &view.View{ + Description: eventCountM.Description(), + Measure: eventCountM, + Aggregation: view.Count(), + TagKeys: tagKeys, + }, + &view.View{ + Description: retryEventCountM.Description(), + Measure: retryEventCountM, + Aggregation: view.Count(), + TagKeys: tagKeys, + }, + ); err != nil { + panic(err) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index f72c9344056..1cc975635cd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1100,6 +1100,7 @@ knative.dev/pkg/reconciler knative.dev/pkg/reconciler/testing knative.dev/pkg/resolver knative.dev/pkg/signals +knative.dev/pkg/source knative.dev/pkg/system knative.dev/pkg/system/testing knative.dev/pkg/test