Skip to content

Commit

Permalink
chore: add gw failure stats (#3809)
Browse files Browse the repository at this point in the history
Add stats for failures at GW
  • Loading branch information
cisse21 committed Sep 1, 2023
1 parent fdfb4f6 commit 437b8d5
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 30 deletions.
4 changes: 2 additions & 2 deletions gateway/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ var _ = Describe("Gateway", func() {
"workspaceId": "",
"writeKey": "noWriteKey",
"reqType": reqType,
"reason": "noWriteKeyInBasicAuth",
"reason": "Failed to read writeKey from header",
"sourceType": "",
"sdkVersion": "",
},
Expand Down Expand Up @@ -935,7 +935,7 @@ var _ = Describe("Gateway", func() {
"workspaceId": "",
"writeKey": "noWriteKey",
"reqType": reqType,
"reason": "noWriteKeyInBasicAuth",
"reason": "Failed to read writeKey from header",
"sourceType": "",
"sdkVersion": "",
},
Expand Down
90 changes: 63 additions & 27 deletions gateway/handle_http_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,26 @@ func (gw *Handle) writeKeyAuth(delegate http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
reqType := r.Context().Value(gwtypes.CtxParamCallType).(string)
var errorMessage string
var arctx *gwtypes.AuthRequestContext
defer func() {
gw.handleHttpError(w, r, errorMessage)
gw.handleFailureStats(errorMessage, reqType, arctx)
}()
writeKey, _, ok := r.BasicAuth()
if !ok || writeKey == "" {
stat := gwstats.SourceStat{
Source: "noWriteKey",
SourceID: "noWriteKey",
WriteKey: "noWriteKey",
ReqType: reqType,
}
stat.RequestFailed("noWriteKeyInBasicAuth")
stat.Report(gw.stats)
errorMessage = response.NoWriteKeyInBasicAuth
return
}
arctx := gw.authRequestContextForWriteKey(writeKey)
arctx = gw.authRequestContextForWriteKey(writeKey)
if arctx == nil {
stat := gwstats.SourceStat{
Source: "invalidWriteKey",
SourceID: "invalidWriteKey",
WriteKey: writeKey,
ReqType: reqType,
}
stat.RequestFailed("invalidWriteKey")
stat.Report(gw.stats)
errorMessage = response.InvalidWriteKey
return
}
Expand All @@ -55,9 +57,11 @@ func (gw *Handle) writeKeyAuth(delegate http.HandlerFunc) http.HandlerFunc {
func (gw *Handle) webhookAuth(delegate http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
reqType := r.Context().Value(gwtypes.CtxParamCallType).(string)
var arctx *gwtypes.AuthRequestContext
var errorMessage string
defer func() {
gw.handleHttpError(w, r, errorMessage)
gw.handleFailureStats(errorMessage, reqType, arctx)
}()

var writeKey string
Expand All @@ -67,18 +71,10 @@ func (gw *Handle) webhookAuth(delegate http.HandlerFunc) http.HandlerFunc {
writeKey, _, _ = r.BasicAuth()
}
if writeKey == "" {
stat := gwstats.SourceStat{
Source: "noWriteKey",
SourceID: "noWriteKey",
WriteKey: "noWriteKey",
ReqType: reqType,
}
stat.RequestFailed("noWriteKeyInQueryParams")
stat.Report(gw.stats)
errorMessage = response.NoWriteKeyInQueryParams
return
}
arctx := gw.authRequestContextForWriteKey(writeKey)
arctx = gw.authRequestContextForWriteKey(writeKey)
if arctx == nil || arctx.SourceCategory != "webhook" {
errorMessage = response.InvalidWriteKey
return
Expand All @@ -99,23 +95,17 @@ func (gw *Handle) sourceIDAuth(delegate http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
reqType := r.Context().Value(gwtypes.CtxParamCallType).(string)
var errorMessage string
var arctx *gwtypes.AuthRequestContext
defer func() {
gw.handleHttpError(w, r, errorMessage)
gw.handleFailureStats(errorMessage, reqType, arctx)
}()
sourceID := r.Header.Get("X-Rudder-Source-Id")
if sourceID == "" {
stat := gwstats.SourceStat{
Source: "noSourceID",
SourceID: "noSourceID",
WriteKey: "noSourceID",
ReqType: reqType,
}
stat.RequestFailed("noSourceIdInHeader")
stat.Report(gw.stats)
errorMessage = response.NoSourceIdInHeader
return
}
arctx := gw.authRequestContextForSourceID(sourceID)
arctx = gw.authRequestContextForSourceID(sourceID)
if arctx == nil {
errorMessage = response.InvalidSourceID
return
Expand All @@ -138,6 +128,7 @@ func (gw *Handle) replaySourceIDAuth(delegate http.HandlerFunc) http.HandlerFunc
s, ok := gw.sourceIDSourceMap[arctx.SourceID]
if !ok || !s.IsReplaySource() {
gw.handleHttpError(w, r, response.InvalidReplaySource)
gw.handleFailureStats(response.InvalidReplaySource, "replay", arctx)
return
}
delegate.ServeHTTP(w, r)
Expand Down Expand Up @@ -200,3 +191,48 @@ func (gw *Handle) handleHttpError(w http.ResponseWriter, r *http.Request, errorM
http.Error(w, responseBody, status)
}
}

func (gw *Handle) handleFailureStats(errorMessage, reqType string, arctx *gwtypes.AuthRequestContext) {
if errorMessage != "" {
var stat gwstats.SourceStat
switch errorMessage {
case response.NoWriteKeyInBasicAuth, response.NoWriteKeyInQueryParams:
stat = gwstats.SourceStat{
Source: "noWriteKey",
SourceID: "noWriteKey",
WriteKey: "noWriteKey",
ReqType: reqType,
}
case response.InvalidWriteKey:
stat = gwstats.SourceStat{
Source: "noWriteKey",
SourceID: "noWriteKey",
WriteKey: "noWriteKey",
ReqType: reqType,
}
case response.InvalidSourceID:
stat = gwstats.SourceStat{
SourceID: "InvalidSourceId",
WriteKey: "InvalidSourceId",
ReqType: reqType,
Source: "InvalidSourceId",
}
case response.NoSourceIdInHeader:
stat = gwstats.SourceStat{
SourceID: "noSourceIDInHeader",
WriteKey: "noSourceIDInHeader",
ReqType: reqType,
Source: "noSourceIDInHeader",
}
case response.SourceDisabled:
stat = gwstats.SourceStat{
SourceID: arctx.SourceID,
WriteKey: arctx.WriteKey,
ReqType: reqType,
Source: arctx.SourceTag(),
}
}
stat.RequestFailed(response.GetStatus(errorMessage))
stat.Report(gw.stats)
}
}
9 changes: 9 additions & 0 deletions gateway/handle_http_beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gateway
import (
"net/http"

gwstats "github.com/rudderlabs/rudder-server/gateway/internal/stats"
"github.com/rudderlabs/rudder-server/gateway/response"
"github.com/rudderlabs/rudder-server/utils/misc"
)
Expand All @@ -25,6 +26,14 @@ func (gw *Handle) beaconInterceptor(delegate http.HandlerFunc) http.HandlerFunc
} else {
status := http.StatusUnauthorized
responseBody := response.NoWriteKeyInQueryParams
stat := gwstats.SourceStat{
Source: "invalidWriteKey",
SourceID: "invalidWriteKey",
WriteKey: "invalidWriteKey",
ReqType: "beacon",
}
stat.RequestFailed("invalidWriteKey")
stat.Report(gw.stats)
gw.logger.Infow("response",
"ip", misc.GetIPFromReq(r),
"path", r.URL.Path,
Expand Down
10 changes: 10 additions & 0 deletions gateway/handle_http_pixel.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

"github.com/tidwall/sjson"

gwstats "github.com/rudderlabs/rudder-server/gateway/internal/stats"

"github.com/rudderlabs/rudder-server/gateway/response"
"github.com/rudderlabs/rudder-server/utils/misc"
)
Expand Down Expand Up @@ -67,6 +69,14 @@ func (gw *Handle) pixelInterceptor(reqType string, next http.HandlerFunc) http.H
}
}
} else {
stat := gwstats.SourceStat{
Source: "NoWriteKeyInQueryParams",
SourceID: "NoWriteKeyInQueryParams",
WriteKey: "NoWriteKeyInQueryParams",
ReqType: reqType,
}
stat.RequestFailed("NoWriteKeyInQueryParams")
stat.Report(gw.stats)
gw.logger.Infow("Error while handling request",
"ip", misc.GetIPFromReq(r),
"path", r.URL.Path,
Expand Down
1 change: 0 additions & 1 deletion gateway/internal/stats/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ func (ss *SourceStat) Report(s stats.Stats) {
if ss.reason != "" {
failedTags["reason"] = ss.reason
}

s.NewTaggedStat("gateway.write_key_requests", stats.CountType, tags).Count(ss.requests.total)
s.NewTaggedStat("gateway.write_key_successful_requests", stats.CountType, tags).Count(ss.requests.succeeded)
s.NewTaggedStat("gateway.write_key_failed_requests", stats.CountType, failedTags).Count(ss.requests.failed)
Expand Down

0 comments on commit 437b8d5

Please sign in to comment.