Embedding Perses panels#
This little documentation aims to provide you the minimum code needed to have a Perses panel into your React application.
Info
We are working actively on reducing this amount of required dependencies/providers working on some default values or opt-in/opt-out mechanisms.
Getting started (npm example)#
# Create new React app or modify an existing app using the dependencies below
# Example: https://react.dev/learn/build-a-react-app-from-scratch
# Install Perses dependencies
# Note: React 19 is not supported yet
npm i --save @perses-dev/components \
@perses-dev/plugin-system @perses-dev/timeseries-chart-plugin \
@perses-dev/prometheus-plugin @perses-dev/dashboards \
@tanstack/react-query \
@mui/material \
@emotion/styled @hookform/resolvers \
react@18 react-dom@18
Minimal code#
Here replacing your App.tsx
import React from "react";
import "./App.css";
import {
ChartsProvider,
generateChartsTheme,
getTheme,
SnackbarProvider,
} from "@perses-dev/components";
import {
DataQueriesProvider,
dynamicImportPluginLoader,
PluginModuleResource,
PluginRegistry,
TimeRangeProvider,
} from "@perses-dev/plugin-system";
import { ThemeProvider } from "@mui/material";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
DatasourceStoreProvider,
Panel,
VariableProvider,
} from "@perses-dev/dashboards";
import {
DashboardResource,
GlobalDatasourceResource,
DatasourceResource,
} from "@perses-dev/core";
import { DatasourceApi } from "@perses-dev/dashboards";
import * as prometheusPlugin from "@perses-dev/prometheus-plugin";
import * as timeseriesChartPlugin from "@perses-dev/timeseries-chart-plugin";
const fakeDatasource: GlobalDatasourceResource = {
kind: "GlobalDatasource",
metadata: { name: "hello" },
spec: {
default: true,
plugin: {
kind: "PrometheusDatasource",
spec: {
// Update to your actual datasource url
directUrl: "https://prometheus.demo.do.prometheus.io",
},
},
},
};
class DatasourceApiImpl implements DatasourceApi {
getDatasource(): Promise<DatasourceResource | undefined> {
return Promise.resolve(undefined);
}
getGlobalDatasource(): Promise<GlobalDatasourceResource | undefined> {
return Promise.resolve(fakeDatasource);
}
listDatasources(): Promise<DatasourceResource[]> {
return Promise.resolve([]);
}
listGlobalDatasources(): Promise<GlobalDatasourceResource[]> {
return Promise.resolve([fakeDatasource]);
}
buildProxyUrl(): string {
return "/prometheus";
}
}
export const fakeDatasourceApi = new DatasourceApiImpl();
export const fakeDashboard = {
kind: "Dashboard",
metadata: {},
spec: {},
} as DashboardResource;
function App() {
const muiTheme = getTheme("light");
const chartsTheme = generateChartsTheme(muiTheme, {});
const pluginLoader = dynamicImportPluginLoader([
{
resource: prometheusPlugin.getPluginModule(),
importPlugin: () => Promise.resolve(prometheusPlugin),
},
{
resource: timeseriesChartPlugin.getPluginModule(),
importPlugin: () => Promise.resolve(timeseriesChartPlugin),
},
]);
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 0,
},
},
});
return (
<ThemeProvider theme={muiTheme}>
<ChartsProvider chartsTheme={chartsTheme}>
<SnackbarProvider
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
variant="default"
content=""
>
<PluginRegistry
pluginLoader={pluginLoader}
defaultPluginKinds={{
Panel: "TimeSeriesChart",
TimeSeriesQuery: "PrometheusTimeSeriesQuery",
}}
>
<QueryClientProvider client={queryClient}>
<TimeRangeProvider
refreshInterval="0s"
timeRange={{ pastDuration: "30m" }}
>
<VariableProvider>
<DatasourceStoreProvider
dashboardResource={fakeDashboard}
datasourceApi={fakeDatasourceApi}
>
<DataQueriesProvider
definitions={[
{
kind: "PrometheusTimeSeriesQuery",
spec: { query: `up{job="prometheus"}` },
},
]}
>
<Panel
panelOptions={{
hideHeader: true,
}}
definition={{
kind: "Panel",
spec: {
display: { name: "Example Panel" },
plugin: {
kind: "TimeSeriesChart",
spec: {
legend: {
position: "bottom",
size: "medium",
},
},
},
},
}}
/>
</DataQueriesProvider>
</DatasourceStoreProvider>
</VariableProvider>
</TimeRangeProvider>
</QueryClientProvider>
</PluginRegistry>
</SnackbarProvider>
</ChartsProvider>
</ThemeProvider>
);
}
export default App;
You should see a perses panel going to your browser
Definitions by provider#
Check each Provider's source code/jsdoc for more details.
DataQueriesProvider
: Provide the queries' definition, with the query type, the value. This is to be inside the chart below. For each query, one line will be displayed in the chart.DatasourceStoreProvider
: Provide the datasources. In other terms, the place from which the data will be collected.VariableProvider
: Provide the variables that can be used inside the chart. It will allow you to reference any variable into the queries thanks to the${myVar}
syntax. Available variables will be either the builtin variables or the local/external variables that you can pass to the provider.TimeRangeProvider
: Providetime range
of the query, but also therefresh interval
(time between each query automatic replay)QueryClientProvider
: Provide a@tanstack/react-query
QueryClient
, which is a mandatory dependency. (We advise to configure it withrefetchOnWindowFocus: false
except if you want to replay the queries every time you change window)QueryParamProvider
: Provide the ability to take time range, refresh interval, and different variables from the url query params.BrowserRouter
: Provide necessary elements for theQueryParamProvider
PluginRegistry
: Provide the different Perses plugins that will be used in the providers/charts below.SnackbarProvider
: Provide the toaster that will occurs in case of error/success.ChartsProvider
: Provider for the option of apache/echarts library. Which is used for all the charts display.ThemeProvider
: Provider of the Material UI theme which is currently the theme used in Perses.