mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
add logs to monitor probe
This commit is contained in:
@@ -117,7 +117,7 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
|
||||
title: `${arg.monitorType} monitor is offline`,
|
||||
description: `${arg.monitorType} monitor is currently offline.`,
|
||||
incidentSeverityId: arg.incidentSeverityId,
|
||||
autoResolveIncident: false
|
||||
autoResolveIncident: true,
|
||||
},
|
||||
],
|
||||
changeMonitorStatus: true,
|
||||
@@ -152,7 +152,7 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
|
||||
title: `${arg.monitorType} monitor is offline`,
|
||||
description: `${arg.monitorType} monitor is currently offline.`,
|
||||
incidentSeverityId: arg.incidentSeverityId,
|
||||
autoResolveIncident: false
|
||||
autoResolveIncident: true,
|
||||
},
|
||||
],
|
||||
changeMonitorStatus: true,
|
||||
|
||||
@@ -10,4 +10,5 @@ export default interface ProbeMonitorResponse {
|
||||
responseBody?: string | JSONObject | undefined;
|
||||
monitorStepId: ObjectID;
|
||||
monitorId: ObjectID;
|
||||
probeId: ObjectID;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,8 @@ const MonitorCriteriaIncidentForm: FunctionComponent<ComponentProps> = (
|
||||
},
|
||||
title: 'Auto Resolve Incident',
|
||||
stepId: 'incident-details',
|
||||
description: 'Automatically resolve this incident when this criteria is no longer met.',
|
||||
description:
|
||||
'Automatically resolve this incident when this criteria is no longer met.',
|
||||
fieldType: FormFieldSchemaType.Toggle,
|
||||
required: false,
|
||||
},
|
||||
|
||||
@@ -79,7 +79,8 @@ const MonitorCriteriaIncidentForm: FunctionComponent<ComponentProps> = (
|
||||
{
|
||||
key: 'autoResolveIncident',
|
||||
title: 'Auto Resolve Incident',
|
||||
description: 'Automatically resolve this incident when this criteria is no longer met.',
|
||||
description:
|
||||
'Automatically resolve this incident when this criteria is no longer met.',
|
||||
fieldType: FieldType.Boolean,
|
||||
placeholder: 'No',
|
||||
},
|
||||
|
||||
@@ -32,12 +32,15 @@ import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
|
||||
import URL from 'Common/Types/API/URL';
|
||||
import { DASHBOARD_API_URL } from 'CommonUI/src/Config';
|
||||
import DisabledWarning from '../../../Components/Monitor/DisabledWarning';
|
||||
import { ButtonStyleType } from 'CommonUI/src/Components/Button/Button';
|
||||
import Modal, { ModalWidth } from 'CommonUI/src/Components/Modal/Modal';
|
||||
|
||||
const MonitorProbes: FunctionComponent<PageComponentProps> = (
|
||||
_props: PageComponentProps
|
||||
): ReactElement => {
|
||||
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
|
||||
|
||||
const [showViewLogsModal, setShowViewLogsModal] = useState<boolean>(false);
|
||||
const [logs, setLogs] = useState<string>('');
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
const [error, setError] = useState<string>('');
|
||||
@@ -168,6 +171,33 @@ const MonitorProbes: FunctionComponent<PageComponentProps> = (
|
||||
'No probes found for this resource. However, you can add some probes to monitor this resource.'
|
||||
}
|
||||
viewPageRoute={Navigation.getCurrentRoute()}
|
||||
selectMoreFields={{
|
||||
lastMonitoringLog: true,
|
||||
}}
|
||||
actionButtons={[
|
||||
{
|
||||
title: 'View Logs',
|
||||
buttonStyleType: ButtonStyleType.NORMAL,
|
||||
icon: IconProp.List,
|
||||
onClick: async (
|
||||
item: JSONObject,
|
||||
onCompleteAction: Function
|
||||
) => {
|
||||
setLogs(
|
||||
item['lastMonitoringLog']
|
||||
? JSON.stringify(
|
||||
item['lastMonitoringLog'],
|
||||
null,
|
||||
2
|
||||
)
|
||||
: 'Not monitored yet'
|
||||
);
|
||||
setShowViewLogsModal(true);
|
||||
|
||||
onCompleteAction();
|
||||
},
|
||||
},
|
||||
]}
|
||||
formFields={[
|
||||
{
|
||||
field: {
|
||||
@@ -279,6 +309,25 @@ const MonitorProbes: FunctionComponent<PageComponentProps> = (
|
||||
>
|
||||
<DisabledWarning monitorId={modelId} />
|
||||
{getPageContent()}
|
||||
{showViewLogsModal && (
|
||||
<Modal
|
||||
title={'Monitoring Logs'}
|
||||
description="Here are the latest monitoring log for this resource."
|
||||
isLoading={false}
|
||||
modalWidth={ModalWidth.Large}
|
||||
onSubmit={() => {
|
||||
setShowViewLogsModal(false);
|
||||
}}
|
||||
submitButtonText={'Close'}
|
||||
submitButtonStyleType={ButtonStyleType.NORMAL}
|
||||
>
|
||||
<div className="text-gray-500 mt-5 text-sm h-96 overflow-y-auto overflow-x-hidden p-5 border-gray-50 border border-2 bg-gray-100 rounded">
|
||||
{logs.split('\n').map((log: string, i: number) => {
|
||||
return <div key={i}>{log}</div>;
|
||||
})}
|
||||
</div>
|
||||
</Modal>
|
||||
)}
|
||||
</ModelPage>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ import IconProp from 'Common/Types/Icon/IconProp';
|
||||
import EnableDocumentation from 'Common/Types/Model/EnableDocumentation';
|
||||
import Monitor from './Monitor';
|
||||
import Probe from './Probe';
|
||||
import { JSONObject } from 'Common/Types/JSON';
|
||||
|
||||
@EnableDocumentation()
|
||||
@TenantColumn('projectId')
|
||||
@@ -445,4 +446,26 @@ export default class MonitorProbe extends AccessControlModel {
|
||||
default: true,
|
||||
})
|
||||
public isEnabled?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CanReadMonitorProbe,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: false,
|
||||
required: false,
|
||||
type: TableColumnType.JSON,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.JSON,
|
||||
nullable: true,
|
||||
unique: false,
|
||||
})
|
||||
public lastMonitoringLog?: JSONObject = undefined;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import WebsiteMonitor, {
|
||||
import ApiMonitor, { APIResponse } from './MonitorTypes/ApiMonitor';
|
||||
import JSONFunctions from 'Common/Types/JSONFunctions';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import ProbeUtil from '../Probe';
|
||||
|
||||
export default class MonitorUtil {
|
||||
public static async probeMonitor(
|
||||
@@ -69,6 +70,7 @@ export default class MonitorUtil {
|
||||
const result: ProbeMonitorResponse = {
|
||||
monitorStepId: monitorStep.id,
|
||||
monitorId: monitor.id!,
|
||||
probeId: ProbeUtil.getProbeId(),
|
||||
};
|
||||
|
||||
if (!monitorStep.data || !monitorStep.data?.monitorDestination) {
|
||||
|
||||
17
Probe/Utils/Probe.ts
Normal file
17
Probe/Utils/Probe.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import LocalCache from 'CommonServer/Infrastructure/LocalCache';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
|
||||
export default class ProbeUtil {
|
||||
public static getProbeId(): ObjectID {
|
||||
const id: string | undefined =
|
||||
LocalCache.getString('PROBE', 'PROBE_ID') ||
|
||||
process.env['PROBE_ID'];
|
||||
|
||||
if (!id) {
|
||||
throw new BadDataException('Probe ID not found');
|
||||
}
|
||||
|
||||
return new ObjectID(id);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
import { JSONObject } from 'Common/Types/JSON';
|
||||
import LocalCache from 'CommonServer/Infrastructure/LocalCache';
|
||||
import ProbeUtil from './Probe';
|
||||
import { PROBE_KEY } from '../Config';
|
||||
|
||||
export default class ProbeAPIRequest {
|
||||
public static getDefaultRequestBody(): JSONObject {
|
||||
return {
|
||||
probeKey: PROBE_KEY,
|
||||
probeId:
|
||||
LocalCache.getString('PROBE', 'PROBE_ID') ||
|
||||
process.env['PROBE_ID'],
|
||||
probeId: ProbeUtil.getProbeId().toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ import Monitor from 'Model/Models/Monitor';
|
||||
import MonitorStatusTimeline from 'Model/Models/MonitorStatusTimeline';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import { JSONObject } from 'Common/Types/JSON';
|
||||
import MonitorProbeService from 'CommonServer/Services/MonitorProbeService';
|
||||
import OneUptimeDate from 'Common/Types/Date';
|
||||
import MonitorProbe from 'Model/Models/MonitorProbe';
|
||||
|
||||
export default class ProbeMonitorResponseService {
|
||||
public static async processProbeResponse(
|
||||
@@ -50,6 +53,46 @@ export default class ProbeMonitorResponseService {
|
||||
throw new BadDataException('Monitor not found');
|
||||
}
|
||||
|
||||
// save the last log to MonitorProbe.
|
||||
|
||||
// get last log. We do this because there are many monitoring steps and we need to store those.
|
||||
const monitorProbe: MonitorProbe | null =
|
||||
await MonitorProbeService.findOneBy({
|
||||
query: {
|
||||
monitorId: monitor.id!,
|
||||
probeId: probeMonitorResponse.probeId!,
|
||||
},
|
||||
select: {
|
||||
lastMonitoringLog: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!monitorProbe) {
|
||||
throw new BadDataException('Probe is not assigned to this monitor');
|
||||
}
|
||||
|
||||
await MonitorProbeService.updateOneBy({
|
||||
query: {
|
||||
monitorId: monitor.id!,
|
||||
probeId: probeMonitorResponse.probeId!,
|
||||
},
|
||||
data: {
|
||||
lastMonitoringLog: {
|
||||
...(monitorProbe.lastMonitoringLog || {}),
|
||||
[probeMonitorResponse.monitorStepId.toString()]: {
|
||||
...JSON.parse(JSON.stringify(probeMonitorResponse)),
|
||||
monitoredAt: OneUptimeDate.getCurrentDate(),
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
// save data to Clickhouse.
|
||||
|
||||
const monitorSteps: MonitorSteps = monitor.monitorSteps!;
|
||||
|
||||
Reference in New Issue
Block a user