Skip to content

Commit

Permalink
feat(server): add analytics middleware (#2684)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgeepc committed Jun 9, 2023
1 parent 90472ba commit 249d475
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 25 deletions.
2 changes: 1 addition & 1 deletion cli/analytics/analytics.go
Expand Up @@ -33,7 +33,7 @@ func Init(conf config.Config) {
if err == nil {
// only use id if available.
mid = id
} // ignore errors and continue with an empty ID if neccesary
} // ignore errors and continue with an empty ID if necessary

client.Enqueue(segment.Identify{
UserId: mid,
Expand Down
2 changes: 2 additions & 0 deletions cli/utils/api.go
Expand Up @@ -28,6 +28,7 @@ type ListArgs struct {
func GetAPIClient(cliConfig config.Config) *openapi.APIClient {
config := openapi.NewConfiguration()
config.AddDefaultHeader("x-client-id", analytics.ClientID())
config.AddDefaultHeader("x-source", "cli")
config.Scheme = cliConfig.Scheme
config.Host = strings.TrimSuffix(cliConfig.Endpoint, "/")
if cliConfig.ServerPath != nil {
Expand Down Expand Up @@ -84,6 +85,7 @@ func (resourceClient ResourceClient) NewRequest(url, method, body, contentType s
}

request.Header.Set("x-client-id", analytics.ClientID())
request.Header.Set("x-source", "cli")
request.Header.Set("Content-Type", contentType)
request.Header.Set("Accept", contentType)
if augmented {
Expand Down
36 changes: 36 additions & 0 deletions server/app/app.go
Expand Up @@ -8,6 +8,7 @@ import (
"log"
"net/http"
"os"
"regexp"

"github.com/gorilla/handlers"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -248,6 +249,9 @@ func (app *App) Start(opts ...appOption) error {
router, mappers := controller(app.cfg, testDB, transactionsRepository, tracer, environmentRepo, rf, triggerRegistry)
registerWSHandler(router, mappers, subscriptionManager)

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

apiRouter := router.
PathPrefix(app.cfg.ServerPathPrefix()).
PathPrefix("/api").
Expand Down Expand Up @@ -289,6 +293,38 @@ 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")

if routeName != "" {
analytics.SendEvent(toWords(routeName), "test", machineID, &map[string]string{
"source": source,
})
}

next.ServeHTTP(w, r)
})
}

func registerSPAHandler(router *mux.Router, cfg httpServerConfig, analyticsEnabled bool, serverID string, isTracetestDev bool) {
router.
PathPrefix(cfg.ServerPathPrefix()).
Expand Down
23 changes: 0 additions & 23 deletions server/http/custom_routes.go
Expand Up @@ -6,11 +6,9 @@ import (
"errors"
"fmt"
"net/http"
"regexp"
"strconv"

"github.com/gorilla/mux"
"github.com/kubeshop/tracetest/server/analytics"
"github.com/kubeshop/tracetest/server/openapi"
"github.com/kubeshop/tracetest/server/resourcemanager"
"go.opentelemetry.io/otel"
Expand Down Expand Up @@ -51,7 +49,6 @@ func (c *customController) Routes() openapi.Routes {
hf := route.HandlerFunc

hf = c.instrumentRoute(routeName, route.Pattern, hf)
hf = c.analytics(route.Name, hf)

route.HandlerFunc = hf

Expand Down Expand Up @@ -225,26 +222,6 @@ func parseInt32Parameter(param string, required bool) (int32, error) {
return int32(val), nil
}

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

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

func (c *customController) analytics(name string, f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
machineID := r.Header.Get("x-client-id")
analytics.SendEvent(toWords(name), "test", machineID, nil)

f(w, r)
}
}

func (c *customController) instrumentRoute(name string, route string, f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
Expand Down
2 changes: 1 addition & 1 deletion server/resourcemanager/resource_manager.go
Expand Up @@ -130,7 +130,7 @@ func (m *manager[T]) RegisterRoutes(r *mux.Router) *mux.Router {
enabledOps := m.EnabledOperations()

if slices.Contains(enabledOps, OperationList) {
m.instrumentRoute(subrouter.HandleFunc("", m.list).Methods(http.MethodGet).Name("list"))
m.instrumentRoute(subrouter.HandleFunc("", m.list).Methods(http.MethodGet).Name(fmt.Sprintf("%s.List", m.resourceTypePlural)))
}

if slices.Contains(enabledOps, OperationCreate) {
Expand Down
3 changes: 3 additions & 0 deletions web/src/redux/apis/TraceTest.api.ts
Expand Up @@ -17,6 +17,9 @@ const TraceTestAPI = createApi({
reducerPath: 'tests',
baseQuery: fetchBaseQuery({
baseUrl: PATH,
prepareHeaders: headers => {
headers.set('x-source', 'web');
},
}),
tagTypes: Object.values(TracetestApiTags),
endpoints(builder: TTestApiEndpointBuilder) {
Expand Down

0 comments on commit 249d475

Please sign in to comment.