Skip to content

Commit b989852

Browse files
authored
Enable model serving metrics upstream (#957)
* Enable modelserving upstream with parametrized option - Backend * Enable modelserving upstream - Frontend * Refactor using a hook * Refactor the hook to return a boolean
1 parent 533044f commit b989852

File tree

11 files changed

+96
-18
lines changed

11 files changed

+96
-18
lines changed

backend/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type DashboardConfig = K8sResourceCommon & {
1818
disableUserManagement: boolean;
1919
disableProjects: boolean;
2020
disableModelServing: boolean;
21+
modelMetricsNamespace: string;
2122
};
2223
groupsConfig?: {
2324
adminGroups: string;

backend/src/utils/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const blankDashboardCR: DashboardConfig = {
4646
disableUserManagement: false,
4747
disableProjects: false,
4848
disableModelServing: false,
49+
modelMetricsNamespace: '',
4950
},
5051
notebookController: {
5152
enabled: true,

backend/src/utils/prometheusUtils.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import {
88
import https from 'https';
99
import { getDirectCallOptions } from './directCallUtils';
1010
import { DEV_MODE } from './constants';
11+
import { getNamespaces } from './notebookUtils';
12+
import { getDashboardConfig } from './resourceUtils';
13+
import { createCustomError } from './requestUtils';
1114

1215
const callPrometheus = async <T>(
1316
fastify: KubeFastifyInstance,
@@ -108,11 +111,34 @@ export const callPrometheusServing = (
108111
fastify: KubeFastifyInstance,
109112
request: OauthFastifyRequest,
110113
query: string,
111-
): Promise<{ code: number; response: PrometheusQueryRangeResponse }> =>
112-
callPrometheus(
113-
fastify,
114-
request,
115-
query,
116-
generatePrometheusHostURL(fastify, 'rhods-model-monitoring', 'redhat-ods-monitoring', '443'),
117-
QueryType.QUERY_RANGE,
114+
): Promise<{ code: number; response: PrometheusQueryRangeResponse | undefined }> => {
115+
const { dashboardNamespace } = getNamespaces(fastify);
116+
117+
const modelMetricsNamespace = getDashboardConfig().spec.dashboardConfig.modelMetricsNamespace;
118+
119+
if (dashboardNamespace !== 'redhat-ods-applications' && modelMetricsNamespace) {
120+
return callPrometheus(
121+
fastify,
122+
request,
123+
query,
124+
generatePrometheusHostURL(fastify, 'odh-model-monitoring', modelMetricsNamespace, '443'),
125+
QueryType.QUERY_RANGE,
126+
);
127+
}
128+
129+
if (dashboardNamespace === 'redhat-ods-applications' && !modelMetricsNamespace) {
130+
return callPrometheus(
131+
fastify,
132+
request,
133+
query,
134+
generatePrometheusHostURL(fastify, 'rhods-model-monitoring', 'redhat-ods-monitoring', '443'),
135+
QueryType.QUERY_RANGE,
136+
);
137+
}
138+
139+
throw createCustomError(
140+
'Service Unavailable',
141+
'Service Prometheus is down or misconfigured',
142+
503,
118143
);
144+
};

frontend/src/pages/modelServing/ModelServingRoutes.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ import { Navigate, Routes, Route } from 'react-router-dom';
33
import ModelServingContextProvider from './ModelServingContext';
44
import ModelServingMetricsWrapper from './screens/metrics/ModelServingMetricsWrapper';
55
import ModelServingGlobal from './screens/global/ModelServingGlobal';
6+
import useModelMetricsEnabled from './useModelMetricsEnabled';
67

78
const ModelServingRoutes: React.FC = () => {
9+
const [modelMetricsEnabled] = useModelMetricsEnabled();
10+
811
return (
912
<Routes>
1013
<Route path="/" element={<ModelServingContextProvider />}>
1114
<Route index element={<ModelServingGlobal />} />
1215
<Route
1316
path="/metrics/:project/:inferenceService"
14-
element={<ModelServingMetricsWrapper />}
17+
element={
18+
modelMetricsEnabled ? <ModelServingMetricsWrapper /> : <Navigate replace to="/" />
19+
}
1520
/>
1621
<Route path="*" element={<Navigate to="." />} />
1722
</Route>

frontend/src/pages/modelServing/screens/global/InferenceServiceTableRow.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import InferenceServiceEndpoint from './InferenceServiceEndpoint';
88
import InferenceServiceProject from './InferenceServiceProject';
99
import InferenceServiceStatus from './InferenceServiceStatus';
1010
import { Link } from 'react-router-dom';
11+
import useModelMetricsEnabled from 'pages/modelServing/useModelMetricsEnabled';
1112

1213
type InferenceServiceTableRowProps = {
1314
obj: InferenceServiceKind;
@@ -24,20 +25,26 @@ const InferenceServiceTableRow: React.FC<InferenceServiceTableRowProps> = ({
2425
onEditInferenceService,
2526
isGlobal,
2627
}) => {
28+
const [modelMetricsEnabled] = useModelMetricsEnabled();
29+
2730
return (
2831
<Tbody>
2932
<Tr>
3033
<Td dataLabel="Name">
3134
<ResourceNameTooltip resource={inferenceService}>
32-
<Link
33-
to={
34-
isGlobal
35-
? `/modelServing/metrics/${inferenceService.metadata.namespace}/${inferenceService.metadata.name}`
36-
: `/projects/${inferenceService.metadata.namespace}/metrics/model/${inferenceService.metadata.name}`
37-
}
38-
>
39-
{getInferenceServiceDisplayName(inferenceService)}
40-
</Link>
35+
{modelMetricsEnabled ? (
36+
<Link
37+
to={
38+
isGlobal
39+
? `/modelServing/metrics/${inferenceService.metadata.namespace}/${inferenceService.metadata.name}`
40+
: `/projects/${inferenceService.metadata.namespace}/metrics/model/${inferenceService.metadata.name}`
41+
}
42+
>
43+
{getInferenceServiceDisplayName(inferenceService)}
44+
</Link>
45+
) : (
46+
getInferenceServiceDisplayName(inferenceService)
47+
)}
4148
</ResourceNameTooltip>
4249
</Td>
4350
{isGlobal && (

frontend/src/pages/modelServing/screens/metrics/utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ import { SelectOptionObject } from '@patternfly/react-core';
33
import { TimeframeTitle } from '../types';
44
import { InferenceServiceKind } from '../../../../k8sTypes';
55
import { ModelServingMetricType } from './ModelServingMetricsContext';
6+
import { DashboardConfig } from 'types';
7+
8+
export const isModelMetricsEnabled = (
9+
dashboardNamespace: string,
10+
dashboardConfig: DashboardConfig,
11+
): boolean => {
12+
if (dashboardNamespace === 'redhat-ods-applications') {
13+
return true;
14+
} else {
15+
return dashboardConfig.spec.dashboardConfig.modelMetricsNamespace !== '';
16+
}
17+
};
618

719
export const getInferenceServiceMetricsQueries = (
820
inferenceService: InferenceServiceKind,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useAppContext } from 'app/AppContext';
2+
import { useDashboardNamespace } from 'redux/selectors';
3+
import { isModelMetricsEnabled } from './screens/metrics/utils';
4+
5+
const useModelMetricsEnabled = (): [modelMetricsEnabled: boolean] => {
6+
const { dashboardNamespace } = useDashboardNamespace();
7+
const { dashboardConfig } = useAppContext();
8+
9+
const checkModelMetricsEnabled = () => isModelMetricsEnabled(dashboardNamespace, dashboardConfig);
10+
11+
return [checkModelMetricsEnabled()];
12+
};
13+
14+
export default useModelMetricsEnabled;

frontend/src/pages/projects/ProjectViewRoutes.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,24 @@ import ProjectDetailsContextProvider from './ProjectDetailsContext';
66
import SpawnerPage from './screens/spawner/SpawnerPage';
77
import EditSpawnerPage from './screens/spawner/EditSpawnerPage';
88
import DetailsPageMetricsWrapper from '../modelServing/screens/projects/DetailsPageMetricsWrapper';
9+
import useModelMetricsEnabled from 'pages/modelServing/useModelMetricsEnabled';
910

1011
const ProjectViewRoutes: React.FC = () => {
12+
const [modelMetricsEnabled] = useModelMetricsEnabled();
13+
1114
return (
1215
<Routes>
1316
<Route path="/" element={<ProjectView />} />
1417
<Route path="/:namespace/*" element={<ProjectDetailsContextProvider />}>
1518
<Route index element={<ProjectDetails />} />
1619
<Route path="spawner" element={<SpawnerPage />} />
1720
<Route path="spawner/:notebookName" element={<EditSpawnerPage />} />
18-
<Route path="metrics/model/:inferenceService" element={<DetailsPageMetricsWrapper />} />
21+
<Route
22+
path="metrics/model/:inferenceService"
23+
element={
24+
modelMetricsEnabled ? <DetailsPageMetricsWrapper /> : <Navigate replace to="/" />
25+
}
26+
/>
1927
<Route path="*" element={<Navigate to="." />} />
2028
</Route>
2129
<Route path="*" element={<Navigate to="." />} />

frontend/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export type DashboardCommonConfig = {
7171
disableUserManagement: boolean;
7272
disableProjects: boolean;
7373
disableModelServing: boolean;
74+
modelMetricsNamespace: string;
7475
};
7576

7677
export type NotebookControllerUserState = {

manifests/crd/odhdashboardconfigs.opendatahub.io.crd.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ spec:
4545
type: boolean
4646
disableModelServing:
4747
type: boolean
48+
modelMetricsNamespace:
49+
type: string
4850
groupsConfig:
4951
type: object
5052
required:

0 commit comments

Comments
 (0)