mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
245 lines
7.0 KiB
TypeScript
245 lines
7.0 KiB
TypeScript
import OneUptimeDate from "Common/Types/Date";
|
|
import RunCron from "../../Utils/Cron";
|
|
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
|
|
import MonitorType from "Common/Types/Monitor/MonitorType";
|
|
import { EVERY_MINUTE } from "Common/Utils/CronTime";
|
|
import MonitorService from "Common/Server/Services/MonitorService";
|
|
import logger from "Common/Server/Utils/Logger";
|
|
import MonitorResourceUtil from "Common/Server/Utils/Monitor/MonitorResource";
|
|
import Monitor from "Common/Models/DatabaseModels/Monitor";
|
|
import CronTab from "Common/Server/Utils/CronTab";
|
|
import MonitorStep from "Common/Types/Monitor/MonitorStep";
|
|
import LogMonitorResponse from "Common/Types/Monitor/LogMonitor/LogMonitorResponse";
|
|
import MonitorStepLogMonitor, {
|
|
MonitorStepLogMonitorUtil,
|
|
} from "Common/Types/Monitor/MonitorStepLogMonitor";
|
|
import BadDataException from "Common/Types/Exception/BadDataException";
|
|
import LogService from "Common/Server/Services/LogService";
|
|
import Query from "Common/Server/Types/AnalyticsDatabase/Query";
|
|
import Log from "Common/Models/AnalyticsModels/Log";
|
|
import PositiveNumber from "Common/Types/PositiveNumber";
|
|
import JSONFunctions from "Common/Types/JSONFunctions";
|
|
import DatabaseQueryHelper from "Common/Server/Types/Database/QueryHelper";
|
|
import ObjectID from "Common/Types/ObjectID";
|
|
import TraceMonitorResponse from "Common/Types/Monitor/TraceMonitor/TraceMonitorResponse";
|
|
import MonitorStepTraceMonitor, {
|
|
MonitorStepTraceMonitorUtil,
|
|
} from "Common/Types/Monitor/MonitorStepTraceMonitor";
|
|
import SpanService from "Common/Server/Services/SpanService";
|
|
|
|
RunCron(
|
|
"LogMonitor:MonitorLogMonitor",
|
|
{ schedule: EVERY_MINUTE, runOnStartup: false },
|
|
async () => {
|
|
logger.debug("Checking LogMonitor:MonitorLogMonitor");
|
|
|
|
const telemetryMonitors: Array<Monitor> = await MonitorService.findBy({
|
|
query: {
|
|
disableActiveMonitoring: false,
|
|
disableActiveMonitoringBecauseOfScheduledMaintenanceEvent: false,
|
|
disableActiveMonitoringBecauseOfManualIncident: false,
|
|
|
|
monitorType: DatabaseQueryHelper.any([
|
|
MonitorType.Logs,
|
|
MonitorType.Traces,
|
|
MonitorType.Metrics,
|
|
]),
|
|
telemetryMonitorNextMonitorAt:
|
|
DatabaseQueryHelper.lessThanEqualToOrNull(
|
|
OneUptimeDate.getCurrentDate(),
|
|
),
|
|
},
|
|
props: {
|
|
isRoot: true,
|
|
},
|
|
select: {
|
|
_id: true,
|
|
monitorSteps: true,
|
|
createdAt: true,
|
|
monitoringInterval: true,
|
|
monitorType: true,
|
|
},
|
|
limit: LIMIT_MAX,
|
|
skip: 0,
|
|
});
|
|
|
|
const updatePromises: Array<Promise<void>> = [];
|
|
|
|
for (const telemetryMonitor of telemetryMonitors) {
|
|
if (!telemetryMonitor.monitoringInterval) {
|
|
continue;
|
|
}
|
|
|
|
let nextPing: Date = OneUptimeDate.addRemoveMinutes(
|
|
OneUptimeDate.getCurrentDate(),
|
|
1,
|
|
);
|
|
|
|
try {
|
|
nextPing = CronTab.getNextExecutionTime(
|
|
telemetryMonitor?.monitoringInterval as string,
|
|
);
|
|
} catch (err) {
|
|
logger.error(err);
|
|
}
|
|
|
|
updatePromises.push(
|
|
MonitorService.updateOneById({
|
|
id: telemetryMonitor.id!,
|
|
data: {
|
|
telemetryMonitorLastMonitorAt: OneUptimeDate.getCurrentDate(),
|
|
telemetryMonitorNextMonitorAt: nextPing,
|
|
},
|
|
props: {
|
|
isRoot: true,
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
|
|
await Promise.all(updatePromises);
|
|
|
|
logger.debug(`Found ${telemetryMonitors.length} telemetry monitors`);
|
|
|
|
logger.debug(telemetryMonitors);
|
|
|
|
const monitorResponses: Array<
|
|
Promise<LogMonitorResponse | TraceMonitorResponse>
|
|
> = [];
|
|
|
|
for (const monitor of telemetryMonitors) {
|
|
try {
|
|
if (
|
|
!monitor.monitorSteps ||
|
|
!monitor.monitorSteps.data?.monitorStepsInstanceArray?.length ||
|
|
monitor.monitorSteps.data.monitorStepsInstanceArray.length === 0
|
|
) {
|
|
logger.debug("Monitor has no steps. Skipping...");
|
|
continue;
|
|
}
|
|
|
|
monitorResponses.push(
|
|
monitorTelemetryMonitor({
|
|
monitorStep:
|
|
monitor.monitorSteps.data!.monitorStepsInstanceArray[0]!,
|
|
monitorType: monitor.monitorType!,
|
|
monitorId: monitor.id!,
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
logger.error(
|
|
`Error while processing incoming request monitor: ${monitor.id?.toString()}`,
|
|
);
|
|
logger.error(error);
|
|
}
|
|
}
|
|
|
|
const responses: Array<LogMonitorResponse | TraceMonitorResponse> =
|
|
await Promise.all(monitorResponses);
|
|
|
|
for (const response of responses) {
|
|
MonitorResourceUtil.monitorResource(response);
|
|
}
|
|
},
|
|
);
|
|
|
|
type MonitorTelemetryMonitorFunction = (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorType: MonitorType;
|
|
monitorId: ObjectID;
|
|
}) => Promise<LogMonitorResponse | TraceMonitorResponse>;
|
|
|
|
const monitorTelemetryMonitor: MonitorTelemetryMonitorFunction = async (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorType: MonitorType;
|
|
monitorId: ObjectID;
|
|
}): Promise<LogMonitorResponse | TraceMonitorResponse> => {
|
|
const { monitorStep, monitorType, monitorId } = data;
|
|
|
|
if (monitorType === MonitorType.Logs) {
|
|
return monitorLogs({
|
|
monitorStep,
|
|
monitorId,
|
|
});
|
|
}
|
|
|
|
if (monitorType === MonitorType.Traces) {
|
|
return monitorTrace({
|
|
monitorStep,
|
|
monitorId,
|
|
});
|
|
}
|
|
|
|
throw new BadDataException("Monitor type is not supported");
|
|
};
|
|
|
|
type MonitorTraceFunction = (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorId: ObjectID;
|
|
}) => Promise<TraceMonitorResponse>;
|
|
|
|
const monitorTrace: MonitorTraceFunction = async (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorId: ObjectID;
|
|
}): Promise<TraceMonitorResponse> => {
|
|
// Monitor traces
|
|
const traceQuery: MonitorStepTraceMonitor | undefined =
|
|
data.monitorStep.data?.traceMonitor;
|
|
|
|
if (!traceQuery) {
|
|
throw new BadDataException("Trace query is missing");
|
|
}
|
|
|
|
const query: Query<Log> = MonitorStepTraceMonitorUtil.toQuery(traceQuery);
|
|
|
|
const countTraces: PositiveNumber = await SpanService.countBy({
|
|
query: query,
|
|
limit: LIMIT_PER_PROJECT,
|
|
skip: 0,
|
|
props: {
|
|
isRoot: true,
|
|
},
|
|
});
|
|
|
|
return {
|
|
spanCount: countTraces.toNumber(),
|
|
spanQuery: query,
|
|
monitorId: data.monitorId,
|
|
};
|
|
};
|
|
|
|
type MonitorLogsFunction = (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorId: ObjectID;
|
|
}) => Promise<LogMonitorResponse>;
|
|
|
|
const monitorLogs: MonitorLogsFunction = async (data: {
|
|
monitorStep: MonitorStep;
|
|
monitorId: ObjectID;
|
|
}): Promise<LogMonitorResponse> => {
|
|
// Monitor logs
|
|
const logQuery: MonitorStepLogMonitor | undefined =
|
|
data.monitorStep.data?.logMonitor;
|
|
|
|
if (!logQuery) {
|
|
throw new BadDataException("Log query is missing");
|
|
}
|
|
|
|
const query: Query<Log> = MonitorStepLogMonitorUtil.toQuery(logQuery);
|
|
|
|
const countLogs: PositiveNumber = await LogService.countBy({
|
|
query: query,
|
|
limit: LIMIT_PER_PROJECT,
|
|
skip: 0,
|
|
props: {
|
|
isRoot: true,
|
|
},
|
|
});
|
|
|
|
return {
|
|
logCount: countLogs.toNumber(),
|
|
logQuery: JSONFunctions.anyObjectToJSONObject(query),
|
|
monitorId: data.monitorId,
|
|
};
|
|
};
|