mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 06:29:02 +08:00
fix: move analytics middleware (#6901)
* fix: move analytics middleware * fix: use logger from params * fix: use remove custom response writer * fix: use correct names
This commit is contained in:
parent
7f25674640
commit
c56345e1db
@ -322,7 +322,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server,
|
|||||||
s.serverOptions.Config.APIServer.Timeout.Default,
|
s.serverOptions.Config.APIServer.Timeout.Default,
|
||||||
s.serverOptions.Config.APIServer.Timeout.Max,
|
s.serverOptions.Config.APIServer.Timeout.Max,
|
||||||
).Wrap)
|
).Wrap)
|
||||||
r.Use(s.analyticsMiddleware)
|
r.Use(middleware.NewAnalytics(zap.L()).Wrap)
|
||||||
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
||||||
|
|
||||||
apiHandler.RegisterPrivateRoutes(r)
|
apiHandler.RegisterPrivateRoutes(r)
|
||||||
@ -368,7 +368,7 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
|
|||||||
s.serverOptions.Config.APIServer.Timeout.Default,
|
s.serverOptions.Config.APIServer.Timeout.Default,
|
||||||
s.serverOptions.Config.APIServer.Timeout.Max,
|
s.serverOptions.Config.APIServer.Timeout.Max,
|
||||||
).Wrap)
|
).Wrap)
|
||||||
r.Use(s.analyticsMiddleware)
|
r.Use(middleware.NewAnalytics(zap.L()).Wrap)
|
||||||
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
||||||
|
|
||||||
apiHandler.RegisterRoutes(r, am)
|
apiHandler.RegisterRoutes(r, am)
|
||||||
|
161
pkg/http/middleware/analytics.go
Normal file
161
pkg/http/middleware/analytics.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
// TODO(remove): Remove auth packages
|
||||||
|
"go.signoz.io/signoz/pkg/query-service/auth"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
||||||
|
"go.signoz.io/signoz/pkg/query-service/telemetry"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Analytics struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAnalytics(logger *zap.Logger) *Analytics {
|
||||||
|
if logger == nil {
|
||||||
|
panic("cannot build analytics middleware, logger is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Analytics{logger: logger}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Analytics) Wrap(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := auth.AttachJwtToContext(r.Context(), r)
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
route := mux.CurrentRoute(r)
|
||||||
|
path, _ := route.GetPathTemplate()
|
||||||
|
|
||||||
|
badResponseBuffer := new(bytes.Buffer)
|
||||||
|
writer := newBadResponseLoggingWriter(w, badResponseBuffer)
|
||||||
|
next.ServeHTTP(writer, r)
|
||||||
|
|
||||||
|
queryRangeData, metadataExists := a.extractQueryRangeData(path, r)
|
||||||
|
a.getActiveLogs(path, r)
|
||||||
|
|
||||||
|
data := map[string]interface{}{"path": path, "statusCode": writer.StatusCode()}
|
||||||
|
if metadataExists {
|
||||||
|
for key, value := range queryRangeData {
|
||||||
|
data[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := telemetry.EnabledPaths()[path]; ok {
|
||||||
|
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||||
|
if err == nil {
|
||||||
|
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail, true, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Analytics) getActiveLogs(path string, r *http.Request) {
|
||||||
|
// this is for the old logs explorer api.
|
||||||
|
if path == "/api/v1/logs" {
|
||||||
|
hasFilters := len(r.URL.Query().Get("q"))
|
||||||
|
if hasFilters > 0 {
|
||||||
|
telemetry.GetInstance().AddActiveLogsUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Analytics) extractQueryRangeData(path string, r *http.Request) (map[string]interface{}, bool) {
|
||||||
|
pathToExtractBodyFromV3 := "/api/v3/query_range"
|
||||||
|
pathToExtractBodyFromV4 := "/api/v4/query_range"
|
||||||
|
|
||||||
|
data := map[string]interface{}{}
|
||||||
|
var postData *v3.QueryRangeParamsV3
|
||||||
|
|
||||||
|
if (r.Method == "POST") && ((path == pathToExtractBodyFromV3) || (path == pathToExtractBodyFromV4)) {
|
||||||
|
if r.Body != nil {
|
||||||
|
bodyBytes, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
r.Body.Close() // must close
|
||||||
|
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||||
|
json.Unmarshal(bodyBytes, &postData)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
referrer := r.Header.Get("Referer")
|
||||||
|
|
||||||
|
dashboardMatched, err := regexp.MatchString(`/dashboard/[a-zA-Z0-9\-]+/(new|edit)(?:\?.*)?$`, referrer)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Error("error while matching the referrer", zap.Error(err))
|
||||||
|
}
|
||||||
|
alertMatched, err := regexp.MatchString(`/alerts/(new|edit)(?:\?.*)?$`, referrer)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Error("error while matching the alert: ", zap.Error(err))
|
||||||
|
}
|
||||||
|
logsExplorerMatched, err := regexp.MatchString(`/logs/logs-explorer(?:\?.*)?$`, referrer)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Error("error while matching the logs explorer: ", zap.Error(err))
|
||||||
|
}
|
||||||
|
traceExplorerMatched, err := regexp.MatchString(`/traces-explorer(?:\?.*)?$`, referrer)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Error("error while matching the trace explorer: ", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
queryInfoResult := telemetry.GetInstance().CheckQueryInfo(postData)
|
||||||
|
|
||||||
|
if (queryInfoResult.MetricsUsed || queryInfoResult.LogsUsed || queryInfoResult.TracesUsed) && (queryInfoResult.FilterApplied) {
|
||||||
|
if queryInfoResult.MetricsUsed {
|
||||||
|
telemetry.GetInstance().AddActiveMetricsUser()
|
||||||
|
}
|
||||||
|
if queryInfoResult.LogsUsed {
|
||||||
|
telemetry.GetInstance().AddActiveLogsUser()
|
||||||
|
}
|
||||||
|
if queryInfoResult.TracesUsed {
|
||||||
|
telemetry.GetInstance().AddActiveTracesUser()
|
||||||
|
}
|
||||||
|
data["metricsUsed"] = queryInfoResult.MetricsUsed
|
||||||
|
data["logsUsed"] = queryInfoResult.LogsUsed
|
||||||
|
data["tracesUsed"] = queryInfoResult.TracesUsed
|
||||||
|
data["filterApplied"] = queryInfoResult.FilterApplied
|
||||||
|
data["groupByApplied"] = queryInfoResult.GroupByApplied
|
||||||
|
data["aggregateOperator"] = queryInfoResult.AggregateOperator
|
||||||
|
data["aggregateAttributeKey"] = queryInfoResult.AggregateAttributeKey
|
||||||
|
data["numberOfQueries"] = queryInfoResult.NumberOfQueries
|
||||||
|
data["queryType"] = queryInfoResult.QueryType
|
||||||
|
data["panelType"] = queryInfoResult.PanelType
|
||||||
|
|
||||||
|
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||||
|
if err == nil {
|
||||||
|
// switch case to set data["screen"] based on the referrer
|
||||||
|
switch {
|
||||||
|
case dashboardMatched:
|
||||||
|
data["screen"] = "panel"
|
||||||
|
case alertMatched:
|
||||||
|
data["screen"] = "alert"
|
||||||
|
case logsExplorerMatched:
|
||||||
|
data["screen"] = "logs-explorer"
|
||||||
|
case traceExplorerMatched:
|
||||||
|
data["screen"] = "traces-explorer"
|
||||||
|
default:
|
||||||
|
data["screen"] = "unknown"
|
||||||
|
return data, true
|
||||||
|
}
|
||||||
|
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail, true, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data, true
|
||||||
|
}
|
@ -265,7 +265,7 @@ func (s *Server) createPrivateServer(api *APIHandler) (*http.Server, error) {
|
|||||||
s.serverOptions.Config.APIServer.Timeout.Default,
|
s.serverOptions.Config.APIServer.Timeout.Default,
|
||||||
s.serverOptions.Config.APIServer.Timeout.Max,
|
s.serverOptions.Config.APIServer.Timeout.Max,
|
||||||
).Wrap)
|
).Wrap)
|
||||||
r.Use(s.analyticsMiddleware)
|
r.Use(middleware.NewAnalytics(zap.L()).Wrap)
|
||||||
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
||||||
|
|
||||||
api.RegisterPrivateRoutes(r)
|
api.RegisterPrivateRoutes(r)
|
||||||
@ -295,7 +295,7 @@ func (s *Server) createPublicServer(api *APIHandler, web web.Web) (*http.Server,
|
|||||||
s.serverOptions.Config.APIServer.Timeout.Default,
|
s.serverOptions.Config.APIServer.Timeout.Default,
|
||||||
s.serverOptions.Config.APIServer.Timeout.Max,
|
s.serverOptions.Config.APIServer.Timeout.Max,
|
||||||
).Wrap)
|
).Wrap)
|
||||||
r.Use(s.analyticsMiddleware)
|
r.Use(middleware.NewAnalytics(zap.L()).Wrap)
|
||||||
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
r.Use(middleware.NewLogging(zap.L()).Wrap)
|
||||||
|
|
||||||
// add auth middleware
|
// add auth middleware
|
||||||
|
Loading…
x
Reference in New Issue
Block a user