Skip to content

Commit

Permalink
add explorer plugins
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel Bernal <[email protected]>
  • Loading branch information
jgbernalp committed Feb 6, 2025
1 parent d4f43f4 commit a92ff6f
Show file tree
Hide file tree
Showing 21 changed files with 2,984 additions and 147 deletions.
26 changes: 21 additions & 5 deletions Prometheus/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@perses-dev/prometheus",
"private": true,
"version": "0.4.1",
"version": "0.5.0",
"scripts": {
"dev": "rsbuild dev",
"build": "rsbuild build",
Expand All @@ -11,26 +11,33 @@
},
"dependencies": {
"@module-federation/enhanced": "^0.8.9",
"@nexucis/fuzzy": "^0.5.1",
"@prometheus-io/codemirror-promql": "^0.301.0",
"color-hash": "^2.0.2"
"color-hash": "^2.0.2",
"qs": "^6.13.0",
"@perses-dev/explore": "0.0.0-snapshot-explorer-plugin-c4a7621"
},
"peerDependencies": {
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@hookform/resolvers": "^3.2.0",
"@perses-dev/components": "^0.50.1",
"@perses-dev/core": "^0.50.1",
"@perses-dev/dashboards": "^0.50.1",
"@perses-dev/plugin-system": "^0.50.1",
"@tanstack/react-query": "^5.64.2",
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.8",
"echarts": "5.5.0",
"immer": "^9.0.15",
"lodash": "^4.17.21",
"react": "^17.0.2 || ^18.0.0",
"react-dom": "^17.0.2 || ^18.0.0",
"use-resize-observer": "^9.0.0",
"react-hook-form": "^7.52.2",
"@tanstack/react-query": "^4.36.1",
"immer": "^9.0.15"
"use-resize-observer": "^9.0.0"
},
"devDependencies": {
"@types/qs": "^6.9.18"
},
"files": [
"dist"
Expand Down Expand Up @@ -81,6 +88,15 @@
},
"name": "PrometheusPromQLVariable"
}
},
{
"kind": "Explore",
"spec": {
"display": {
"name": "Prometheus Explorer"
},
"name": "PrometheusExplorer"
}
}
]
}
Expand Down
4 changes: 4 additions & 0 deletions Prometheus/rsbuild.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default defineConfig({
'./PrometheusLabelValuesVariable': './src/plugins/PrometheusLabelValuesVariable.tsx',
'./PrometheusLabelNamesVariable': './src/plugins/PrometheusLabelNamesVariable.tsx',
'./PrometheusPromQLVariable': './src/plugins/PrometheusPromQLVariable.tsx',
'./PrometheusExplorer': './src/explore/PrometheusExplorer.tsx',
},
shared: {
react: { requiredVersion: '18.2.0', singleton: true },
Expand All @@ -50,11 +51,14 @@ export default defineConfig({
lodash: { singleton: true },
'@perses-dev/components': { singleton: true },
'@perses-dev/plugin-system': { singleton: true },
'@perses-dev/explore': { singleton: true },
'@perses-dev/dashboards': { singleton: true },
'@emotion/react': { requiredVersion: '^11.11.3', singleton: true },
'@emotion/styled': { singleton: true },
'@hookform/resolvers': { singleton: true },
'@tanstack/react-query': { singleton: true },
'react-hook-form': { singleton: true },
'react-router-dom': { singleton: true },
},
dts: false,
runtime: false,
Expand Down
143 changes: 143 additions & 0 deletions Prometheus/src/explore/PrometheusExplorer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2024 The Perses Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { QueryDefinition } from '@perses-dev/core';
import { Box, Stack, Tab, Tabs } from '@mui/material';
import { DataQueriesProvider, MultiQueryEditor, useSuggestedStepMs } from '@perses-dev/plugin-system';
import { useExplorerManagerContext } from '@perses-dev/explore';
import useResizeObserver from 'use-resize-observer';
import { Panel } from '@perses-dev/dashboards';
import { ReactElement } from 'react';
import { DEFAULT_PROM } from '../model/prometheus-selectors';
import { FinderQueryParams } from './PrometheusMetricsFinder/types';
import { PrometheusMetricsFinder } from './PrometheusMetricsFinder';

interface MetricsExplorerQueryParams extends FinderQueryParams {
tab?: string;
queries?: QueryDefinition[];
}

const PANEL_PREVIEW_HEIGHT = 700;

function TimeSeriesPanel({ queries }: { queries: QueryDefinition[] }): ReactElement {
const { width, ref: boxRef } = useResizeObserver();
const height = PANEL_PREVIEW_HEIGHT;

const suggestedStepMs = useSuggestedStepMs(width);

// map TimeSeriesQueryDefinition to Definition<UnknownSpec>
const definitions = queries.length
? queries.map((query) => {
return {
kind: query.spec.plugin.kind,
spec: query.spec.plugin.spec,
};
})
: [];

return (
<Box ref={boxRef} height={height}>
<DataQueriesProvider definitions={definitions} options={{ suggestedStepMs, mode: 'range' }}>
<Panel
panelOptions={{
hideHeader: true,
}}
definition={{
kind: 'Panel',
spec: { queries: queries, display: { name: '' }, plugin: { kind: 'TimeSeriesChart', spec: {} } },
}}
/>
</DataQueriesProvider>
</Box>
);
}

function MetricDataTable({ queries }: { queries: QueryDefinition[] }): ReactElement {
const height = PANEL_PREVIEW_HEIGHT;

// map TimeSeriesQueryDefinition to Definition<UnknownSpec>
const definitions = queries.map((query) => {
return {
kind: query.spec.plugin.kind,
spec: query.spec.plugin.spec,
};
});

return (
<Box height={height}>
<DataQueriesProvider definitions={definitions} options={{ mode: 'instant' }}>
<Panel
panelOptions={{
hideHeader: true,
}}
definition={{
kind: 'Panel',
spec: { queries: queries, display: { name: '' }, plugin: { kind: 'TimeSeriesTable', spec: {} } },
}}
/>
</DataQueriesProvider>
</Box>
);
}

export function PrometheusExplorer(): ReactElement {
const {
data: { tab = 'table', queries = [], datasource = DEFAULT_PROM, filters = [], exploredMetric = undefined },
setData,
} = useExplorerManagerContext<MetricsExplorerQueryParams>();

return (
<Stack gap={2} sx={{ width: '100%' }}>
<Tabs
value={tab}
onChange={(_, state) => setData({ tab: state, queries })}
variant="scrollable"
sx={{ borderBottom: 1, borderColor: 'divider' }}
>
<Tab value="table" label="Table" />
<Tab value="graph" label="Graph" />
<Tab value="finder" label="Finder" />
</Tabs>
<Stack gap={1}>
{tab === 'table' && (
<Stack>
<MultiQueryEditor
queryTypes={['TimeSeriesQuery']}
onChange={(state) => setData({ tab, queries: state })}
queries={queries}
/>
<MetricDataTable queries={queries} />
</Stack>
)}
{tab === 'graph' && (
<Stack>
<MultiQueryEditor
queryTypes={['TimeSeriesQuery']}
onChange={(state) => setData({ tab, queries: state })}
queries={queries}
/>
<TimeSeriesPanel queries={queries} />
</Stack>
)}
{tab === 'finder' && (
<Stack>
<PrometheusMetricsFinder
onChange={(state) => setData({ tab, ...state })}
value={{ datasource, filters, exploredMetric }}
/>
</Stack>
)}
</Stack>
</Stack>
);
}
Loading

0 comments on commit a92ff6f

Please sign in to comment.