// Copyright 2018 Google Inc. All Rights Reserved. // // 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. // +build go1.8 package pubsub import ( "log" "sync" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" "golang.org/x/net/context" "google.golang.org/api/option" "google.golang.org/grpc" ) func openCensusOptions() []option.ClientOption { return []option.ClientOption{ option.WithGRPCDialOption(grpc.WithStatsHandler(&ocgrpc.ClientHandler{})), } } var subscriptionKey tag.Key func init() { var err error if subscriptionKey, err = tag.NewKey("subscription"); err != nil { log.Fatal("cannot create 'subscription' key") } } var ( // PullCount is a measure of the number of messages pulled. // It is EXPERIMENTAL and subject to change or removal without notice. PullCount *stats.Int64Measure // AckCount is a measure of the number of messages acked. // It is EXPERIMENTAL and subject to change or removal without notice. AckCount *stats.Int64Measure // NackCount is a measure of the number of messages nacked. // It is EXPERIMENTAL and subject to change or removal without notice. NackCount *stats.Int64Measure // ModAckCount is a measure of the number of messages whose ack-deadline was modified. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckCount *stats.Int64Measure // StreamOpenCount is a measure of the number of times a streaming-pull stream was opened. // It is EXPERIMENTAL and subject to change or removal without notice. StreamOpenCount *stats.Int64Measure // StreamRetryCount is a measure of the number of times a streaming-pull operation was retried. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRetryCount *stats.Int64Measure // StreamRequestCount is a measure of the number of requests sent on a streaming-pull stream. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRequestCount *stats.Int64Measure // StreamRequestCount is a measure of the number of responses received on a streaming-pull stream. // It is EXPERIMENTAL and subject to change or removal without notice. StreamResponseCount *stats.Int64Measure // PullCountView is a cumulative sum of PullCount. // It is EXPERIMENTAL and subject to change or removal without notice. PullCountView *view.View // AckCountView is a cumulative sum of AckCount. // It is EXPERIMENTAL and subject to change or removal without notice. AckCountView *view.View // NackCountView is a cumulative sum of NackCount. // It is EXPERIMENTAL and subject to change or removal without notice. NackCountView *view.View // ModAckCountView is a cumulative sum of ModAckCount. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckCountView *view.View // StreamOpenCountView is a cumulative sum of StreamOpenCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamOpenCountView *view.View // StreamRetryCountView is a cumulative sum of StreamRetryCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRetryCountView *view.View // StreamRequestCountView is a cumulative sum of StreamRequestCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRequestCountView *view.View // StreamResponseCountView is a cumulative sum of StreamResponseCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamResponseCountView *view.View ) const statsPrefix = "cloud.google.com/go/pubsub/" func init() { PullCount = mustNewMeasure("pull_count", "Number of PubSub messages pulled") AckCount = mustNewMeasure("ack_count", "Number of PubSub messages acked") NackCount = mustNewMeasure("nack_count", "Number of PubSub messages nacked") ModAckCount = mustNewMeasure("mod_ack_count", "Number of ack-deadlines modified") StreamOpenCount = mustNewMeasure("stream_open_count", "Number of calls opening a new streaming pull") StreamRetryCount = mustNewMeasure("stream_retry_count", "Number of retries of a stream send or receive") StreamRequestCount = mustNewMeasure("stream_request_count", "Number gRPC StreamingPull request messages sent") StreamResponseCount = mustNewMeasure("stream_response_count", "Number of gRPC StreamingPull response messages received") PullCountView = mustNewView(PullCount) AckCountView = mustNewView(AckCount) NackCountView = mustNewView(NackCount) ModAckCountView = mustNewView(ModAckCount) StreamOpenCountView = mustNewView(StreamOpenCount) StreamRetryCountView = mustNewView(StreamRetryCount) StreamRequestCountView = mustNewView(StreamRequestCount) StreamResponseCountView = mustNewView(StreamResponseCount) } func mustNewMeasure(name, desc string) *stats.Int64Measure { const unitCount = "1" name = statsPrefix + name m, err := stats.Int64(name, desc, unitCount) if err != nil { log.Fatalf("creating %q: %v", name, err) } return m } func mustNewView(m *stats.Int64Measure) *view.View { v, err := view.New(m.Name(), "cumulative "+m.Description(), []tag.Key{subscriptionKey}, m, view.Sum()) if err != nil { log.Fatalf("creating view for %q: %v", m.Name(), err) } return v } var logOnce sync.Once func withSubscriptionKey(ctx context.Context, subName string) context.Context { ctx, err := tag.New(ctx, tag.Upsert(subscriptionKey, subName)) if err != nil { logOnce.Do(func() { log.Printf("pubsub: error creating tag map: %v", err) }) } return ctx } func recordStat(ctx context.Context, m *stats.Int64Measure, n int64) { stats.Record(ctx, m.M(n)) }