Skip to content

Commit

Permalink
capture metrics for put requests only
Browse files Browse the repository at this point in the history
  • Loading branch information
katherinelc321 committed May 23, 2024
1 parent b7ea4f1 commit d306510
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
11 changes: 10 additions & 1 deletion frontend/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Frontend struct {
ready atomic.Value
done chan struct{}
metrics metrics.Emitter
region string
}

// MuxPattern forms a URL pattern suitable for passing to http.ServeMux.
Expand All @@ -67,9 +68,10 @@ func NewFrontend(logger *slog.Logger, listener net.Listener, emitter metrics.Emi
cache: *NewCache(),
dbClient: *dbClient,
done: make(chan struct{}),
region: region,
}

subscriptionStateMuxValidator := NewSubscriptionStateMuxValidator(&f.cache, emitter, region)
subscriptionStateMuxValidator := NewSubscriptionStateMuxValidator(&f.cache)

// Setup metrics middleware
metricsMiddleware := MetricsMiddleware{Emitter: emitter}
Expand Down Expand Up @@ -432,6 +434,13 @@ func (f *Frontend) ArmSubscriptionAction(writer http.ResponseWriter, request *ht
subId := request.PathValue(PathSegmentSubscriptionID)
f.cache.SetSubscription(subId, &subscription)

// Emit the subscription state metric
f.metrics.EmitGauge("subscription_lifecycle", 1, map[string]string{
"region": f.region,
"subscriptionid": subId,
"state": string(subscription.State),
})

resp, err := json.Marshal(subscription)
if err != nil {
f.logger.Error(err.Error())
Expand Down
24 changes: 24 additions & 0 deletions frontend/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/maps"

"github.com/Azure/ARO-HCP/internal/api/arm"
"github.com/Azure/ARO-HCP/internal/metrics"
)

Expand Down Expand Up @@ -50,6 +51,7 @@ func (pe *PrometheusEmitter) EmitCounter(name string, value float64, labels map[

type MetricsMiddleware struct {
metrics.Emitter
cache *Cache
}

type logResponseWriter struct {
Expand All @@ -76,12 +78,34 @@ func (mm MetricsMiddleware) Metrics() MiddlewareFunc {
routePattern := r.URL.Path
duration := time.Since(startTime).Milliseconds()

subscriptionId := r.PathValue(PathSegmentSubscriptionID)
if subscriptionId == "" {
arm.WriteError(
w, http.StatusBadRequest,
arm.CloudErrorCodeInvalidParameter, "",
SubscriptionMissingMessage,
PathSegmentSubscriptionID)
return
}

sub, exists := mm.cache.GetSubscription(subscriptionId)

if !exists {
arm.WriteError(
w, http.StatusBadRequest,
arm.CloudErrorInvalidSubscriptionState, "",
UnregisteredSubscriptionStateMessage,
subscriptionId)
return
}

// Emit metrics
mm.Emitter.EmitCounter("frontend_count", 1.0, map[string]string{
"verb": r.Method,
"api_version": r.URL.Query().Get(APIVersionKey),
"code": strconv.Itoa(lrw.statusCode),
"route": routePattern,
"state": string(sub.State),
})

mm.Emitter.EmitGauge("frontend_duration", float64(duration), map[string]string{
Expand Down
18 changes: 3 additions & 15 deletions frontend/middleware_validatesubscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"net/http"

"github.com/Azure/ARO-HCP/internal/api/arm"
"github.com/Azure/ARO-HCP/internal/metrics"
)

const (
Expand All @@ -17,16 +16,12 @@ const (
)

type SubscriptionStateMuxValidator struct {
cache *Cache
metrics metrics.Emitter
region string
cache *Cache
}

func NewSubscriptionStateMuxValidator(c *Cache, emitter metrics.Emitter, region string) *SubscriptionStateMuxValidator {
func NewSubscriptionStateMuxValidator(c *Cache) *SubscriptionStateMuxValidator {
return &SubscriptionStateMuxValidator{
cache: c,
metrics: emitter,
region: region,
cache: c,
}
}

Expand Down Expand Up @@ -54,13 +49,6 @@ func (s *SubscriptionStateMuxValidator) MiddlewareValidateSubscriptionState(w ht
return
}

// Emit the subscription state metric
s.metrics.EmitGauge("subscription_lifecycle", 1, map[string]string{
"region": s.region,
"subscriptionid": subscriptionId,
"state": string(sub.State),
})

// the subscription exists, store its current state as context
ctx := ContextWithSubscriptionState(r.Context(), sub.State)
r = r.WithContext(ctx)
Expand Down
18 changes: 1 addition & 17 deletions frontend/middleware_validatesubscription_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,13 @@ import (
"github.com/google/go-cmp/cmp"

"github.com/Azure/ARO-HCP/internal/api/arm"
"github.com/Azure/ARO-HCP/internal/metrics"
)

type MockEmitter struct{}

func (m *MockEmitter) EmitGauge(metric string, value float64, labels map[string]string) {
// No-op for testing
}

func (m *MockEmitter) EmitCounter(metric string, value float64, labels map[string]string) {
// No-op for testing
}

func NewMockEmitter() metrics.Emitter {
return &MockEmitter{}
}
func TestMiddlewareValidateSubscription(t *testing.T) {
subscriptionId := "1234-5678"
region := "eastus"
defaultRequestPath := fmt.Sprintf("subscriptions/%s/resourceGroups/xyz", subscriptionId)
cache := NewCache()
mockEmitter := NewMockEmitter()
middleware := NewSubscriptionStateMuxValidator(cache, mockEmitter, region)
middleware := NewSubscriptionStateMuxValidator(cache)

tests := []struct {
name string
Expand Down

0 comments on commit d306510

Please sign in to comment.