Skip to content

Commit

Permalink
update ui for monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
thorrester committed Oct 10, 2024
1 parent f17a1a1 commit 95e2a8e
Show file tree
Hide file tree
Showing 21 changed files with 775 additions and 219 deletions.
16 changes: 4 additions & 12 deletions opsml/app/routes/scouter.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ def insert_profile(request: Request, payload: DriftProfileRequest) -> Success:
return Success()
except Exception as error:
logger.error(f"Failed to insert drift profile: {error}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to insert drift profile"
) from error
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to insert drift profile") from error


@router.put("/scouter/drift/profile", name="update_drift_profile", response_model=ProfileUpdateResponse)
Expand Down Expand Up @@ -150,9 +148,7 @@ def update_profile(request: Request, payload: DriftProfileUpdateRequest) -> Prof
return ProfileUpdateResponse()
except Exception as error:
logger.error(f"Failed to insert drift profile: {error}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to insert drift profile"
) from error
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to insert drift profile") from error


@router.get("/scouter/drift/profile", name="get_profile", response_model=GetDriftProfileResponse)
Expand Down Expand Up @@ -185,9 +181,7 @@ def get_profile(
return GetDriftProfileResponse(profile=profile)
except Exception as error:
logger.error(f"Failed to get drift profile: {error}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to get drift profile"
) from error
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to get drift profile") from error


@router.get("/scouter/drift/values", name="get_drift", response_model=DriftResponse)
Expand Down Expand Up @@ -237,9 +231,7 @@ def get_drift_values(
return DriftResponse(**values)
except Exception as error:
logger.error(f"Failed to get drift values: {error}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to get drift values"
) from error
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to get drift values") from error


@router.get("/scouter/feature/distribution", name="feature distribution", response_model=FeatureDistribution)
Expand Down
35 changes: 21 additions & 14 deletions opsml/app/static/src/lib/card/TimeChartDiv.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,12 @@
Chart.register(annotationPlugin);
onMount(() => {
ctx = chartCanvas.getContext('2d');
chart = new Chart(ctx, {
// @ts-ignore
type: type,
data: data,
options: options
});
// @ts-ignore
window[id] = chart;
createChart();
return () => {
chart.destroy();
if (chart) {
chart.destroy();
}
};
});
Expand All @@ -54,6 +44,8 @@
//check if chart.type is not undefined
if (chart.type) {
// log chart id
console.log('Updating chart with id: ', id);
chart.destroy();
ctx = chartCanvas.getContext('2d');
chart = new Chart(ctx, {
Expand All @@ -75,6 +67,21 @@
}
function createChart() {
// log chart id
console.log('Creating chart with id: ', id);
ctx = chartCanvas.getContext('2d');
chart = new Chart(ctx, {
// @ts-ignore
type: type,
data: data,
options: options
});
// @ts-ignore
window[id] = chart;
}
</script>

Expand Down
4 changes: 2 additions & 2 deletions opsml/app/static/src/lib/card/monitoring/Alerts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@
<td class="text-xs">{formatDate(alert.created_at)}</td>
<td class="text-xs">{alert.id}</td>
<td class="text-xs"><button type="button" class="badge variant-soft-primary" on:click={() => switchFeature(alert.feature)}>{alert.feature}</button></td>
<td class="text-xs">{alert.alerts["kind"]}</td>
<td class="text-xs">{alert.alerts["zone"]}</td>
<td class="text-xs">{alert.alert["kind"]}</td>
<td class="text-xs">{alert.alert["zone"]}</td>
<td class="text-xs">
<button
type="button"
Expand Down
196 changes: 96 additions & 100 deletions opsml/app/static/src/lib/card/monitoring/SPCMonitoringUI.svelte
Original file line number Diff line number Diff line change
@@ -1,112 +1,108 @@
<script lang="ts">
import { type ChartjsData, type SpcDriftProfile, type SpcFeatureDriftProfile, type MonitorAlerts , ProfileType } from "$lib/scripts/types";
import { rebuildSpcDriftViz } from "$lib/scripts/monitoring/utils";
import TimeChartDiv from '$lib/card/TimeChartDiv.svelte';
import AlertDiv from "$lib/card/monitoring/Alerts.svelte";
import SpcStats from "$lib/card/monitoring/SPCStats.svelte";
import Fa from 'svelte-fa';
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
import { type ChartjsData, type SpcDriftProfile, type SpcFeatureDriftProfile, type MonitorAlerts , ProfileType } from "$lib/scripts/types";
import {type MonitoringVizData} from "$lib/scripts/monitoring/types";
import { rebuildSpcDriftViz } from "$lib/scripts/monitoring/utils";
import SpcTimeChartDiv from '$lib/card/monitoring/SpcTimeChart.svelte';
import AlertDiv from "$lib/card/monitoring/Alerts.svelte";
import SpcStats from "$lib/card/monitoring/SPCStats.svelte";
import Fa from 'svelte-fa';
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
import TimeChartDiv from '$lib/card/TimeChartDiv.svelte';
export let driftProfiles: Map<ProfileType, SpcDriftProfile>;
export let targetFeature:SpcFeatureDriftProfile;
export let driftVizData: ChartjsData;
export let featureDistVizData: ChartjsData;
export let alertMetricVizData: ChartjsData;
export let timeWindow: string;
export let max_data_points: number;
export let name: string;
export let repository: string;;
export let version: string;
export let alerts: MonitorAlerts;
export let profileType: ProfileType;
export let driftProfiles: Map<ProfileType, SpcDriftProfile>;
export let targetFeature:SpcFeatureDriftProfile;
export let monitorVizData: MonitoringVizData;
export let timeWindow: string;
export let max_data_points: number;
export let name: string;
export let repository: string;;
export let version: string;
export let alerts: MonitorAlerts;
export let profileType: ProfileType;
let driftVizId: string;
$: driftVizId = "Drift values for " + targetFeature.id;
let alertMeticsId: string;
$: alertMeticsId = 'Alert Metrics';
async function updateFeatureValues(feature:string) {
if (feature === targetFeature.id) {
return;
}
targetFeature = driftProfiles[profileType].features[feature];
let rebuiltViz = await rebuildSpcDriftViz(repository, name, version, timeWindow, max_data_points, feature, targetFeature);
driftVizData = rebuiltViz[0];
featureDistVizData = rebuiltViz[1];
}
function handleFeatureUpdate(event) {
updateFeatureValues(event.detail.feature);
}
</script>
let driftVizId: string;
$: driftVizId = "Drift values for " + targetFeature.id;
<!-- Drift Viz -->
{#if driftVizData}
<div class="grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-4 gap-y-1 lg:gap-x-2">
<div class="col-span-2 xl:col-span-3">
<TimeChartDiv
data={driftVizData.data}
id={driftVizId}
options={driftVizData.options}
minHeight="min-h-[300px] lg:min-h-[400px]"
maxHeight="max-h-[300px] lg:min-h-[400px]"
/>
</div>
<div class="col-span-1">
<SpcStats
feature_profile={targetFeature}
featureDistVizData={featureDistVizData}
/>
</div>
let alertMeticsId: string;
$: alertMeticsId = 'Alert Metrics';
async function updateFeatureValues(feature:string) {
if (feature === targetFeature.id) {
return;
}
targetFeature = driftProfiles[profileType].features[feature];
monitorVizData = await rebuildSpcDriftViz(repository, name, version, timeWindow, max_data_points, feature, targetFeature);
}
function handleFeatureUpdate(event) {
updateFeatureValues(event.detail.feature);
}
</script>

<!-- Drift Viz -->
{#if monitorVizData.driftVizData}
<div class="grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-4 gap-y-1 lg:gap-x-2">
<div class="col-span-2 xl:col-span-3">
<SpcTimeChartDiv
data={monitorVizData.driftVizData.data}
id={driftVizId}
options={monitorVizData.driftVizData.options}
minHeight="min-h-[400px]"
maxHeight="max-h-[400px]"
/>
</div>
{:else}
<div class="flex justify-center items-center h-4/5">
<p class="text-gray-400">No feature values found for the current time period</p>
<div class="col-span-1">
<SpcStats
feature_profile={targetFeature}
featureDistVizData={monitorVizData.featureDistVizData}
/>
</div>
{/if}

<div class="flex flex-col pt-2">
<div class="text-primary-500 text-2xl font-bold pt-2 pb-1">Alerts</div>
<div class="border border-2 border-primary-500 w-full mb-2"></div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-1">
<div class="lg:mr-2 lg:col-span-2">
<div class="flex flex-row items-center">
<Fa icon={faTriangleExclamation} size="lg" color="#f54d55"/>
<header class="pl-2 text-secondary-600 text-lg font-bold">Alert History</header>
</div>
{#if alertMetricVizData}
<TimeChartDiv
data={alertMetricVizData.data}
id={alertMeticsId}
options={alertMetricVizData.options}
minHeight="min-h-[300px]"
maxHeight="max-h-[300px]"
type="bar"
/>
{:else}
<div class="flex justify-center items-center h-4/5">
<p class="text-gray-400">No feature values found for the current time period</p>
</div>
{/if}
</div>
{:else}
<div class="flex justify-center items-center h-4/5">
<p class="text-gray-400">No feature values found for the current time period</p>
</div>
{/if}

<div class="flex flex-col pt-2">
<div class="text-primary-500 text-2xl font-bold pt-2 pb-1">Alerts</div>
<div class="border border-2 border-primary-500 w-full mb-2"></div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-1">
<div class="lg:mr-2 lg:col-span-2">
<div class="flex flex-row items-center">
<Fa icon={faTriangleExclamation} size="lg" color="#f54d55"/>
<header class="pl-2 text-secondary-600 text-lg font-bold">Alert History</header>
</div>
<div>
<div class="flex flex-row items-center">
<Fa icon={faTriangleExclamation} size="lg" color="#f54d55"/>
<header class="pl-2 text-secondary-600 text-lg font-bold">Active Alerts</header>
</div>
<div id="table" class="col-span-1 min-h-[300px] max-h-[300px] rounded-2xl border border-2 border-primary-500 overflow-y-auto mb-4 shadow-md shadow-primary-500">
<AlertDiv alerts={alerts} on:switchFeature={handleFeatureUpdate}/>
{#if monitorVizData.alertMetricVizData}
<TimeChartDiv
data={monitorVizData.alertMetricVizData.data}
id={alertMeticsId}
options={monitorVizData.alertMetricVizData.options}
minHeight="min-h-[300px]"
maxHeight="max-h-[300px]"
type="bar"
/>
{:else}
<div class="flex justify-center items-center h-4/5">
<p class="text-gray-400">No feature values found for the current time period</p>
</div>
{/if}
</div>
<div>
<div class="flex flex-row items-center">
<Fa icon={faTriangleExclamation} size="lg" color="#f54d55"/>
<header class="pl-2 text-secondary-600 text-lg font-bold">Active Alerts</header>
</div>
<div id="table" class="col-span-1 min-h-[300px] max-h-[300px] rounded-2xl border border-2 border-primary-500 overflow-y-auto mb-4 shadow-md shadow-primary-500">
<AlertDiv alerts={alerts}/>
</div>
</div>
</div>
</div>


Loading

0 comments on commit 95e2a8e

Please sign in to comment.