diff --git a/ee/query-service/app/server.go b/ee/query-service/app/server.go index dfdff14939..dcb5568c04 100644 --- a/ee/query-service/app/server.go +++ b/ee/query-service/app/server.go @@ -10,6 +10,7 @@ import ( "net/http" _ "net/http/pprof" // http profiler "os" + "regexp" "time" "github.com/gorilla/handlers" @@ -393,13 +394,14 @@ func (lrw *loggingResponseWriter) Flush() { lrw.ResponseWriter.(http.Flusher).Flush() } -func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface{}, bool) { - pathToExtractBodyFrom := "/api/v3/query_range" +func 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 path == pathToExtractBodyFrom && (r.Method == "POST") { + if (r.Method == "POST") && ((path == pathToExtractBodyFromV3) || (path == pathToExtractBodyFromV4)) { if r.Body != nil { bodyBytes, err := io.ReadAll(r.Body) if err != nil { @@ -417,6 +419,25 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface return nil, false } + referrer := r.Header.Get("Referer") + + dashboardMatched, err := regexp.MatchString(`/dashboard/[a-zA-Z0-9\-]+/(new|edit)(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the referrer", zap.Error(err)) + } + alertMatched, err := regexp.MatchString(`/alerts/(new|edit)(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the alert: ", zap.Error(err)) + } + logsExplorerMatched, err := regexp.MatchString(`/logs/logs-explorer(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the logs explorer: ", zap.Error(err)) + } + traceExplorerMatched, err := regexp.MatchString(`/traces-explorer(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the trace explorer: ", zap.Error(err)) + } + signozMetricsUsed := false signozLogsUsed := false signozTracesUsed := false @@ -445,6 +466,20 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface data["tracesUsed"] = signozTracesUsed userEmail, err := baseauth.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) } } @@ -472,7 +507,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler { route := mux.CurrentRoute(r) path, _ := route.GetPathTemplate() - queryRangeV3data, metadataExists := extractQueryRangeV3Data(path, r) + queryRangeData, metadataExists := extractQueryRangeData(path, r) getActiveLogs(path, r) lrw := NewLoggingResponseWriter(w) @@ -480,7 +515,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler { data := map[string]interface{}{"path": path, "statusCode": lrw.statusCode} if metadataExists { - for key, value := range queryRangeV3data { + for key, value := range queryRangeData { data[key] = value } } diff --git a/frontend/src/constants/queryFunctionOptions.ts b/frontend/src/constants/queryFunctionOptions.ts index b79f673c46..4aa6332d67 100644 --- a/frontend/src/constants/queryFunctionOptions.ts +++ b/frontend/src/constants/queryFunctionOptions.ts @@ -2,7 +2,7 @@ import { QueryFunctionsTypes } from 'types/common/queryBuilder'; import { SelectOption } from 'types/common/select'; -export const queryFunctionOptions: SelectOption[] = [ +export const metricQueryFunctionOptions: SelectOption[] = [ { value: QueryFunctionsTypes.CUTOFF_MIN, label: 'Cut Off Min', @@ -65,6 +65,12 @@ export const queryFunctionOptions: SelectOption[] = [ }, ]; +export const logsQueryFunctionOptions: SelectOption[] = [ + { + value: QueryFunctionsTypes.TIME_SHIFT, + label: 'Time Shift', + }, +]; interface QueryFunctionConfigType { [key: string]: { showInput: boolean; diff --git a/frontend/src/container/FormAlertRules/QuerySection.tsx b/frontend/src/container/FormAlertRules/QuerySection.tsx index 1604cdb929..406a757eda 100644 --- a/frontend/src/container/FormAlertRules/QuerySection.tsx +++ b/frontend/src/container/FormAlertRules/QuerySection.tsx @@ -56,8 +56,9 @@ function QuerySection({ initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType], }} showFunctions={ - alertType === AlertTypes.METRICS_BASED_ALERT && - alertDef.version === ENTITY_VERSION_V4 + (alertType === AlertTypes.METRICS_BASED_ALERT && + alertDef.version === ENTITY_VERSION_V4) || + alertType === AlertTypes.LOGS_BASED_ALERT } version={alertDef.version || 'v3'} /> diff --git a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.styles.scss b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.styles.scss index 3bafb59879..f0c7565d29 100644 --- a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.styles.scss +++ b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.styles.scss @@ -77,6 +77,7 @@ .qb-entity-options { .options { border-color: var(--bg-vanilla-300); + box-shadow: none; .periscope-btn { border-color: var(--bg-vanilla-300); diff --git a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx index 8730506a88..fd8e860508 100644 --- a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx +++ b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx @@ -17,6 +17,7 @@ import { IBuilderQuery, QueryFunctionProps, } from 'types/api/queryBuilder/queryBuilderData'; +import { DataSource } from 'types/common/queryBuilder'; import QueryFunctions from '../QueryFunctions/QueryFunctions'; @@ -57,6 +58,8 @@ export default function QBEntityOptions({ } }; + const isLogsDataSource = query?.dataSource === DataSource.LOGS; + return (
@@ -97,12 +100,14 @@ export default function QBEntityOptions({ {showFunctions && - isMetricsDataSource && + (isMetricsDataSource || isLogsDataSource) && query && onQueryFunctionsUpdates && ( )} diff --git a/frontend/src/container/QueryBuilder/components/Query/Query.tsx b/frontend/src/container/QueryBuilder/components/Query/Query.tsx index 1bb761fde7..fb8b0e1561 100644 --- a/frontend/src/container/QueryBuilder/components/Query/Query.tsx +++ b/frontend/src/container/QueryBuilder/components/Query/Query.tsx @@ -36,6 +36,7 @@ import { } from 'react'; import { useLocation } from 'react-use'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; +import { DataSource } from 'types/common/queryBuilder'; import { transformToUpperCase } from 'utils/transformToUpperCase'; import QBEntityOptions from '../QBEntityOptions/QBEntityOptions'; @@ -324,7 +325,10 @@ export const Query = memo(function Query({