Skip to content

Commit

Permalink
fix(server): add context event properties (#3429)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgeepc committed Dec 8, 2023
1 parent f59ab68 commit 6d6143a
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 67 deletions.
39 changes: 1 addition & 38 deletions server/app/app.go
Expand Up @@ -7,7 +7,6 @@ import (
"log"
"net/http"
"os"
"regexp"

"github.com/gorilla/handlers"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -329,7 +328,7 @@ func (app *App) Start(opts ...appOption) error {
router.Use(middleware.NewMetricMiddleware(meter))

// use the analytics middleware on complete router
router.Use(analyticsMW)
router.Use(middleware.AnalyticsMiddleware)

// use the tenant middleware on complete router
router.Use(middleware.TenantMiddleware)
Expand Down Expand Up @@ -372,42 +371,6 @@ func (app *App) Start(opts ...appOption) error {
return nil
}

var (
matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
matchResourceName = regexp.MustCompile(`(\w)(\.)(\w)`)
)

func toWords(str string) string {
if matchResourceName.MatchString(str) {
return str
}
words := matchFirstCap.ReplaceAllString(str, "${1} ${2}")
words = matchAllCap.ReplaceAllString(words, "${1} ${2}")
return words
}

// Analytics global middleware
func analyticsMW(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
routeName := mux.CurrentRoute(r).GetName()
machineID := r.Header.Get("x-client-id")
source := r.Header.Get("x-source")
eventProperties := r.Header.Get("x-event-properties")

eventData := map[string]string{
"source": source,
}
eventData = analytics.InjectProperties(eventData, eventProperties)

if routeName != "" {
analytics.SendEvent(toWords(routeName), "test", machineID, &eventData)
}

next.ServeHTTP(w, r)
})
}

func registerSPAHandler(router *mux.Router, cfg httpServerConfig, analyticsEnabled bool, serverID string, isTracetestDev bool) {
router.
PathPrefix(cfg.ServerPathPrefix()).
Expand Down
11 changes: 2 additions & 9 deletions server/executor/assertion_runner.go
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"log"

"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/expression"
"github.com/kubeshop/tracetest/server/http/middleware"
"github.com/kubeshop/tracetest/server/model/events"
Expand Down Expand Up @@ -79,10 +78,7 @@ func (e *defaultAssertionRunner) runAssertionsAndUpdateResult(ctx context.Contex
}

run = run.AssertionFailed(err)
analytics.SendEvent("test_run_finished", "error", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "error", "", map[string]string{"finalState": string(run.State)}, ctx)

return test.Run{}, e.updater.Update(ctx, run)
}
Expand Down Expand Up @@ -139,10 +135,7 @@ func (e *defaultAssertionRunner) executeAssertions(ctx context.Context, req Job)
allPassed,
)

analytics.SendEvent("test_run_finished", "successful", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "successful", "", map[string]string{"finalState": string(run.State)}, ctx)

return run, nil
}
Expand Down
6 changes: 1 addition & 5 deletions server/executor/linter_runner.go
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"log"

"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/http/middleware"
"github.com/kubeshop/tracetest/server/linter"
"github.com/kubeshop/tracetest/server/linter/analyzer"
Expand Down Expand Up @@ -130,10 +129,7 @@ func (e *defaultLinterRunner) onError(ctx context.Context, job Job, run test.Run
log.Printf("[linterRunner] Test %s Run %d: fail to emit TracelinterError event: %s\n", job.Test.ID, job.Run.ID, anotherErr.Error())
}

analytics.SendEvent("test_run_finished", "error", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "error", "", map[string]string{"finalState": string(run.State)}, ctx)

run = run.LinterError(err)
return run, e.updater.Update(ctx, run)
Expand Down
10 changes: 10 additions & 0 deletions server/executor/queue.go
Expand Up @@ -515,6 +515,11 @@ func (b tenantPropagator) Inject(ctx context.Context, carrier propagation.TextMa
if instanceID != nil {
carrier.Set("instanceID", instanceID.(string))
}

eventProperties := middleware.EventPropertiesFromContext(ctx)
if eventProperties != "" {
carrier.Set(string(middleware.EventPropertiesKey), eventProperties)
}
}

// Extract returns a copy of parent with the baggage from the carrier added.
Expand All @@ -531,6 +536,11 @@ func (b tenantPropagator) Extract(parent context.Context, carrier propagation.Te
resultingCtx = context.WithValue(resultingCtx, "instanceID", instanceID)
}

eventProperties := carrier.Get(string(middleware.EventPropertiesKey))
if eventProperties != "" {
resultingCtx = context.WithValue(resultingCtx, middleware.EventPropertiesKey, eventProperties)
}

return resultingCtx

}
Expand Down
6 changes: 1 addition & 5 deletions server/executor/trace_poller.go
Expand Up @@ -7,7 +7,6 @@ import (
"log"
"time"

"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/executor/pollingprofile"
"github.com/kubeshop/tracetest/server/http/middleware"
"github.com/kubeshop/tracetest/server/model/events"
Expand Down Expand Up @@ -203,10 +202,7 @@ func (tp tracePoller) handleTraceDBError(ctx context.Context, job Job, err error
}

run = run.TraceFailed(err)
analytics.SendEvent("test_run_finished", "error", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "error", "", map[string]string{"finalState": string(run.State)}, ctx)

tp.handleDBError(tp.updater.Update(ctx, run))

Expand Down
6 changes: 1 addition & 5 deletions server/executor/tracepollerworker/evaluator_worker.go
Expand Up @@ -7,7 +7,6 @@ import (
"log"
"time"

"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/datastore"
"github.com/kubeshop/tracetest/server/executor"
"github.com/kubeshop/tracetest/server/http/middleware"
Expand Down Expand Up @@ -103,10 +102,7 @@ func (w *tracePollerEvaluatorWorker) ProcessItem(ctx context.Context, job execut
populateSpan(span, job, reason, &successful)

run := job.Run.TraceFailed(err)
analytics.SendEvent("test_run_finished", "error", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "error", "", map[string]string{"finalState": string(run.State)}, ctx)

handleDBError(w.state.updater.Update(ctx, run))

Expand Down
6 changes: 1 addition & 5 deletions server/executor/trigger_result_processor_worker.go
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"

"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/http/middleware"
"github.com/kubeshop/tracetest/server/model"
"github.com/kubeshop/tracetest/server/model/events"
Expand Down Expand Up @@ -128,10 +127,7 @@ func (r triggerResultProcessorWorker) handleExecutionResult(run test.Run, ctx co
if run.TriggerResult.Error != nil {
run = run.TriggerFailed(fmt.Errorf(run.TriggerResult.Error.ErrorMessage))

analytics.SendEvent("test_run_finished", "error", "", &map[string]string{
"finalState": string(run.State),
"tenant_id": middleware.TenantIDFromContext(ctx),
})
middleware.SendEventWithProperties("test_run_finished", "error", "", map[string]string{"finalState": string(run.State)}, ctx)

return run
}
Expand Down
64 changes: 64 additions & 0 deletions server/http/middleware/analytics.go
@@ -0,0 +1,64 @@
package middleware

import (
"context"
"net/http"
"regexp"

"github.com/gorilla/mux"
"github.com/kubeshop/tracetest/server/analytics"
)

var (
matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
matchResourceName = regexp.MustCompile(`(\w)(\.)(\w)`)
)

const EventPropertiesKey key = "x-event-properties"

func AnalyticsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
routeName := mux.CurrentRoute(r).GetName()
machineID := r.Header.Get("x-client-id")
source := r.Header.Get("x-source")
eventProperties := r.Header.Get("x-event-properties")

eventData := map[string]string{
"source": source,
}
eventData = analytics.InjectProperties(eventData, eventProperties)

if routeName != "" {
analytics.SendEvent(toWords(routeName), "test", machineID, &eventData)
}

ctx := r.Context()
ctx = context.WithValue(ctx, EventPropertiesKey, eventProperties)
next.ServeHTTP(w, r.WithContext(ctx))
})
}

func toWords(str string) string {
if matchResourceName.MatchString(str) {
return str
}
words := matchFirstCap.ReplaceAllString(str, "${1} ${2}")
words = matchAllCap.ReplaceAllString(words, "${1} ${2}")
return words
}

func EventPropertiesFromContext(ctx context.Context) string {
eventProperties := ctx.Value(EventPropertiesKey)

if eventProperties == nil {
return ""
}

return eventProperties.(string)
}

func SendEventWithProperties(name, category, clientID string, data map[string]string, ctx context.Context) error {
eventData := analytics.InjectProperties(data, EventPropertiesFromContext(ctx))
return analytics.SendEvent(name, category, clientID, &eventData)
}

0 comments on commit 6d6143a

Please sign in to comment.