mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-01-16 23:00:51 +00:00
refactor(monitor): tidy formatting, consolidate imports and add type annotations
- Normalize whitespace/indentation and reformat several monitor utilities and message builders - Consolidate and reorder imports (including MonitorEvaluationSummary) across evaluator/data-extractor modules - Add explicit types (MonitorStatus, BasicDiskMetrics) and tighten type annotations in observation/resource code - Minor cleanups to conditional formatting in dashboard components (EvaluationLogList, SummaryInfo)
This commit is contained in:
parent
3837208023
commit
775b8846c7
11 changed files with 2075 additions and 2079 deletions
|
|
@ -174,8 +174,7 @@ export default class ServerMonitorCriteria {
|
|||
).basicInfrastructureMetrics?.diskMetrics.find(
|
||||
(item: BasicDiskMetrics) => {
|
||||
return (
|
||||
item.diskPath.trim().toLowerCase() ===
|
||||
diskPath.trim().toLowerCase()
|
||||
item.diskPath.trim().toLowerCase() === diskPath.trim().toLowerCase()
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,192 +16,193 @@ import MetricQueryConfigData from "../../../Types/Metrics/MetricQueryConfigData"
|
|||
import MetricFormulaConfigData from "../../../Types/Metrics/MetricFormulaConfigData";
|
||||
|
||||
export default class MonitorCriteriaDataExtractor {
|
||||
public static getProbeMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): ProbeMonitorResponse | null {
|
||||
if ((dataToProcess as ProbeMonitorResponse).monitorStepId) {
|
||||
return dataToProcess as ProbeMonitorResponse;
|
||||
}
|
||||
public static getProbeMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): ProbeMonitorResponse | null {
|
||||
if ((dataToProcess as ProbeMonitorResponse).monitorStepId) {
|
||||
return dataToProcess as ProbeMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getServerMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): ServerMonitorResponse | null {
|
||||
if ((dataToProcess as ServerMonitorResponse).hostname) {
|
||||
return dataToProcess as ServerMonitorResponse;
|
||||
}
|
||||
public static getServerMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): ServerMonitorResponse | null {
|
||||
if ((dataToProcess as ServerMonitorResponse).hostname) {
|
||||
return dataToProcess as ServerMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getIncomingMonitorRequest(
|
||||
dataToProcess: DataToProcess,
|
||||
): IncomingMonitorRequest | null {
|
||||
if (
|
||||
(dataToProcess as IncomingMonitorRequest).incomingRequestReceivedAt !==
|
||||
undefined
|
||||
) {
|
||||
return dataToProcess as IncomingMonitorRequest;
|
||||
}
|
||||
public static getIncomingMonitorRequest(
|
||||
dataToProcess: DataToProcess,
|
||||
): IncomingMonitorRequest | null {
|
||||
if (
|
||||
(dataToProcess as IncomingMonitorRequest).incomingRequestReceivedAt !==
|
||||
undefined
|
||||
) {
|
||||
return dataToProcess as IncomingMonitorRequest;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getLogMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): LogMonitorResponse | null {
|
||||
if ((dataToProcess as LogMonitorResponse).logCount !== undefined) {
|
||||
return dataToProcess as LogMonitorResponse;
|
||||
}
|
||||
public static getLogMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): LogMonitorResponse | null {
|
||||
if ((dataToProcess as LogMonitorResponse).logCount !== undefined) {
|
||||
return dataToProcess as LogMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getTraceMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): TraceMonitorResponse | null {
|
||||
if ((dataToProcess as TraceMonitorResponse).spanCount !== undefined) {
|
||||
return dataToProcess as TraceMonitorResponse;
|
||||
}
|
||||
public static getTraceMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): TraceMonitorResponse | null {
|
||||
if ((dataToProcess as TraceMonitorResponse).spanCount !== undefined) {
|
||||
return dataToProcess as TraceMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getMetricMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): MetricMonitorResponse | null {
|
||||
if ((dataToProcess as MetricMonitorResponse).metricResult !== undefined) {
|
||||
return dataToProcess as MetricMonitorResponse;
|
||||
}
|
||||
public static getMetricMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): MetricMonitorResponse | null {
|
||||
if ((dataToProcess as MetricMonitorResponse).metricResult !== undefined) {
|
||||
return dataToProcess as MetricMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getCustomCodeMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): CustomCodeMonitorResponse | null {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
public static getCustomCodeMonitorResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): CustomCodeMonitorResponse | null {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
|
||||
if (probeResponse?.customCodeMonitorResponse) {
|
||||
return probeResponse.customCodeMonitorResponse;
|
||||
}
|
||||
if (probeResponse?.customCodeMonitorResponse) {
|
||||
return probeResponse.customCodeMonitorResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static getSyntheticMonitorResponses(
|
||||
dataToProcess: DataToProcess,
|
||||
): Array<SyntheticMonitorResponse> {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
public static getSyntheticMonitorResponses(
|
||||
dataToProcess: DataToProcess,
|
||||
): Array<SyntheticMonitorResponse> {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
|
||||
return probeResponse?.syntheticMonitorResponse || [];
|
||||
}
|
||||
return probeResponse?.syntheticMonitorResponse || [];
|
||||
}
|
||||
|
||||
public static getSslResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): SslMonitorResponse | null {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
public static getSslResponse(
|
||||
dataToProcess: DataToProcess,
|
||||
): SslMonitorResponse | null {
|
||||
const probeResponse: ProbeMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getProbeMonitorResponse(dataToProcess);
|
||||
|
||||
if (probeResponse?.sslResponse) {
|
||||
return probeResponse.sslResponse;
|
||||
}
|
||||
if (probeResponse?.sslResponse) {
|
||||
return probeResponse.sslResponse;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static extractMetricValues(input: {
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
}): { alias: string | null; values: Array<number> } | null {
|
||||
const metricResponse: MetricMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getMetricMonitorResponse(
|
||||
input.dataToProcess,
|
||||
);
|
||||
public static extractMetricValues(input: {
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
}): { alias: string | null; values: Array<number> } | null {
|
||||
const metricResponse: MetricMonitorResponse | null =
|
||||
MonitorCriteriaDataExtractor.getMetricMonitorResponse(
|
||||
input.dataToProcess,
|
||||
);
|
||||
|
||||
if (!metricResponse) {
|
||||
return null;
|
||||
}
|
||||
if (!metricResponse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const aggregatedResults: Array<AggregatedResult> =
|
||||
metricResponse.metricResult || [];
|
||||
const aggregatedResults: Array<AggregatedResult> =
|
||||
metricResponse.metricResult || [];
|
||||
|
||||
if (!aggregatedResults.length) {
|
||||
return {
|
||||
alias: input.criteriaFilter.metricMonitorOptions?.metricAlias || null,
|
||||
values: [],
|
||||
};
|
||||
}
|
||||
if (!aggregatedResults.length) {
|
||||
return {
|
||||
alias: input.criteriaFilter.metricMonitorOptions?.metricAlias || null,
|
||||
values: [],
|
||||
};
|
||||
}
|
||||
|
||||
let alias: string | null =
|
||||
input.criteriaFilter.metricMonitorOptions?.metricAlias || null;
|
||||
let alias: string | null =
|
||||
input.criteriaFilter.metricMonitorOptions?.metricAlias || null;
|
||||
|
||||
let result: AggregatedResult | undefined;
|
||||
let result: AggregatedResult | undefined;
|
||||
|
||||
if (alias) {
|
||||
const queryConfigs: Array<MetricQueryConfigData> =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig?.queryConfigs ||
|
||||
[];
|
||||
if (alias) {
|
||||
const queryConfigs: Array<MetricQueryConfigData> =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig?.queryConfigs ||
|
||||
[];
|
||||
|
||||
let aliasIndex: number = queryConfigs.findIndex(
|
||||
(queryConfig: MetricQueryConfigData) => {
|
||||
return queryConfig.metricAliasData?.metricVariable === alias;
|
||||
},
|
||||
);
|
||||
let aliasIndex: number = queryConfigs.findIndex(
|
||||
(queryConfig: MetricQueryConfigData) => {
|
||||
return queryConfig.metricAliasData?.metricVariable === alias;
|
||||
},
|
||||
);
|
||||
|
||||
if (aliasIndex < 0) {
|
||||
const formulaConfigs: Array<MetricFormulaConfigData> =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig
|
||||
?.formulaConfigs || [];
|
||||
if (aliasIndex < 0) {
|
||||
const formulaConfigs: Array<MetricFormulaConfigData> =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig
|
||||
?.formulaConfigs || [];
|
||||
|
||||
const formulaIndex: number = formulaConfigs.findIndex(
|
||||
(formulaConfig: MetricFormulaConfigData) => {
|
||||
return formulaConfig.metricAliasData?.metricVariable === alias;
|
||||
},
|
||||
);
|
||||
const formulaIndex: number = formulaConfigs.findIndex(
|
||||
(formulaConfig: MetricFormulaConfigData) => {
|
||||
return formulaConfig.metricAliasData?.metricVariable === alias;
|
||||
},
|
||||
);
|
||||
|
||||
if (formulaIndex >= 0) {
|
||||
aliasIndex = queryConfigs.length + formulaIndex;
|
||||
}
|
||||
}
|
||||
if (formulaIndex >= 0) {
|
||||
aliasIndex = queryConfigs.length + formulaIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (aliasIndex >= 0 && aliasIndex < aggregatedResults.length) {
|
||||
result = aggregatedResults[aliasIndex];
|
||||
}
|
||||
}
|
||||
if (aliasIndex >= 0 && aliasIndex < aggregatedResults.length) {
|
||||
result = aggregatedResults[aliasIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = aggregatedResults[0];
|
||||
if (!alias) {
|
||||
const defaultAlias: string | undefined =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig?.queryConfigs?.[0]?.metricAliasData?.metricVariable;
|
||||
alias = defaultAlias || null;
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
result = aggregatedResults[0];
|
||||
if (!alias) {
|
||||
const defaultAlias: string | undefined =
|
||||
input.monitorStep.data?.metricMonitor?.metricViewConfig
|
||||
?.queryConfigs?.[0]?.metricAliasData?.metricVariable;
|
||||
alias = defaultAlias || null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return {
|
||||
alias: alias,
|
||||
values: [],
|
||||
};
|
||||
}
|
||||
if (!result) {
|
||||
return {
|
||||
alias: alias,
|
||||
values: [],
|
||||
};
|
||||
}
|
||||
|
||||
const values: Array<number> = result.data
|
||||
.map((entry: AggregateModel) => {
|
||||
return entry.value;
|
||||
})
|
||||
.filter((value: number) => {
|
||||
return typeof value === "number" && !isNaN(value);
|
||||
});
|
||||
const values: Array<number> = result.data
|
||||
.map((entry: AggregateModel) => {
|
||||
return entry.value;
|
||||
})
|
||||
.filter((value: number) => {
|
||||
return typeof value === "number" && !isNaN(value);
|
||||
});
|
||||
|
||||
return {
|
||||
alias: alias,
|
||||
values: values,
|
||||
};
|
||||
}
|
||||
return {
|
||||
alias: alias,
|
||||
values: values,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import MonitorCriteria from "../../../Types/Monitor/MonitorCriteria";
|
|||
import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
|
||||
import MonitorStep from "../../../Types/Monitor/MonitorStep";
|
||||
import FilterCondition from "../../../Types/Filter/FilterCondition";
|
||||
import {
|
||||
import MonitorEvaluationSummary, {
|
||||
MonitorEvaluationCriteriaResult,
|
||||
MonitorEvaluationEvent,
|
||||
MonitorEvaluationFilterResult,
|
||||
|
|
@ -30,7 +30,6 @@ import OneUptimeDate from "../../../Types/Date";
|
|||
import { JSONObject } from "../../../Types/JSON";
|
||||
import Typeof from "../../../Types/Typeof";
|
||||
import ReturnResult from "../../../Types/IsolatedVM/ReturnResult";
|
||||
import MonitorEvaluationSummary from "../../../Types/Monitor/MonitorEvaluationSummary";
|
||||
|
||||
export default class MonitorCriteriaEvaluator {
|
||||
public static async processMonitorStep(input: {
|
||||
|
|
|
|||
|
|
@ -1,141 +1,141 @@
|
|||
import {
|
||||
CriteriaFilter,
|
||||
FilterType,
|
||||
CriteriaFilter,
|
||||
FilterType,
|
||||
} from "../../../Types/Monitor/CriteriaFilter";
|
||||
|
||||
export default class MonitorCriteriaExpectationBuilder {
|
||||
public static getCriteriaFilterDescription(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string {
|
||||
const parts: Array<string> = [criteriaFilter.checkOn];
|
||||
public static getCriteriaFilterDescription(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string {
|
||||
const parts: Array<string> = [criteriaFilter.checkOn];
|
||||
|
||||
if (criteriaFilter.filterType) {
|
||||
parts.push(criteriaFilter.filterType);
|
||||
}
|
||||
if (criteriaFilter.filterType) {
|
||||
parts.push(criteriaFilter.filterType);
|
||||
}
|
||||
|
||||
if (criteriaFilter.value !== undefined && criteriaFilter.value !== null) {
|
||||
parts.push(String(criteriaFilter.value));
|
||||
}
|
||||
if (criteriaFilter.value !== undefined && criteriaFilter.value !== null) {
|
||||
parts.push(String(criteriaFilter.value));
|
||||
}
|
||||
|
||||
return parts.join(" ").trim();
|
||||
}
|
||||
return parts.join(" ").trim();
|
||||
}
|
||||
|
||||
public static describeCriteriaExpectation(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string | null {
|
||||
if (!criteriaFilter.filterType) {
|
||||
return null;
|
||||
}
|
||||
public static describeCriteriaExpectation(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string | null {
|
||||
if (!criteriaFilter.filterType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let expectation: string;
|
||||
let expectation: string;
|
||||
|
||||
const value: string | number | undefined = criteriaFilter.value;
|
||||
const value: string | number | undefined = criteriaFilter.value;
|
||||
|
||||
switch (criteriaFilter.filterType) {
|
||||
case FilterType.GreaterThan:
|
||||
expectation = `to be greater than ${value}`;
|
||||
break;
|
||||
case FilterType.GreaterThanOrEqualTo:
|
||||
expectation = `to be greater than or equal to ${value}`;
|
||||
break;
|
||||
case FilterType.LessThan:
|
||||
expectation = `to be less than ${value}`;
|
||||
break;
|
||||
case FilterType.LessThanOrEqualTo:
|
||||
expectation = `to be less than or equal to ${value}`;
|
||||
break;
|
||||
case FilterType.EqualTo:
|
||||
expectation = `to equal ${value}`;
|
||||
break;
|
||||
case FilterType.NotEqualTo:
|
||||
expectation = `to not equal ${value}`;
|
||||
break;
|
||||
case FilterType.Contains:
|
||||
expectation = `to contain ${value}`;
|
||||
break;
|
||||
case FilterType.NotContains:
|
||||
expectation = `to not contain ${value}`;
|
||||
break;
|
||||
case FilterType.StartsWith:
|
||||
expectation = `to start with ${value}`;
|
||||
break;
|
||||
case FilterType.EndsWith:
|
||||
expectation = `to end with ${value}`;
|
||||
break;
|
||||
case FilterType.IsEmpty:
|
||||
expectation = "to be empty";
|
||||
break;
|
||||
case FilterType.IsNotEmpty:
|
||||
expectation = "to not be empty";
|
||||
break;
|
||||
case FilterType.True:
|
||||
expectation = "to be true";
|
||||
break;
|
||||
case FilterType.False:
|
||||
expectation = "to be false";
|
||||
break;
|
||||
case FilterType.IsExecuting:
|
||||
expectation = "to be executing";
|
||||
break;
|
||||
case FilterType.IsNotExecuting:
|
||||
expectation = "to not be executing";
|
||||
break;
|
||||
case FilterType.RecievedInMinutes:
|
||||
expectation = value
|
||||
? `to receive a heartbeat within ${value} minutes`
|
||||
: "to receive a heartbeat within the configured window";
|
||||
break;
|
||||
case FilterType.NotRecievedInMinutes:
|
||||
expectation = value
|
||||
? `to miss a heartbeat for at least ${value} minutes`
|
||||
: "to miss a heartbeat within the configured window";
|
||||
break;
|
||||
case FilterType.EvaluatesToTrue:
|
||||
expectation = "to evaluate to true";
|
||||
break;
|
||||
default:
|
||||
expectation = `${criteriaFilter.filterType}${value ? ` ${value}` : ""}`;
|
||||
break;
|
||||
}
|
||||
switch (criteriaFilter.filterType) {
|
||||
case FilterType.GreaterThan:
|
||||
expectation = `to be greater than ${value}`;
|
||||
break;
|
||||
case FilterType.GreaterThanOrEqualTo:
|
||||
expectation = `to be greater than or equal to ${value}`;
|
||||
break;
|
||||
case FilterType.LessThan:
|
||||
expectation = `to be less than ${value}`;
|
||||
break;
|
||||
case FilterType.LessThanOrEqualTo:
|
||||
expectation = `to be less than or equal to ${value}`;
|
||||
break;
|
||||
case FilterType.EqualTo:
|
||||
expectation = `to equal ${value}`;
|
||||
break;
|
||||
case FilterType.NotEqualTo:
|
||||
expectation = `to not equal ${value}`;
|
||||
break;
|
||||
case FilterType.Contains:
|
||||
expectation = `to contain ${value}`;
|
||||
break;
|
||||
case FilterType.NotContains:
|
||||
expectation = `to not contain ${value}`;
|
||||
break;
|
||||
case FilterType.StartsWith:
|
||||
expectation = `to start with ${value}`;
|
||||
break;
|
||||
case FilterType.EndsWith:
|
||||
expectation = `to end with ${value}`;
|
||||
break;
|
||||
case FilterType.IsEmpty:
|
||||
expectation = "to be empty";
|
||||
break;
|
||||
case FilterType.IsNotEmpty:
|
||||
expectation = "to not be empty";
|
||||
break;
|
||||
case FilterType.True:
|
||||
expectation = "to be true";
|
||||
break;
|
||||
case FilterType.False:
|
||||
expectation = "to be false";
|
||||
break;
|
||||
case FilterType.IsExecuting:
|
||||
expectation = "to be executing";
|
||||
break;
|
||||
case FilterType.IsNotExecuting:
|
||||
expectation = "to not be executing";
|
||||
break;
|
||||
case FilterType.RecievedInMinutes:
|
||||
expectation = value
|
||||
? `to receive a heartbeat within ${value} minutes`
|
||||
: "to receive a heartbeat within the configured window";
|
||||
break;
|
||||
case FilterType.NotRecievedInMinutes:
|
||||
expectation = value
|
||||
? `to miss a heartbeat for at least ${value} minutes`
|
||||
: "to miss a heartbeat within the configured window";
|
||||
break;
|
||||
case FilterType.EvaluatesToTrue:
|
||||
expectation = "to evaluate to true";
|
||||
break;
|
||||
default:
|
||||
expectation = `${criteriaFilter.filterType}${value ? ` ${value}` : ""}`;
|
||||
break;
|
||||
}
|
||||
|
||||
const evaluationWindow: string | null =
|
||||
MonitorCriteriaExpectationBuilder.getEvaluationWindowDescription(
|
||||
criteriaFilter,
|
||||
);
|
||||
const evaluationWindow: string | null =
|
||||
MonitorCriteriaExpectationBuilder.getEvaluationWindowDescription(
|
||||
criteriaFilter,
|
||||
);
|
||||
|
||||
if (evaluationWindow) {
|
||||
expectation += ` ${evaluationWindow}`;
|
||||
}
|
||||
if (evaluationWindow) {
|
||||
expectation += ` ${evaluationWindow}`;
|
||||
}
|
||||
|
||||
return expectation.trim();
|
||||
}
|
||||
return expectation.trim();
|
||||
}
|
||||
|
||||
public static getEvaluationWindowDescription(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string | null {
|
||||
const parts: Array<string> = [];
|
||||
public static getEvaluationWindowDescription(
|
||||
criteriaFilter: CriteriaFilter,
|
||||
): string | null {
|
||||
const parts: Array<string> = [];
|
||||
|
||||
if (
|
||||
criteriaFilter.eveluateOverTime &&
|
||||
criteriaFilter.evaluateOverTimeOptions?.timeValueInMinutes
|
||||
) {
|
||||
parts.push(
|
||||
`over the last ${criteriaFilter.evaluateOverTimeOptions.timeValueInMinutes} minutes`,
|
||||
);
|
||||
}
|
||||
if (
|
||||
criteriaFilter.eveluateOverTime &&
|
||||
criteriaFilter.evaluateOverTimeOptions?.timeValueInMinutes
|
||||
) {
|
||||
parts.push(
|
||||
`over the last ${criteriaFilter.evaluateOverTimeOptions.timeValueInMinutes} minutes`,
|
||||
);
|
||||
}
|
||||
|
||||
const aggregation: string | undefined =
|
||||
criteriaFilter.evaluateOverTimeOptions?.evaluateOverTimeType ||
|
||||
criteriaFilter.metricMonitorOptions?.metricAggregationType;
|
||||
const aggregation: string | undefined =
|
||||
criteriaFilter.evaluateOverTimeOptions?.evaluateOverTimeType ||
|
||||
criteriaFilter.metricMonitorOptions?.metricAggregationType;
|
||||
|
||||
if (aggregation) {
|
||||
parts.push(`using ${aggregation.toLowerCase()}`);
|
||||
}
|
||||
if (aggregation) {
|
||||
parts.push(`using ${aggregation.toLowerCase()}`);
|
||||
}
|
||||
|
||||
if (!parts.length) {
|
||||
return null;
|
||||
}
|
||||
if (!parts.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parts.join(" ");
|
||||
}
|
||||
return parts.join(" ");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,83 +6,83 @@ import MonitorCriteriaExpectationBuilder from "./MonitorCriteriaExpectationBuild
|
|||
import MonitorCriteriaObservationBuilder from "./MonitorCriteriaObservationBuilder";
|
||||
|
||||
export default class MonitorCriteriaMessageBuilder {
|
||||
public static buildCriteriaFilterMessage(input: {
|
||||
monitor: Monitor;
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
didMeetCriteria: boolean;
|
||||
matchMessage: string | null;
|
||||
}): string {
|
||||
if (input.matchMessage) {
|
||||
return input.matchMessage;
|
||||
}
|
||||
public static buildCriteriaFilterMessage(input: {
|
||||
monitor: Monitor;
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
didMeetCriteria: boolean;
|
||||
matchMessage: string | null;
|
||||
}): string {
|
||||
if (input.matchMessage) {
|
||||
return input.matchMessage;
|
||||
}
|
||||
|
||||
if (input.didMeetCriteria) {
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
if (input.didMeetCriteria) {
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
|
||||
return `${description} condition met.`;
|
||||
}
|
||||
return `${description} condition met.`;
|
||||
}
|
||||
|
||||
const failureMessage: string | null =
|
||||
MonitorCriteriaMessageBuilder.buildCriteriaFilterFailureMessage({
|
||||
monitor: input.monitor,
|
||||
criteriaFilter: input.criteriaFilter,
|
||||
dataToProcess: input.dataToProcess,
|
||||
monitorStep: input.monitorStep,
|
||||
});
|
||||
const failureMessage: string | null =
|
||||
MonitorCriteriaMessageBuilder.buildCriteriaFilterFailureMessage({
|
||||
monitor: input.monitor,
|
||||
criteriaFilter: input.criteriaFilter,
|
||||
dataToProcess: input.dataToProcess,
|
||||
monitorStep: input.monitorStep,
|
||||
});
|
||||
|
||||
if (failureMessage) {
|
||||
return failureMessage;
|
||||
}
|
||||
if (failureMessage) {
|
||||
return failureMessage;
|
||||
}
|
||||
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
|
||||
return `${description} condition was not met.`;
|
||||
}
|
||||
return `${description} condition was not met.`;
|
||||
}
|
||||
|
||||
private static buildCriteriaFilterFailureMessage(input: {
|
||||
monitor: Monitor;
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
}): string | null {
|
||||
const expectation: string | null =
|
||||
MonitorCriteriaExpectationBuilder.describeCriteriaExpectation(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
private static buildCriteriaFilterFailureMessage(input: {
|
||||
monitor: Monitor;
|
||||
criteriaFilter: CriteriaFilter;
|
||||
dataToProcess: DataToProcess;
|
||||
monitorStep: MonitorStep;
|
||||
}): string | null {
|
||||
const expectation: string | null =
|
||||
MonitorCriteriaExpectationBuilder.describeCriteriaExpectation(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
|
||||
const observation: string | null =
|
||||
MonitorCriteriaObservationBuilder.describeFilterObservation({
|
||||
monitor: input.monitor,
|
||||
criteriaFilter: input.criteriaFilter,
|
||||
dataToProcess: input.dataToProcess,
|
||||
monitorStep: input.monitorStep,
|
||||
});
|
||||
const observation: string | null =
|
||||
MonitorCriteriaObservationBuilder.describeFilterObservation({
|
||||
monitor: input.monitor,
|
||||
criteriaFilter: input.criteriaFilter,
|
||||
dataToProcess: input.dataToProcess,
|
||||
monitorStep: input.monitorStep,
|
||||
});
|
||||
|
||||
if (observation) {
|
||||
if (expectation) {
|
||||
return `${observation} (expected ${expectation}).`;
|
||||
}
|
||||
if (observation) {
|
||||
if (expectation) {
|
||||
return `${observation} (expected ${expectation}).`;
|
||||
}
|
||||
|
||||
return `${observation}; configured filter was not met.`;
|
||||
}
|
||||
return `${observation}; configured filter was not met.`;
|
||||
}
|
||||
|
||||
if (expectation) {
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
if (expectation) {
|
||||
const description: string =
|
||||
MonitorCriteriaExpectationBuilder.getCriteriaFilterDescription(
|
||||
input.criteriaFilter,
|
||||
);
|
||||
|
||||
return `${description} did not satisfy the configured condition (${expectation}).`;
|
||||
}
|
||||
return `${description} did not satisfy the configured condition (${expectation}).`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,200 +4,193 @@ import Typeof from "../../../Types/Typeof";
|
|||
import { ServerProcess } from "../../../Types/Monitor/ServerMonitor/ServerMonitorResponse";
|
||||
|
||||
export default class MonitorCriteriaMessageFormatter {
|
||||
public static formatNumber(
|
||||
value: number | null | undefined,
|
||||
options?: { maximumFractionDigits?: number },
|
||||
): string | null {
|
||||
if (value === null || value === undefined || isNaN(value)) {
|
||||
return null;
|
||||
}
|
||||
public static formatNumber(
|
||||
value: number | null | undefined,
|
||||
options?: { maximumFractionDigits?: number },
|
||||
): string | null {
|
||||
if (value === null || value === undefined || isNaN(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const fractionDigits: number =
|
||||
options?.maximumFractionDigits !== undefined
|
||||
? options.maximumFractionDigits
|
||||
: Math.abs(value) < 10
|
||||
? 2
|
||||
: Math.abs(value) < 100
|
||||
? 1
|
||||
: 0;
|
||||
const fractionDigits: number =
|
||||
options?.maximumFractionDigits !== undefined
|
||||
? options.maximumFractionDigits
|
||||
: Math.abs(value) < 10
|
||||
? 2
|
||||
: Math.abs(value) < 100
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
return value.toFixed(fractionDigits);
|
||||
}
|
||||
return value.toFixed(fractionDigits);
|
||||
}
|
||||
|
||||
public static formatPercentage(
|
||||
value: number | null | undefined,
|
||||
): string | null {
|
||||
const formatted: string | null = MonitorCriteriaMessageFormatter.formatNumber(
|
||||
value,
|
||||
{
|
||||
maximumFractionDigits:
|
||||
value !== null && value !== undefined && Math.abs(value) < 100 ? 1 : 0,
|
||||
},
|
||||
);
|
||||
public static formatPercentage(
|
||||
value: number | null | undefined,
|
||||
): string | null {
|
||||
const formatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(value, {
|
||||
maximumFractionDigits:
|
||||
value !== null && value !== undefined && Math.abs(value) < 100
|
||||
? 1
|
||||
: 0,
|
||||
});
|
||||
|
||||
if (!formatted) {
|
||||
return null;
|
||||
}
|
||||
if (!formatted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${formatted}%`;
|
||||
}
|
||||
return `${formatted}%`;
|
||||
}
|
||||
|
||||
public static formatBytes(
|
||||
bytes: number | null | undefined,
|
||||
): string | null {
|
||||
if (bytes === null || bytes === undefined || isNaN(bytes)) {
|
||||
return null;
|
||||
}
|
||||
public static formatBytes(bytes: number | null | undefined): string | null {
|
||||
if (bytes === null || bytes === undefined || isNaN(bytes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const units: Array<string> = ["B", "KB", "MB", "GB", "TB", "PB"];
|
||||
let value: number = bytes;
|
||||
let index: number = 0;
|
||||
const units: Array<string> = ["B", "KB", "MB", "GB", "TB", "PB"];
|
||||
let value: number = bytes;
|
||||
let index: number = 0;
|
||||
|
||||
while (value >= 1024 && index < units.length - 1) {
|
||||
value = value / 1024;
|
||||
index++;
|
||||
}
|
||||
while (value >= 1024 && index < units.length - 1) {
|
||||
value = value / 1024;
|
||||
index++;
|
||||
}
|
||||
|
||||
const formatted: string | null = MonitorCriteriaMessageFormatter.formatNumber(
|
||||
value,
|
||||
{
|
||||
maximumFractionDigits: value >= 100 ? 0 : value >= 10 ? 1 : 2,
|
||||
},
|
||||
);
|
||||
const formatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(value, {
|
||||
maximumFractionDigits: value >= 100 ? 0 : value >= 10 ? 1 : 2,
|
||||
});
|
||||
|
||||
if (!formatted) {
|
||||
return null;
|
||||
}
|
||||
if (!formatted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${formatted} ${units[index]}`;
|
||||
}
|
||||
return `${formatted} ${units[index]}`;
|
||||
}
|
||||
|
||||
public static formatList(
|
||||
items: Array<string>,
|
||||
maxItems: number = 5,
|
||||
): string {
|
||||
if (!items.length) {
|
||||
return "";
|
||||
}
|
||||
public static formatList(items: Array<string>, maxItems: number = 5): string {
|
||||
if (!items.length) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const trimmedItems: Array<string> = items.slice(0, maxItems);
|
||||
const suffix: string =
|
||||
items.length > maxItems ? `, +${items.length - maxItems} more` : "";
|
||||
const trimmedItems: Array<string> = items.slice(0, maxItems);
|
||||
const suffix: string =
|
||||
items.length > maxItems ? `, +${items.length - maxItems} more` : "";
|
||||
|
||||
return `${trimmedItems.join(", ")} ${suffix}`.trim();
|
||||
}
|
||||
return `${trimmedItems.join(", ")} ${suffix}`.trim();
|
||||
}
|
||||
|
||||
public static formatSnippet(text: string, maxLength: number = 120): string {
|
||||
const sanitized: string = text.replace(/\s+/g, " ").trim();
|
||||
public static formatSnippet(text: string, maxLength: number = 120): string {
|
||||
const sanitized: string = text.replace(/\s+/g, " ").trim();
|
||||
|
||||
if (sanitized.length <= maxLength) {
|
||||
return sanitized;
|
||||
}
|
||||
if (sanitized.length <= maxLength) {
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
return `${sanitized.slice(0, maxLength)}…`;
|
||||
}
|
||||
return `${sanitized.slice(0, maxLength)}…`;
|
||||
}
|
||||
|
||||
public static describeProcesses(
|
||||
processes: Array<ServerProcess>,
|
||||
): string | null {
|
||||
if (!processes.length) {
|
||||
return null;
|
||||
}
|
||||
public static describeProcesses(
|
||||
processes: Array<ServerProcess>,
|
||||
): string | null {
|
||||
if (!processes.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const processSummaries: Array<string> = processes.map(
|
||||
(process: ServerProcess) => {
|
||||
return `${process.name} (pid ${process.pid})`;
|
||||
},
|
||||
);
|
||||
const processSummaries: Array<string> = processes.map(
|
||||
(process: ServerProcess) => {
|
||||
return `${process.name} (pid ${process.pid})`;
|
||||
},
|
||||
);
|
||||
|
||||
return MonitorCriteriaMessageFormatter.formatList(processSummaries);
|
||||
}
|
||||
return MonitorCriteriaMessageFormatter.formatList(processSummaries);
|
||||
}
|
||||
|
||||
public static computeDiskUsagePercent(
|
||||
diskMetric: BasicInfrastructureMetrics["diskMetrics"][number],
|
||||
): number | null {
|
||||
if (!diskMetric) {
|
||||
return null;
|
||||
}
|
||||
public static computeDiskUsagePercent(
|
||||
diskMetric: BasicInfrastructureMetrics["diskMetrics"][number],
|
||||
): number | null {
|
||||
if (!diskMetric) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
diskMetric.percentUsed !== undefined &&
|
||||
diskMetric.percentUsed !== null &&
|
||||
!isNaN(diskMetric.percentUsed)
|
||||
) {
|
||||
return diskMetric.percentUsed;
|
||||
}
|
||||
if (
|
||||
diskMetric.percentUsed !== undefined &&
|
||||
diskMetric.percentUsed !== null &&
|
||||
!isNaN(diskMetric.percentUsed)
|
||||
) {
|
||||
return diskMetric.percentUsed;
|
||||
}
|
||||
|
||||
if (
|
||||
diskMetric.percentFree !== undefined &&
|
||||
diskMetric.percentFree !== null &&
|
||||
!isNaN(diskMetric.percentFree)
|
||||
) {
|
||||
return 100 - diskMetric.percentFree;
|
||||
}
|
||||
if (
|
||||
diskMetric.percentFree !== undefined &&
|
||||
diskMetric.percentFree !== null &&
|
||||
!isNaN(diskMetric.percentFree)
|
||||
) {
|
||||
return 100 - diskMetric.percentFree;
|
||||
}
|
||||
|
||||
if (diskMetric.total && diskMetric.used && diskMetric.total > 0) {
|
||||
return (diskMetric.used / diskMetric.total) * 100;
|
||||
}
|
||||
if (diskMetric.total && diskMetric.used && diskMetric.total > 0) {
|
||||
return (diskMetric.used / diskMetric.total) * 100;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static summarizeNumericSeries(values: Array<number>): string | null {
|
||||
if (!values.length) {
|
||||
return null;
|
||||
}
|
||||
public static summarizeNumericSeries(values: Array<number>): string | null {
|
||||
if (!values.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const latest: number | undefined = values[values.length - 1];
|
||||
const latest: number | undefined = values[values.length - 1];
|
||||
|
||||
if (latest === undefined) {
|
||||
return null;
|
||||
}
|
||||
if (latest === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const latestFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(latest, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
const latestFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(latest, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
let summary: string = `latest ${latestFormatted ?? latest}`;
|
||||
let summary: string = `latest ${latestFormatted ?? latest}`;
|
||||
|
||||
if (values.length > 1) {
|
||||
const min: number = Math.min(...values);
|
||||
const max: number = Math.max(...values);
|
||||
if (values.length > 1) {
|
||||
const min: number = Math.min(...values);
|
||||
const max: number = Math.max(...values);
|
||||
|
||||
const minFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(min, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
const maxFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(max, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
const minFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(min, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
const maxFormatted: string | null =
|
||||
MonitorCriteriaMessageFormatter.formatNumber(max, {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
summary += ` (min ${minFormatted ?? min}, max ${maxFormatted ?? max})`;
|
||||
}
|
||||
summary += ` (min ${minFormatted ?? min}, max ${maxFormatted ?? max})`;
|
||||
}
|
||||
|
||||
summary += ` across ${values.length} data point${
|
||||
values.length === 1 ? "" : "s"
|
||||
}`;
|
||||
summary += ` across ${values.length} data point${
|
||||
values.length === 1 ? "" : "s"
|
||||
}`;
|
||||
|
||||
return summary;
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
public static formatResultValue(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "undefined";
|
||||
}
|
||||
public static formatResultValue(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "undefined";
|
||||
}
|
||||
|
||||
if (typeof value === Typeof.Object) {
|
||||
try {
|
||||
return JSON.stringify(value);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
return "[object]";
|
||||
}
|
||||
}
|
||||
if (typeof value === Typeof.Object) {
|
||||
try {
|
||||
return JSON.stringify(value);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
return "[object]";
|
||||
}
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,7 +3,10 @@ import CaptureSpan from "../Telemetry/CaptureSpan";
|
|||
import TelemetryUtil from "../Telemetry/Telemetry";
|
||||
import MetricService from "../../Services/MetricService";
|
||||
import DataToProcess from "./DataToProcess";
|
||||
import { MetricPointType, ServiceType } from "../../../Models/AnalyticsModels/Metric";
|
||||
import {
|
||||
MetricPointType,
|
||||
ServiceType,
|
||||
} from "../../../Models/AnalyticsModels/Metric";
|
||||
import MetricType from "../../../Models/DatabaseModels/MetricType";
|
||||
import BasicInfrastructureMetrics from "../../../Types/Infrastructure/BasicMetrics";
|
||||
import Dictionary from "../../../Types/Dictionary";
|
||||
|
|
@ -17,464 +20,463 @@ import ObjectID from "../../../Types/ObjectID";
|
|||
import OneUptimeDate from "../../../Types/Date";
|
||||
|
||||
export default class MonitorMetricUtil {
|
||||
private static buildMonitorMetricAttributes(data: {
|
||||
monitorId: ObjectID;
|
||||
projectId: ObjectID;
|
||||
monitorName?: string | undefined;
|
||||
probeName?: string | undefined;
|
||||
extraAttributes?: JSONObject;
|
||||
}): JSONObject {
|
||||
const attributes: JSONObject = {
|
||||
monitorId: data.monitorId.toString(),
|
||||
projectId: data.projectId.toString(),
|
||||
};
|
||||
|
||||
if (data.extraAttributes) {
|
||||
Object.assign(attributes, data.extraAttributes);
|
||||
}
|
||||
|
||||
if (data.monitorName) {
|
||||
attributes["monitorName"] = data.monitorName;
|
||||
}
|
||||
|
||||
if (data.probeName) {
|
||||
attributes["probeName"] = data.probeName;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private static buildMonitorMetricRow(data: {
|
||||
projectId: ObjectID;
|
||||
monitorId: ObjectID;
|
||||
metricName: string;
|
||||
value: number | null | undefined;
|
||||
attributes: JSONObject;
|
||||
metricPointType?: MetricPointType;
|
||||
}): JSONObject {
|
||||
const ingestionDate: Date = OneUptimeDate.getCurrentDate();
|
||||
const ingestionTimestamp: string =
|
||||
OneUptimeDate.toClickhouseDateTime(ingestionDate);
|
||||
const timeUnixNano: string =
|
||||
OneUptimeDate.toUnixNano(ingestionDate).toString();
|
||||
|
||||
const attributes: JSONObject = { ...data.attributes };
|
||||
const attributeKeys: Array<string> =
|
||||
TelemetryUtil.getAttributeKeys(attributes);
|
||||
|
||||
return {
|
||||
_id: ObjectID.generate().toString(),
|
||||
createdAt: ingestionTimestamp,
|
||||
updatedAt: ingestionTimestamp,
|
||||
projectId: data.projectId.toString(),
|
||||
serviceId: data.monitorId.toString(),
|
||||
serviceType: ServiceType.Monitor,
|
||||
name: data.metricName,
|
||||
aggregationTemporality: null,
|
||||
metricPointType: data.metricPointType || MetricPointType.Sum,
|
||||
time: ingestionTimestamp,
|
||||
startTime: null,
|
||||
timeUnixNano: timeUnixNano,
|
||||
startTimeUnixNano: null,
|
||||
attributes: attributes,
|
||||
attributeKeys: attributeKeys,
|
||||
isMonotonic: null,
|
||||
count: null,
|
||||
sum: null,
|
||||
min: null,
|
||||
max: null,
|
||||
bucketCounts: [],
|
||||
explicitBounds: [],
|
||||
value: data.value ?? null,
|
||||
} as JSONObject;
|
||||
}
|
||||
|
||||
@CaptureSpan()
|
||||
public static async saveMonitorMetrics(data: {
|
||||
monitorId: ObjectID;
|
||||
projectId: ObjectID;
|
||||
dataToProcess: DataToProcess;
|
||||
probeName: string | undefined;
|
||||
monitorName: string | undefined;
|
||||
}): Promise<void> {
|
||||
if (!data.monitorId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.dataToProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
const metricRows: Array<JSONObject> = [];
|
||||
|
||||
/*
|
||||
* Metric name to serviceId map
|
||||
* example: "cpu.usage" -> [serviceId1, serviceId2]
|
||||
* since these are monitor metrics. They dont belong to any service so we can keep the array empty.
|
||||
*/
|
||||
const metricNameServiceNameMap: Dictionary<MetricType> = {};
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ServerMonitorResponse).basicInfrastructureMetrics
|
||||
) {
|
||||
// store cpu, memory, disk metrics.
|
||||
|
||||
if ((data.dataToProcess as ServerMonitorResponse).requestReceivedAt) {
|
||||
let isOnline: boolean = true;
|
||||
|
||||
const differenceInMinutes: number =
|
||||
OneUptimeDate.getDifferenceInMinutes(
|
||||
(data.dataToProcess as ServerMonitorResponse).requestReceivedAt,
|
||||
OneUptimeDate.getCurrentDate(),
|
||||
);
|
||||
|
||||
if (differenceInMinutes > 2) {
|
||||
isOnline = false;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.IsOnline,
|
||||
value: isOnline ? 1 : 0,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
// add MetricType
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.IsOnline;
|
||||
metricType.description = CheckOn.IsOnline + " status for monitor";
|
||||
metricType.unit = "";
|
||||
|
||||
// add to map
|
||||
metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
|
||||
}
|
||||
|
||||
const basicMetrics: BasicInfrastructureMetrics | undefined = (
|
||||
data.dataToProcess as ServerMonitorResponse
|
||||
).basicInfrastructureMetrics;
|
||||
|
||||
if (!basicMetrics) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (basicMetrics.cpuMetrics) {
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.CPUUsagePercent,
|
||||
value: basicMetrics.cpuMetrics.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.CPUUsagePercent;
|
||||
metricType.description = CheckOn.CPUUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.CPUUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (basicMetrics.memoryMetrics) {
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.MemoryUsagePercent,
|
||||
value: basicMetrics.memoryMetrics.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.MemoryUsagePercent;
|
||||
metricType.description = CheckOn.MemoryUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.MemoryUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (basicMetrics.diskMetrics && basicMetrics.diskMetrics.length > 0) {
|
||||
for (const diskMetric of basicMetrics.diskMetrics) {
|
||||
const extraAttributes: JSONObject = {};
|
||||
|
||||
if (diskMetric.diskPath) {
|
||||
extraAttributes["diskPath"] = diskMetric.diskPath;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.DiskUsagePercent,
|
||||
value: diskMetric.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.DiskUsagePercent;
|
||||
metricType.description = CheckOn.DiskUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.DiskUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
|
||||
?.executionTimeInMS
|
||||
) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ExecutionTime,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
|
||||
?.executionTimeInMS ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ExecutionTime;
|
||||
metricType.description = CheckOn.ExecutionTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
|
||||
}
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ProbeMonitorResponse) &&
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse &&
|
||||
(
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse ||
|
||||
[]
|
||||
).length > 0
|
||||
) {
|
||||
const syntheticResponses: Array<SyntheticMonitorResponse> =
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse ||
|
||||
[];
|
||||
|
||||
for (const syntheticMonitorResponse of syntheticResponses) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
if (syntheticMonitorResponse.browserType) {
|
||||
extraAttributes["browserType"] = syntheticMonitorResponse.browserType;
|
||||
}
|
||||
|
||||
if (syntheticMonitorResponse.screenSizeType) {
|
||||
extraAttributes["screenSizeType"] =
|
||||
syntheticMonitorResponse.screenSizeType;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ExecutionTime,
|
||||
value: syntheticMonitorResponse.executionTimeInMS ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ExecutionTime;
|
||||
metricType.description = CheckOn.ExecutionTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).responseTimeInMs) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ResponseTime,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).responseTimeInMs ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ResponseTime;
|
||||
metricType.description = CheckOn.ResponseTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ResponseTime] = metricType;
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).isOnline !== undefined) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.IsOnline,
|
||||
value: (data.dataToProcess as ProbeMonitorResponse).isOnline ? 1 : 0,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.IsOnline;
|
||||
metricType.description = CheckOn.IsOnline + " status for monitor";
|
||||
metricType.unit = "";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).responseCode) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ResponseStatusCode,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).responseCode ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ResponseStatusCode;
|
||||
metricType.description = CheckOn.ResponseStatusCode +
|
||||
" for this monitor";
|
||||
metricType.unit = "Status Code";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ResponseStatusCode] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (metricRows.length > 0) {
|
||||
await MetricService.insertJsonRows(metricRows);
|
||||
}
|
||||
|
||||
// index metrics
|
||||
TelemetryUtil.indexMetricNameServiceNameMap({
|
||||
projectId: data.projectId,
|
||||
metricNameServiceNameMap: metricNameServiceNameMap,
|
||||
}).catch((err: Error) => {
|
||||
logger.error(err);
|
||||
});
|
||||
}
|
||||
private static buildMonitorMetricAttributes(data: {
|
||||
monitorId: ObjectID;
|
||||
projectId: ObjectID;
|
||||
monitorName?: string | undefined;
|
||||
probeName?: string | undefined;
|
||||
extraAttributes?: JSONObject;
|
||||
}): JSONObject {
|
||||
const attributes: JSONObject = {
|
||||
monitorId: data.monitorId.toString(),
|
||||
projectId: data.projectId.toString(),
|
||||
};
|
||||
|
||||
if (data.extraAttributes) {
|
||||
Object.assign(attributes, data.extraAttributes);
|
||||
}
|
||||
|
||||
if (data.monitorName) {
|
||||
attributes["monitorName"] = data.monitorName;
|
||||
}
|
||||
|
||||
if (data.probeName) {
|
||||
attributes["probeName"] = data.probeName;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private static buildMonitorMetricRow(data: {
|
||||
projectId: ObjectID;
|
||||
monitorId: ObjectID;
|
||||
metricName: string;
|
||||
value: number | null | undefined;
|
||||
attributes: JSONObject;
|
||||
metricPointType?: MetricPointType;
|
||||
}): JSONObject {
|
||||
const ingestionDate: Date = OneUptimeDate.getCurrentDate();
|
||||
const ingestionTimestamp: string =
|
||||
OneUptimeDate.toClickhouseDateTime(ingestionDate);
|
||||
const timeUnixNano: string =
|
||||
OneUptimeDate.toUnixNano(ingestionDate).toString();
|
||||
|
||||
const attributes: JSONObject = { ...data.attributes };
|
||||
const attributeKeys: Array<string> =
|
||||
TelemetryUtil.getAttributeKeys(attributes);
|
||||
|
||||
return {
|
||||
_id: ObjectID.generate().toString(),
|
||||
createdAt: ingestionTimestamp,
|
||||
updatedAt: ingestionTimestamp,
|
||||
projectId: data.projectId.toString(),
|
||||
serviceId: data.monitorId.toString(),
|
||||
serviceType: ServiceType.Monitor,
|
||||
name: data.metricName,
|
||||
aggregationTemporality: null,
|
||||
metricPointType: data.metricPointType || MetricPointType.Sum,
|
||||
time: ingestionTimestamp,
|
||||
startTime: null,
|
||||
timeUnixNano: timeUnixNano,
|
||||
startTimeUnixNano: null,
|
||||
attributes: attributes,
|
||||
attributeKeys: attributeKeys,
|
||||
isMonotonic: null,
|
||||
count: null,
|
||||
sum: null,
|
||||
min: null,
|
||||
max: null,
|
||||
bucketCounts: [],
|
||||
explicitBounds: [],
|
||||
value: data.value ?? null,
|
||||
} as JSONObject;
|
||||
}
|
||||
|
||||
@CaptureSpan()
|
||||
public static async saveMonitorMetrics(data: {
|
||||
monitorId: ObjectID;
|
||||
projectId: ObjectID;
|
||||
dataToProcess: DataToProcess;
|
||||
probeName: string | undefined;
|
||||
monitorName: string | undefined;
|
||||
}): Promise<void> {
|
||||
if (!data.monitorId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.dataToProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
const metricRows: Array<JSONObject> = [];
|
||||
|
||||
/*
|
||||
* Metric name to serviceId map
|
||||
* example: "cpu.usage" -> [serviceId1, serviceId2]
|
||||
* since these are monitor metrics. They dont belong to any service so we can keep the array empty.
|
||||
*/
|
||||
const metricNameServiceNameMap: Dictionary<MetricType> = {};
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ServerMonitorResponse).basicInfrastructureMetrics
|
||||
) {
|
||||
// store cpu, memory, disk metrics.
|
||||
|
||||
if ((data.dataToProcess as ServerMonitorResponse).requestReceivedAt) {
|
||||
let isOnline: boolean = true;
|
||||
|
||||
const differenceInMinutes: number =
|
||||
OneUptimeDate.getDifferenceInMinutes(
|
||||
(data.dataToProcess as ServerMonitorResponse).requestReceivedAt,
|
||||
OneUptimeDate.getCurrentDate(),
|
||||
);
|
||||
|
||||
if (differenceInMinutes > 2) {
|
||||
isOnline = false;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.IsOnline,
|
||||
value: isOnline ? 1 : 0,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
// add MetricType
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.IsOnline;
|
||||
metricType.description = CheckOn.IsOnline + " status for monitor";
|
||||
metricType.unit = "";
|
||||
|
||||
// add to map
|
||||
metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
|
||||
}
|
||||
|
||||
const basicMetrics: BasicInfrastructureMetrics | undefined = (
|
||||
data.dataToProcess as ServerMonitorResponse
|
||||
).basicInfrastructureMetrics;
|
||||
|
||||
if (!basicMetrics) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (basicMetrics.cpuMetrics) {
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.CPUUsagePercent,
|
||||
value: basicMetrics.cpuMetrics.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.CPUUsagePercent;
|
||||
metricType.description = CheckOn.CPUUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.CPUUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (basicMetrics.memoryMetrics) {
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.MemoryUsagePercent,
|
||||
value: basicMetrics.memoryMetrics.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.MemoryUsagePercent;
|
||||
metricType.description = CheckOn.MemoryUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.MemoryUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (basicMetrics.diskMetrics && basicMetrics.diskMetrics.length > 0) {
|
||||
for (const diskMetric of basicMetrics.diskMetrics) {
|
||||
const extraAttributes: JSONObject = {};
|
||||
|
||||
if (diskMetric.diskPath) {
|
||||
extraAttributes["diskPath"] = diskMetric.diskPath;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.DiskUsagePercent,
|
||||
value: diskMetric.percentUsed ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.DiskUsagePercent;
|
||||
metricType.description = CheckOn.DiskUsagePercent + " of Server/VM";
|
||||
metricType.unit = "%";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.DiskUsagePercent] =
|
||||
metricType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
|
||||
?.executionTimeInMS
|
||||
) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ExecutionTime,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
|
||||
?.executionTimeInMS ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ExecutionTime;
|
||||
metricType.description = CheckOn.ExecutionTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
|
||||
}
|
||||
|
||||
if (
|
||||
(data.dataToProcess as ProbeMonitorResponse) &&
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse &&
|
||||
(
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse ||
|
||||
[]
|
||||
).length > 0
|
||||
) {
|
||||
const syntheticResponses: Array<SyntheticMonitorResponse> =
|
||||
(data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse ||
|
||||
[];
|
||||
|
||||
for (const syntheticMonitorResponse of syntheticResponses) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
if (syntheticMonitorResponse.browserType) {
|
||||
extraAttributes["browserType"] = syntheticMonitorResponse.browserType;
|
||||
}
|
||||
|
||||
if (syntheticMonitorResponse.screenSizeType) {
|
||||
extraAttributes["screenSizeType"] =
|
||||
syntheticMonitorResponse.screenSizeType;
|
||||
}
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ExecutionTime,
|
||||
value: syntheticMonitorResponse.executionTimeInMS ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ExecutionTime;
|
||||
metricType.description = CheckOn.ExecutionTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).responseTimeInMs) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ResponseTime,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).responseTimeInMs ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ResponseTime;
|
||||
metricType.description = CheckOn.ResponseTime + " of this monitor";
|
||||
metricType.unit = "ms";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ResponseTime] = metricType;
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).isOnline !== undefined) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.IsOnline,
|
||||
value: (data.dataToProcess as ProbeMonitorResponse).isOnline ? 1 : 0,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.IsOnline;
|
||||
metricType.description = CheckOn.IsOnline + " status for monitor";
|
||||
metricType.unit = "";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
|
||||
}
|
||||
|
||||
if ((data.dataToProcess as ProbeMonitorResponse).responseCode) {
|
||||
const extraAttributes: JSONObject = {
|
||||
probeId: (
|
||||
data.dataToProcess as ProbeMonitorResponse
|
||||
).probeId.toString(),
|
||||
};
|
||||
|
||||
const attributes: JSONObject = this.buildMonitorMetricAttributes({
|
||||
monitorId: data.monitorId,
|
||||
projectId: data.projectId,
|
||||
monitorName: data.monitorName,
|
||||
probeName: data.probeName,
|
||||
extraAttributes: extraAttributes,
|
||||
});
|
||||
|
||||
const metricRow: JSONObject = this.buildMonitorMetricRow({
|
||||
projectId: data.projectId,
|
||||
monitorId: data.monitorId,
|
||||
metricName: MonitorMetricType.ResponseStatusCode,
|
||||
value:
|
||||
(data.dataToProcess as ProbeMonitorResponse).responseCode ?? null,
|
||||
attributes: attributes,
|
||||
metricPointType: MetricPointType.Sum,
|
||||
});
|
||||
|
||||
metricRows.push(metricRow);
|
||||
|
||||
const metricType: MetricType = new MetricType();
|
||||
metricType.name = MonitorMetricType.ResponseStatusCode;
|
||||
metricType.description = CheckOn.ResponseStatusCode + " for this monitor";
|
||||
metricType.unit = "Status Code";
|
||||
|
||||
metricNameServiceNameMap[MonitorMetricType.ResponseStatusCode] =
|
||||
metricType;
|
||||
}
|
||||
|
||||
if (metricRows.length > 0) {
|
||||
await MetricService.insertJsonRows(metricRows);
|
||||
}
|
||||
|
||||
// index metrics
|
||||
TelemetryUtil.indexMetricNameServiceNameMap({
|
||||
projectId: data.projectId,
|
||||
metricNameServiceNameMap: metricNameServiceNameMap,
|
||||
}).catch((err: Error) => {
|
||||
logger.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import ProbeApiIngestResponse from "../../../Types/Probe/ProbeApiIngestResponse"
|
|||
import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
|
||||
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
||||
import MonitorProbe from "../../../Models/DatabaseModels/MonitorProbe";
|
||||
import MonitorStatus from "../../../Models/DatabaseModels/MonitorStatus";
|
||||
import MonitorStatusTimeline from "../../../Models/DatabaseModels/MonitorStatusTimeline";
|
||||
import OneUptimeDate from "../../../Types/Date";
|
||||
import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResponse";
|
||||
|
|
@ -87,17 +88,18 @@ export default class MonitorResourceUtil {
|
|||
return monitorStatusNameCache[cacheKey];
|
||||
}
|
||||
|
||||
const monitorStatus = await MonitorStatusService.findOneBy({
|
||||
query: {
|
||||
_id: statusId,
|
||||
},
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
const monitorStatus: MonitorStatus | null =
|
||||
await MonitorStatusService.findOneBy({
|
||||
query: {
|
||||
_id: statusId,
|
||||
},
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
const statusName: string | null = monitorStatus?.name || null;
|
||||
monitorStatusNameCache[cacheKey] = statusName;
|
||||
|
|
|
|||
|
|
@ -116,8 +116,7 @@ const EvaluationLogList: FunctionComponent<ComponentProps> = (
|
|||
const renderEventAction: () => ReactElement | null = () => {
|
||||
if (
|
||||
event.relatedIncidentId &&
|
||||
(event.type === "incident-created" ||
|
||||
event.type === "incident-skipped")
|
||||
(event.type === "incident-created" || event.type === "incident-skipped")
|
||||
) {
|
||||
const incidentRoute: Route = RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.INCIDENT_VIEW] as Route,
|
||||
|
|
@ -140,8 +139,7 @@ const EvaluationLogList: FunctionComponent<ComponentProps> = (
|
|||
|
||||
if (
|
||||
event.relatedAlertId &&
|
||||
(event.type === "alert-created" ||
|
||||
event.type === "alert-skipped")
|
||||
(event.type === "alert-created" || event.type === "alert-skipped")
|
||||
) {
|
||||
const alertRoute: Route = RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.ALERT_VIEW] as Route,
|
||||
|
|
|
|||
|
|
@ -118,11 +118,9 @@ const SummaryInfo: FunctionComponent<ComponentProps> = (
|
|||
|
||||
const probableMonitorEvaluationSummary: MonitorEvaluationSummary | undefined =
|
||||
props.evaluationSummary ||
|
||||
props.probeMonitorResponses?.find(
|
||||
(response: ProbeMonitorResponse) => {
|
||||
return Boolean(response.evaluationSummary);
|
||||
},
|
||||
)?.evaluationSummary;
|
||||
props.probeMonitorResponses?.find((response: ProbeMonitorResponse) => {
|
||||
return Boolean(response.evaluationSummary);
|
||||
})?.evaluationSummary;
|
||||
|
||||
if (
|
||||
MonitorTypeHelper.isProbableMonitor(props.monitorType) &&
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue