feat: enhance Metrics and Incident services with Search integration for improved data handling

This commit is contained in:
Nawaz Dhandala
2026-04-01 09:31:05 +01:00
parent 848fd2c30b
commit ac39602ef6
5 changed files with 48 additions and 28 deletions

View File

@@ -12,7 +12,6 @@ import URL from "Common/Types/API/URL";
import { APP_API_URL } from "Common/UI/Config";
import AggregatedModel from "Common/Types/BaseDatabase/AggregatedModel";
import MetricsAggregationType from "Common/Types/Metrics/MetricsAggregationType";
import Dictionary from "Common/Types/Dictionary";
import AggregatedResult from "Common/Types/BaseDatabase/AggregatedResult";
import MetricViewData from "Common/Types/Metrics/MetricViewData";
import OneUptimeDate from "Common/Types/Date";
@@ -35,8 +34,7 @@ export default class MetricUtil {
projectId: ProjectUtil.getCurrentProjectId()!,
time: metricViewData.startAndEndDate!,
name: queryConfig.metricQueryData.filterData.metricName!,
attributes: queryConfig.metricQueryData.filterData
.attributes as Dictionary<string | number | boolean>,
attributes: queryConfig.metricQueryData.filterData.attributes as any,
},
aggregationType:
(queryConfig.metricQueryData.filterData

View File

@@ -5,6 +5,7 @@ import React, {
useState,
} from "react";
import ObjectID from "Common/Types/ObjectID";
import Search from "Common/Types/BaseDatabase/Search";
import IncidentMetricType from "Common/Types/Incident/IncidentMetricType";
import IncidentMetricTypeUtil from "Common/Utils/Incident/IncidentMetricType";
import MetricView from "../Metrics/MetricView";
@@ -60,7 +61,7 @@ const MonitorIncidentMetrics: FunctionComponent<ComponentProps> = (
filterData: {
metricName: metricType,
attributes: {
monitorIds: props.monitorId.toString(),
monitorIds: new Search(props.monitorId.toString()),
projectId: ProjectUtil.getCurrentProjectId()?.toString() || "",
},
aggegationType:

View File

@@ -2287,23 +2287,33 @@ ${incidentSeverity.name}
const metricTypesMap: Dictionary<MetricType> = {};
// common attributes shared by all incident metrics
// All values must be strings for ClickHouse Map(String, String) storage.
// Arrays are joined as comma-separated strings.
const baseMetricAttributes: JSONObject = {
incidentId: data.incidentId.toString(),
projectId: incident.projectId.toString(),
monitorIds:
incident.monitors?.map((monitor: Monitor) => {
return monitor._id?.toString();
}) || [],
(
incident.monitors
?.map((monitor: Monitor) => {
return monitor._id?.toString();
})
.filter(Boolean) || []
).join(", "),
monitorNames:
incident.monitors?.map((monitor: Monitor) => {
return monitor.name?.toString();
}) || [],
(
incident.monitors
?.map((monitor: Monitor) => {
return monitor.name?.toString();
})
.filter(Boolean) || []
).join(", "),
incidentSeverityId: incident.incidentSeverity?._id?.toString(),
incidentSeverityName: incident.incidentSeverity?.name?.toString(),
ownerUserIds: ownerUserIds,
ownerUserNames: ownerUserNames,
ownerTeamIds: ownerTeamIds,
ownerTeamNames: ownerTeamNames,
ownerUserIds: ownerUserIds.join(", "),
ownerUserNames: ownerUserNames.join(", "),
ownerTeamIds: ownerTeamIds.join(", "),
ownerTeamNames: ownerTeamNames.join(", "),
};
const incidentCountMetric: Metric = new Metric();

View File

@@ -419,23 +419,33 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
tableColumn.type === TableColumnType.MapStringString &&
typeof value === "object"
) {
const mapValue: Record<string, string> = value as Record<
string,
string
>;
const mapValue: Record<string, string | Search<string>> =
value as Record<string, string | Search<string>>;
for (const mapKey in mapValue) {
if (mapValue[mapKey] === undefined) {
continue;
}
whereStatement.append(
SQL`AND ${key}[${{
value: mapKey,
type: TableColumnType.Text,
}}] = ${{
value: mapValue[mapKey] as string,
type: TableColumnType.Text,
}}`,
);
if (mapValue[mapKey] instanceof Search) {
whereStatement.append(
SQL`AND ${key}[${{
value: mapKey,
type: TableColumnType.Text,
}}] ILIKE ${{
value: mapValue[mapKey] as Search<string>,
type: TableColumnType.Text,
}}`,
);
} else {
whereStatement.append(
SQL`AND ${key}[${{
value: mapKey,
type: TableColumnType.Text,
}}] = ${{
value: mapValue[mapKey] as string,
type: TableColumnType.Text,
}}`,
);
}
}
} else if (
(tableColumn.type === TableColumnType.JSON ||

View File

@@ -1,9 +1,10 @@
import Search from "../BaseDatabase/Search";
import Dictionary from "../Dictionary";
import MetricsAggregationType from "./MetricsAggregationType";
export default interface MetricsQuery {
metricName: string;
attributes: Dictionary<string | boolean | number>;
attributes: Dictionary<string | boolean | number | Search<string>>;
aggegationType: MetricsAggregationType;
aggregateBy: Dictionary<boolean>;