refactor: conditional based apdex on metrics and trace query range (#4395)

* refactor: conditional based apdex on metrics and trace query range

* chore: add invalid float conversion

* Revert "refactor: conditional based apdex on metrics and trace query range"

This reverts commit ca44a7aedd9d5635fe28c65f1608f4822a6bf204.

* refactor: added servicename to the query params

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
Rajat Dabade 2024-01-19 13:50:51 +05:30 committed by GitHub
parent 51c1f88593
commit 4a7d972c85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 25 additions and 11 deletions

View File

@ -4,5 +4,6 @@ import { MetricMetaProps } from 'types/api/metrics/getApDex';
export const getMetricMeta = ( export const getMetricMeta = (
metricName: string, metricName: string,
servicename: string,
): Promise<AxiosResponse<MetricMetaProps>> => ): Promise<AxiosResponse<MetricMetaProps>> =>
axios.get(`/metric_meta?metricName=${metricName}`); axios.get(`/metric_meta?metricName=${metricName}&serviceName=${servicename}`);

View File

@ -1,7 +1,9 @@
import Spinner from 'components/Spinner'; import Spinner from 'components/Spinner';
import { useGetMetricMeta } from 'hooks/apDex/useGetMetricMeta'; import { useGetMetricMeta } from 'hooks/apDex/useGetMetricMeta';
import useErrorNotification from 'hooks/useErrorNotification'; import useErrorNotification from 'hooks/useErrorNotification';
import { useParams } from 'react-router-dom';
import { IServiceName } from '../../types';
import ApDexMetrics from './ApDexMetrics'; import ApDexMetrics from './ApDexMetrics';
import { metricMeta } from './constants'; import { metricMeta } from './constants';
import { ApDexDataSwitcherProps } from './types'; import { ApDexDataSwitcherProps } from './types';
@ -13,7 +15,8 @@ function ApDexMetricsApplication({
thresholdValue, thresholdValue,
topLevelOperationsRoute, topLevelOperationsRoute,
}: ApDexDataSwitcherProps): JSX.Element { }: ApDexDataSwitcherProps): JSX.Element {
const { data, isLoading, error } = useGetMetricMeta(metricMeta); const { servicename } = useParams<IServiceName>();
const { data, isLoading, error } = useGetMetricMeta(metricMeta, servicename);
useErrorNotification(error); useErrorNotification(error);
if (isLoading) { if (isLoading) {

View File

@ -5,8 +5,9 @@ import { MetricMetaProps } from 'types/api/metrics/getApDex';
export const useGetMetricMeta = ( export const useGetMetricMeta = (
metricName: string, metricName: string,
servicename: string,
): UseQueryResult<AxiosResponse<MetricMetaProps>, AxiosError> => ): UseQueryResult<AxiosResponse<MetricMetaProps>, AxiosError> =>
useQuery<AxiosResponse<MetricMetaProps>, AxiosError>({ useQuery<AxiosResponse<MetricMetaProps>, AxiosError>({
queryKey: [{ metricName }], queryKey: [{ metricName, servicename }],
queryFn: async () => getMetricMeta(metricName), queryFn: async () => getMetricMeta(metricName, servicename),
}); });

View File

@ -36,7 +36,8 @@ func (aH *APIHandler) getApdexSettings(w http.ResponseWriter, r *http.Request) {
func (aH *APIHandler) getLatencyMetricMetadata(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getLatencyMetricMetadata(w http.ResponseWriter, r *http.Request) {
metricName := r.URL.Query().Get("metricName") metricName := r.URL.Query().Get("metricName")
metricMetadata, err := aH.reader.GetLatencyMetricMetadata(r.Context(), metricName, aH.preferDelta) serviceName := r.URL.Query().Get("serviceName")
metricMetadata, err := aH.reader.GetLatencyMetricMetadata(r.Context(), metricName, serviceName, aH.preferDelta)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Err: err, Typ: model.ErrorInternal}, nil) RespondError(w, &model.ApiError{Err: err, Typ: model.ErrorInternal}, nil)
return return

View File

@ -4057,8 +4057,8 @@ func (r *ClickHouseReader) GetMetricAttributeValues(ctx context.Context, req *v3
return &attributeValues, nil return &attributeValues, nil
} }
func (r *ClickHouseReader) GetLatencyMetricMetadata(ctx context.Context, metricName string, preferDelta bool) (*v3.LatencyMetricMetadataResponse, error) { func (r *ClickHouseReader) GetLatencyMetricMetadata(ctx context.Context, metricName, serviceName string, preferDelta bool) (*v3.LatencyMetricMetadataResponse, error) {
query := fmt.Sprintf("SELECT DISTINCT(temporality) from %s.%s WHERE metric_name='%s'", signozMetricDBName, signozTSTableName, metricName) query := fmt.Sprintf("SELECT DISTINCT(temporality) from %s.%s WHERE metric_name='%s' AND JSONExtractString(labels, 'service_name') = '%s'", signozMetricDBName, signozTSTableName, metricName, serviceName)
rows, err := r.db.Query(ctx, query, metricName) rows, err := r.db.Query(ctx, query, metricName)
if err != nil { if err != nil {
zap.S().Error(err) zap.S().Error(err)
@ -4077,7 +4077,7 @@ func (r *ClickHouseReader) GetLatencyMetricMetadata(ctx context.Context, metricN
} }
} }
query = fmt.Sprintf("SELECT DISTINCT(toFloat64(JSONExtractString(labels, 'le'))) as le from %s.%s WHERE metric_name='%s' ORDER BY le", signozMetricDBName, signozTSTableName, metricName) query = fmt.Sprintf("SELECT DISTINCT(JSONExtractString(labels, 'le')) as le from %s.%s WHERE metric_name='%s' AND JSONExtractString(labels, 'service_name') = '%s' ORDER BY le", signozMetricDBName, signozTSTableName, metricName, serviceName)
rows, err = r.db.Query(ctx, query, metricName) rows, err = r.db.Query(ctx, query, metricName)
if err != nil { if err != nil {
zap.S().Error(err) zap.S().Error(err)
@ -4087,10 +4087,18 @@ func (r *ClickHouseReader) GetLatencyMetricMetadata(ctx context.Context, metricN
var leFloat64 []float64 var leFloat64 []float64
for rows.Next() { for rows.Next() {
var le float64 var leStr string
if err := rows.Scan(&le); err != nil { if err := rows.Scan(&leStr); err != nil {
return nil, fmt.Errorf("error while scanning rows: %s", err.Error()) return nil, fmt.Errorf("error while scanning rows: %s", err.Error())
} }
le, err := strconv.ParseFloat(leStr, 64)
// ignore the error and continue if the value is not a float
// ideally this should not happen but we have seen ClickHouse
// returning empty string for some values
if err != nil {
zap.S().Error("error while parsing le value: ", err)
continue
}
if math.IsInf(le, 0) { if math.IsInf(le, 0) {
continue continue
} }

View File

@ -98,7 +98,7 @@ type Reader interface {
QueryDashboardVars(ctx context.Context, query string) (*model.DashboardVar, error) QueryDashboardVars(ctx context.Context, query string) (*model.DashboardVar, error)
CheckClickHouse(ctx context.Context) error CheckClickHouse(ctx context.Context) error
GetLatencyMetricMetadata(context.Context, string, bool) (*v3.LatencyMetricMetadataResponse, error) GetLatencyMetricMetadata(context.Context, string, string, bool) (*v3.LatencyMetricMetadataResponse, error)
} }
type Querier interface { type Querier interface {