Merge pull request #2219 from OneUptime/diff-products

Diff products
This commit is contained in:
Simon Larsen 2026-01-09 21:50:10 +00:00 committed by GitHub
commit b464ff1cf9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 556 additions and 1475 deletions

View file

@ -63,10 +63,20 @@ const OngoingScheduledEvents: React.LazyExoticComponent<
> = lazy(() => {
return import("./Pages/Home/OngoingScheduledMaintenance");
});
const TelemetryRoutes: React.LazyExoticComponent<
const LogsRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
> = lazy(() => {
return import("./Routes/TelemetryRoutes");
return import("./Routes/LogsRoutes");
});
const MetricsRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
> = lazy(() => {
return import("./Routes/MetricsRoutes");
});
const TracesRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
> = lazy(() => {
return import("./Routes/TracesRoutes");
});
const MonitorsRoutes: React.LazyExoticComponent<
React.FunctionComponent<PageComponentProps>
@ -427,10 +437,22 @@ const App: () => JSX.Element = () => {
/>
}
/>
{/* Telemetry */}
{/* Logs */}
<PageRoute
path={RouteMap[PageMap.TELEMETRY_ROOT]?.toString() || ""}
element={<TelemetryRoutes {...commonPageProps} />}
path={RouteMap[PageMap.LOGS_ROOT]?.toString() || ""}
element={<LogsRoutes {...commonPageProps} />}
/>
{/* Metrics */}
<PageRoute
path={RouteMap[PageMap.METRICS_ROOT]?.toString() || ""}
element={<MetricsRoutes {...commonPageProps} />}
/>
{/* Traces */}
<PageRoute
path={RouteMap[PageMap.TRACES_ROOT]?.toString() || ""}
element={<TracesRoutes {...commonPageProps} />}
/>
{/* Monitors */}

View file

@ -317,12 +317,9 @@ const DashboardLogsViewer: FunctionComponent<ComponentProps> = (
return undefined;
}
return RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
{
modelId: traceId,
},
);
return RouteUtil.populateRouteParams(RouteMap[PageMap.TRACE_VIEW]!, {
modelId: traceId,
});
}}
getSpanRoute={(spanId: string, log: Log) => {
const traceId: string | undefined = log.traceId?.toString();
@ -332,7 +329,7 @@ const DashboardLogsViewer: FunctionComponent<ComponentProps> = (
}
const route: Route = RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
RouteMap[PageMap.TRACE_VIEW]!,
{
modelId: traceId,
},

View file

@ -46,7 +46,7 @@ const MetricsTable: FunctionComponent<ComponentProps> = (
}}
onViewPage={async (item: MetricType) => {
const route: Route = RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_METRIC_VIEW]!,
RouteMap[PageMap.METRIC_VIEW]!,
);
const currentUrl: URL = Navigation.getCurrentURL();

View file

@ -98,16 +98,32 @@ const DashboardNavbar: FunctionComponent<ComponentProps> = (
},
// Observability
{
title: "Telemetry",
description: "Logs, metrics, and traces.",
route: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY] as Route,
),
activeRoute: RouteMap[PageMap.TELEMETRY],
icon: IconProp.Cube,
title: "Logs",
description: "Search and analyze logs.",
route: RouteUtil.populateRouteParams(RouteMap[PageMap.LOGS] as Route),
activeRoute: RouteMap[PageMap.LOGS],
icon: IconProp.Logs,
iconColor: "purple",
category: "Observability",
},
{
title: "Metrics",
description: "Monitor system metrics.",
route: RouteUtil.populateRouteParams(RouteMap[PageMap.METRICS] as Route),
activeRoute: RouteMap[PageMap.METRICS],
icon: IconProp.ChartBar,
iconColor: "green",
category: "Observability",
},
{
title: "Traces",
description: "Distributed tracing analysis.",
route: RouteUtil.populateRouteParams(RouteMap[PageMap.TRACES] as Route),
activeRoute: RouteMap[PageMap.TRACES],
icon: IconProp.RectangleStack,
iconColor: "blue",
category: "Observability",
},
{
title: "Exceptions",
description: "Catch and fix bugs early.",

View file

@ -41,12 +41,9 @@ const SpanStatusElement: FunctionComponent<ComponentProps> = (
{props.title ? (
<div className={`${props.titleClassName} hover:underline`}>
<AppLink
to={RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
{
modelId: props.traceId,
},
)}
to={RouteUtil.populateRouteParams(RouteMap[PageMap.TRACE_VIEW]!, {
modelId: props.traceId,
})}
>
<p>{props.title}</p>
</AppLink>

View file

@ -191,12 +191,9 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
return undefined;
}
return RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
{
modelId: traceId,
},
);
return RouteUtil.populateRouteParams(RouteMap[PageMap.TRACE_VIEW]!, {
modelId: traceId,
});
}}
getSpanRoute={(spanId: string, log: Log) => {
const traceId: string | undefined = log.traceId?.toString();
@ -206,7 +203,7 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
}
const route: Route = RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
RouteMap[PageMap.TRACE_VIEW]!,
{
modelId: traceId,
},

View file

@ -40,7 +40,7 @@ const TelemetryServiceElement: FunctionComponent<ComponentProps> = (
onNavigateComplete={props.onNavigateComplete}
className="hover:underline"
to={RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW] as Route,
RouteMap[PageMap.SERVICE_VIEW] as Route,
{
modelId: new ObjectID(props.telemetryService._id as string),
},

View file

@ -76,7 +76,7 @@ const TelemetryServiceTable: FunctionComponent<ComponentProps> = (
]}
showRefreshButton={true}
viewPageRoute={RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_ROOT]!,
RouteMap[PageMap.SERVICE_VIEW]!,
)}
filters={[
{

View file

@ -15,12 +15,9 @@ const TraceElement: FunctionComponent<ComponentProps> = (
{props.traceId ? (
<div className={`hover:underline`}>
<AppLink
to={RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_VIEW]!,
{
modelId: props.traceId,
},
)}
to={RouteUtil.populateRouteParams(RouteMap[PageMap.TRACE_VIEW]!, {
modelId: props.traceId,
})}
>
<p>{props.traceId}</p>
</AppLink>

View file

@ -229,12 +229,12 @@ const TraceTable: FunctionComponent<ComponentProps> = (
SpanUtil.getSpanKindDropdownOptions();
let viewRoute: Route = RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACE_ROOT]!,
RouteMap[PageMap.TRACE_VIEW]!,
);
if (modelId) {
viewRoute = RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_TRACES]!,
RouteMap[PageMap.SERVICE_VIEW_TRACES]!,
{
modelId: modelId,
},

View file

@ -3,7 +3,7 @@ import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import React, { FunctionComponent, ReactElement } from "react";
import DashboardLogsViewer from "../../Components/Logs/LogsViewer";
const Services: FunctionComponent<PageComponentProps> = (
const LogsPage: FunctionComponent<PageComponentProps> = (
props: PageComponentProps,
): ReactElement => {
const disableTelemetryForThisProject: boolean =
@ -19,11 +19,11 @@ const Services: FunctionComponent<PageComponentProps> = (
<DashboardLogsViewer
showFilters={true}
serviceIds={[]}
limit={100} // Limit the number of logs to 100 by default
limit={100}
enableRealtime={true}
id="logs"
/>
);
};
export default Services;
export default LogsPage;

View file

@ -0,0 +1,24 @@
import { getLogsBreadcrumbs } from "../../Utils/Breadcrumbs";
import { RouteUtil } from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import SideMenu from "./SideMenu";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet } from "react-router-dom";
const LogsLayout: FunctionComponent<PageComponentProps> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<Page
title="Logs"
breadcrumbLinks={getLogsBreadcrumbs(path)}
sideMenu={<SideMenu />}
>
<Outlet />
</Page>
);
};
export default LogsLayout;

View file

@ -0,0 +1,29 @@
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import SideMenu, {
SideMenuSectionProps,
} from "Common/UI/Components/SideMenu/SideMenu";
import React, { FunctionComponent, ReactElement } from "react";
const DashboardSideMenu: FunctionComponent = (): ReactElement => {
const sections: SideMenuSectionProps[] = [
{
title: "Logs",
items: [
{
link: {
title: "All Logs",
to: RouteUtil.populateRouteParams(RouteMap[PageMap.LOGS] as Route),
},
icon: IconProp.Logs,
},
],
},
];
return <SideMenu sections={sections} />;
};
export default DashboardSideMenu;

View file

@ -3,7 +3,7 @@ import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import React, { FunctionComponent, ReactElement } from "react";
import MetricsTable from "../../Components/Metrics/MetricsTable";
const Services: FunctionComponent<PageComponentProps> = (
const MetricsPage: FunctionComponent<PageComponentProps> = (
props: PageComponentProps,
): ReactElement => {
const disableTelemetryForThisProject: boolean =
@ -18,4 +18,4 @@ const Services: FunctionComponent<PageComponentProps> = (
return <MetricsTable />;
};
export default Services;
export default MetricsPage;

View file

@ -1,6 +1,7 @@
import { getTelemetryBreadcrumbs } from "../../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import { getMetricsBreadcrumbs } from "../../Utils/Breadcrumbs";
import { RouteUtil } from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import SideMenu from "./SideMenu";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
@ -10,10 +11,12 @@ const MetricsLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<Page
title="Metrics Explorer"
breadcrumbLinks={getTelemetryBreadcrumbs(path)}
title="Metrics"
breadcrumbLinks={getMetricsBreadcrumbs(path)}
sideMenu={<SideMenu />}
>
<Outlet />
</Page>

View file

@ -0,0 +1,31 @@
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import SideMenu, {
SideMenuSectionProps,
} from "Common/UI/Components/SideMenu/SideMenu";
import React, { FunctionComponent, ReactElement } from "react";
const DashboardSideMenu: FunctionComponent = (): ReactElement => {
const sections: SideMenuSectionProps[] = [
{
title: "Metrics",
items: [
{
link: {
title: "All Metrics",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.METRICS] as Route,
),
},
icon: IconProp.ChartBar,
},
],
},
];
return <SideMenu sections={sections} />;
};
export default DashboardSideMenu;

View file

@ -1,8 +1,8 @@
import MetricExplorer from "../../../../Components/Metrics/MetricExplorer";
import PageComponentProps from "../../../PageComponentProps";
import MetricExplorer from "../../../Components/Metrics/MetricExplorer";
import PageComponentProps from "../../PageComponentProps";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const TelemetryMetricViewPage: FunctionComponent<
const MetricViewPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
return (
@ -14,4 +14,4 @@ const TelemetryMetricViewPage: FunctionComponent<
);
};
export default TelemetryMetricViewPage;
export default MetricViewPage;

View file

@ -0,0 +1,23 @@
import { getMetricsBreadcrumbs } from "../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../Utils/RouteMap";
import PageComponentProps from "../../PageComponentProps";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet } from "react-router-dom";
const MetricsViewLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<Page
title="Metrics Explorer"
breadcrumbLinks={getMetricsBreadcrumbs(path)}
>
<Outlet />
</Page>
);
};
export default MetricsViewLayout;

View file

@ -1,21 +0,0 @@
import PageComponentProps from "../PageComponentProps";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import React, { FunctionComponent, ReactElement } from "react";
import ComingSoon from "Common/UI/Components/ComingSoon/ComingSoon";
const Services: FunctionComponent<PageComponentProps> = (
props: PageComponentProps,
): ReactElement => {
const disableTelemetryForThisProject: boolean =
props.currentProject?.reseller?.enableTelemetryFeatures === false;
if (disableTelemetryForThisProject) {
return (
<ErrorMessage message="Looks like you have bought this plan from a reseller. It did not include telemetry features in your plan. Telemetry features are disabled for this project." />
);
}
return <ComingSoon />;
};
export default Services;

View file

@ -1,15 +0,0 @@
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
import PageComponentProps from "../PageComponentProps";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const TelemetryDocumentationPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
return (
<Fragment>
<TelemetryDocumentation />
</Fragment>
);
};
export default TelemetryDocumentationPage;

View file

@ -1,35 +0,0 @@
import { getTelemetryBreadcrumbs } from "../../Utils/Breadcrumbs";
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import SideMenu from "./SideMenu";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet } from "react-router-dom";
const TelemetryLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
if (path.endsWith("telemetry") || path.endsWith("telemetry/*")) {
Navigation.navigate(
RouteUtil.populateRouteParams(RouteMap[PageMap.TELEMETRY_SERVICES]!),
);
return <></>;
}
return (
<Page
title="Telemetry & APM"
breadcrumbLinks={getTelemetryBreadcrumbs(path)}
sideMenu={<SideMenu />}
>
<Outlet />
</Page>
);
};
export default TelemetryLayout;

View file

@ -1,21 +0,0 @@
import PageComponentProps from "../PageComponentProps";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import React, { FunctionComponent, ReactElement } from "react";
import TelemetryServiceTable from "../../Components/TelemetryService/TelemetryServiceTable";
const Services: FunctionComponent<PageComponentProps> = (
props: PageComponentProps,
): ReactElement => {
const disableTelemetryForThisProject: boolean =
props.currentProject?.reseller?.enableTelemetryFeatures === false;
if (disableTelemetryForThisProject) {
return (
<ErrorMessage message="Looks like you have bought this plan from a reseller. It did not include telemetry features in your plan. Telemetry features are disabled for this project." />
);
}
return <TelemetryServiceTable />;
};
export default Services;

View file

@ -1,34 +0,0 @@
import PageMap from "../../../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import Route from "Common/Types/API/Route";
import ObjectID from "Common/Types/ObjectID";
import ModelDelete from "Common/UI/Components/ModelDelete/ModelDelete";
import Navigation from "Common/UI/Utils/Navigation";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<ModelDelete
modelType={Service}
modelId={modelId}
onDeleteSuccess={() => {
Navigation.navigate(
RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES] as Route,
{ modelId },
),
);
}}
/>
</Fragment>
);
};
export default ServiceDelete;

View file

@ -1,15 +0,0 @@
import TelemetryDocumentation from "../../../../Components/Telemetry/Documentation";
import PageComponentProps from "../../../PageComponentProps";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const TelemetryDocumentationPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
return (
<Fragment>
<TelemetryDocumentation />
</Fragment>
);
};
export default TelemetryDocumentationPage;

View file

@ -1,124 +0,0 @@
import LabelsElement from "Common/UI/Components/Label/Labels";
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import Label from "Common/Models/DatabaseModels/Label";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(0);
return (
<Fragment>
{/* Service View */}
<CardModelDetail<Service>
name="Service Details"
formSteps={[
{
title: "Service Info",
id: "service-info",
},
{
title: "Labels",
id: "labels",
},
]}
cardProps={{
title: "Service Details",
description: "Here are more details for this service.",
}}
isEditable={true}
formFields={[
{
field: {
name: true,
},
stepId: "service-info",
title: "Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "Service Name",
validation: {
minLength: 2,
},
},
{
field: {
description: true,
},
stepId: "service-info",
title: "Description",
fieldType: FormFieldSchemaType.LongText,
required: false,
placeholder: "Description",
},
{
field: {
labels: true,
},
stepId: "labels",
title: "Labels ",
description:
"Team members with access to these labels will only be able to access this resource. This is optional and an advanced feature.",
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownModal: {
type: Label,
labelField: "name",
valueField: "_id",
},
required: false,
placeholder: "Labels",
},
]}
modelDetailProps={{
showDetailsInNumberOfColumns: 2,
modelType: Service,
id: "model-detail-services",
fields: [
{
field: {
_id: true,
},
title: "Service ID",
fieldType: FieldType.ObjectID,
},
{
field: {
name: true,
},
title: "Service Name",
},
{
field: {
labels: {
name: true,
color: true,
},
},
title: "Labels",
fieldType: FieldType.Element,
getElement: (item: Service): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},
{
field: {
description: true,
},
title: "Description",
},
],
modelId: modelId,
}}
/>
</Fragment>
);
};
export default ServiceDelete;

View file

@ -1,32 +0,0 @@
import { getTelemetryBreadcrumbs } from "../../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import SideMenu from "./SideMenu";
import ObjectID from "Common/Types/ObjectID";
import ModelPage from "Common/UI/Components/Page/ModelPage";
import Navigation from "Common/UI/Utils/Navigation";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet, useParams } from "react-router-dom";
const ServiceViewLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const { id } = useParams();
const modelId: ObjectID = new ObjectID(id || "");
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<ModelPage
title="Service"
modelType={Service}
modelId={modelId}
modelNameField="name"
breadcrumbLinks={getTelemetryBreadcrumbs(path)}
sideMenu={<SideMenu modelId={modelId} />}
>
<Outlet />
</ModelPage>
);
};
export default ServiceViewLayout;

View file

@ -1,25 +0,0 @@
import DashboardLogsViewer from "../../../../../Components/Logs/LogsViewer";
import PageComponentProps from "../../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<DashboardLogsViewer
showFilters={true}
serviceIds={[modelId]}
enableRealtime={true}
limit={100}
id="logs"
/>
</Fragment>
);
};
export default ServiceDelete;

View file

@ -1,74 +0,0 @@
import PageComponentProps from "../../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import Service from "Common/Models/DatabaseModels/Service";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import API from "Common/UI/Utils/API/API";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import MetricsTable from "../../../../../Components/Metrics/MetricsTable";
const MetricsTablePage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [service, setService] = useState<Service | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string>("");
useEffect(() => {
fetchService().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
const fetchService: PromiseVoidFunction = async (): Promise<void> => {
try {
setIsLoading(true);
const service: Service | null = await ModelAPI.getItem({
modelType: Service,
id: modelId,
select: {
name: true,
},
});
if (!service) {
setIsLoading(false);
setError("Service not found.");
return;
}
setService(service);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(API.getFriendlyMessage(err));
}
};
if (error) {
return <ErrorMessage message={error} />;
}
if (isLoading) {
return <PageLoader isVisible={true} />;
}
if (!service) {
return <ErrorMessage message="Service not found." />;
}
return <MetricsTable serviceIds={[service.id!]} />;
};
export default MetricsTablePage;

View file

@ -1,11 +0,0 @@
import PageComponentProps from "../../../../../PageComponentProps";
import React, { FunctionComponent, ReactElement } from "react";
import MetricExplorer from "../../../../../../Components/Metrics/MetricExplorer";
const MetricViewPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
return <MetricExplorer />;
};
export default MetricViewPage;

View file

@ -1,97 +0,0 @@
import PageComponentProps from "../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<CardModelDetail
name="Data Retention"
cardProps={{
title: "Telemetry Data Retention",
description:
"Configure how long you want to keep your telemetry data - like Logs, Metrics, and Traces.",
}}
isEditable={true}
editButtonText="Edit Data Retention"
formFields={[
{
field: {
retainTelemetryDataForDays: true,
},
title: "Telemetry Data Retention (Days)",
description:
"How long do you want to keep your telemetry data - like Logs, Metrics, and Traces.",
fieldType: FormFieldSchemaType.Number,
required: true,
placeholder: "15",
},
]}
modelDetailProps={{
modelType: Service,
id: "model-detail-project",
fields: [
{
field: {
retainTelemetryDataForDays: true,
},
title: "Telemetry Data Retention (Days)",
description:
"How long do you want to keep your telemetry data - like Logs, Metrics, and Traces.",
fieldType: FieldType.Number,
},
],
modelId: modelId,
}}
/>
<CardModelDetail
name="Telemetry Service Settings"
cardProps={{
title: "Telemetry Service Settings",
description: "Configure settings for your telemetry service.",
}}
isEditable={true}
editButtonText="Edit Settings"
formFields={[
{
field: {
serviceColor: true,
},
title: "Service Color",
description: "Choose a color for your telemetry service.",
fieldType: FormFieldSchemaType.Color,
required: true,
placeholder: "15",
},
]}
modelDetailProps={{
modelType: Service,
id: "model-detail-project",
fields: [
{
field: {
serviceColor: true,
},
title: "Service Color",
description: "Color for your telemetry service.",
fieldType: FieldType.Color,
},
],
modelId: modelId,
}}
/>
</Fragment>
);
};
export default ServiceDelete;

View file

@ -1,102 +0,0 @@
import PageMap from "../../../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import ObjectID from "Common/Types/ObjectID";
import SideMenu from "Common/UI/Components/SideMenu/SideMenu";
import SideMenuItem from "Common/UI/Components/SideMenu/SideMenuItem";
import SideMenuSection from "Common/UI/Components/SideMenu/SideMenuSection";
import React, { FunctionComponent, ReactElement } from "react";
export interface ComponentProps {
modelId: ObjectID;
}
const DashboardSideMenu: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<SideMenu>
<SideMenuSection title="Basic">
<SideMenuItem
link={{
title: "Overview",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Info}
/>
<SideMenuItem
link={{
title: "Documentation",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Book}
/>
</SideMenuSection>
<SideMenuSection title="Telemetry">
<SideMenuItem
link={{
title: "Logs",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_LOGS] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Logs}
/>
<SideMenuItem
link={{
title: "Traces",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_TRACES] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.RectangleStack}
/>
<SideMenuItem
link={{
title: "Metrics",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_METRICS] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.ChartBar}
/>
</SideMenuSection>
<SideMenuSection title="Advanced">
<SideMenuItem
link={{
title: "Settings",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Settings}
/>
<SideMenuItem
link={{
title: "Delete Service",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_DELETE] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Trash}
className="danger-on-hover"
/>
</SideMenuSection>
</SideMenu>
);
};
export default DashboardSideMenu;

View file

@ -1,17 +0,0 @@
import PageComponentProps from "../../../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import TraceTable from "../../../../../Components/Traces/TraceTable";
const TracesList: FunctionComponent<PageComponentProps> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<Fragment>
<TraceTable modelId={modelId} />
</Fragment>
);
};
export default TracesList;

View file

@ -1,26 +0,0 @@
import PageComponentProps from "../../../../../PageComponentProps";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import TraceExplorer from "../../../../../../Components/Traces/TraceExplorer";
const TraceView: FunctionComponent<PageComponentProps> = (): ReactElement => {
const traceId: string = Navigation.getLastParamAsString(0);
const spanIdQuery: string | null = Navigation.getQueryStringByName("spanId");
const highlightSpanIds: string[] = spanIdQuery
? spanIdQuery
.split(",")
.map((spanId: string) => {
return spanId.trim();
})
.filter((spanId: string) => {
return spanId.length > 0;
})
: [];
return (
<TraceExplorer traceId={traceId} highlightSpanIds={highlightSpanIds} />
);
};
export default TraceView;

View file

@ -1,72 +0,0 @@
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import SideMenu, {
SideMenuSectionProps,
} from "Common/UI/Components/SideMenu/SideMenu";
import React, { FunctionComponent, ReactElement } from "react";
const DashboardSideMenu: FunctionComponent = (): ReactElement => {
const sections: SideMenuSectionProps[] = [
{
title: "Basic",
items: [
{
link: {
title: "Services",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_SERVICES] as Route,
),
},
icon: IconProp.SquareStack,
},
{
link: {
title: "Documentation",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_DOCUMENTATION] as Route,
),
},
icon: IconProp.Info,
},
],
},
{
title: "Telemetry",
items: [
{
link: {
title: "Logs",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_LOGS] as Route,
),
},
icon: IconProp.Logs,
},
{
link: {
title: "Traces",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_TRACES] as Route,
),
},
icon: IconProp.RectangleStack,
},
{
link: {
title: "Metrics",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TELEMETRY_METRICS] as Route,
),
},
icon: IconProp.ChartBar,
},
],
},
];
return <SideMenu sections={sections} />;
};
export default DashboardSideMenu;

View file

@ -3,7 +3,7 @@ import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import React, { FunctionComponent, ReactElement } from "react";
import TraceTable from "../../Components/Traces/TraceTable";
const Services: FunctionComponent<PageComponentProps> = (
const TracesPage: FunctionComponent<PageComponentProps> = (
props: PageComponentProps,
): ReactElement => {
const disableTelemetryForThisProject: boolean =
@ -18,4 +18,4 @@ const Services: FunctionComponent<PageComponentProps> = (
return <TraceTable />;
};
export default Services;
export default TracesPage;

View file

@ -1,6 +1,7 @@
import { getTelemetryBreadcrumbs } from "../../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../../Utils/RouteMap";
import PageComponentProps from "../../../PageComponentProps";
import { getTracesBreadcrumbs } from "../../Utils/Breadcrumbs";
import { RouteUtil } from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import SideMenu from "./SideMenu";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
@ -10,10 +11,12 @@ const TracesLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<Page
title="Trace Explorer"
breadcrumbLinks={getTelemetryBreadcrumbs(path)}
title="Traces"
breadcrumbLinks={getTracesBreadcrumbs(path)}
sideMenu={<SideMenu />}
>
<Outlet />
</Page>

View file

@ -0,0 +1,31 @@
import PageMap from "../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import IconProp from "Common/Types/Icon/IconProp";
import SideMenu, {
SideMenuSectionProps,
} from "Common/UI/Components/SideMenu/SideMenu";
import React, { FunctionComponent, ReactElement } from "react";
const DashboardSideMenu: FunctionComponent = (): ReactElement => {
const sections: SideMenuSectionProps[] = [
{
title: "Traces",
items: [
{
link: {
title: "All Traces",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.TRACES] as Route,
),
},
icon: IconProp.RectangleStack,
},
],
},
];
return <SideMenu sections={sections} />;
};
export default DashboardSideMenu;

View file

@ -1,9 +1,11 @@
import PageComponentProps from "../../../PageComponentProps";
import PageComponentProps from "../../PageComponentProps";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import TraceExplorer from "../../../../Components/Traces/TraceExplorer";
import TraceExplorer from "../../../Components/Traces/TraceExplorer";
const TraceView: FunctionComponent<PageComponentProps> = (): ReactElement => {
const TraceViewPage: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const traceId: string = Navigation.getLastParamAsString(0);
const spanIdQuery: string | null = Navigation.getQueryStringByName("spanId");
@ -23,4 +25,4 @@ const TraceView: FunctionComponent<PageComponentProps> = (): ReactElement => {
);
};
export default TraceView;
export default TraceViewPage;

View file

@ -0,0 +1,20 @@
import { getTracesBreadcrumbs } from "../../../Utils/Breadcrumbs";
import { RouteUtil } from "../../../Utils/RouteMap";
import PageComponentProps from "../../PageComponentProps";
import Page from "Common/UI/Components/Page/Page";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet } from "react-router-dom";
const TracesViewLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const path: string = Navigation.getRoutePath(RouteUtil.getRoutes());
return (
<Page title="Trace Explorer" breadcrumbLinks={getTracesBreadcrumbs(path)}>
<Outlet />
</Page>
);
};
export default TracesViewLayout;

View file

@ -0,0 +1,45 @@
import Loader from "../Components/Loader/Loader";
import ComponentProps from "../Pages/PageComponentProps";
import LogsLayout from "../Pages/Logs/Layout";
import PageMap from "../Utils/PageMap";
import RouteMap from "../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import React, {
FunctionComponent,
LazyExoticComponent,
ReactElement,
Suspense,
lazy,
} from "react";
import { Route as PageRoute, Routes } from "react-router-dom";
// Lazy Pages
const LogsPage: LazyExoticComponent<FunctionComponent<ComponentProps>> = lazy(
() => {
return import("../Pages/Logs/Index");
},
);
const LogsRoutes: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<Routes>
<PageRoute path="/" element={<LogsLayout {...props} />}>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<LogsPage
{...props}
pageRoute={RouteMap[PageMap.LOGS] as Route}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);
};
export default LogsRoutes;

View file

@ -0,0 +1,80 @@
import Loader from "../Components/Loader/Loader";
import ComponentProps from "../Pages/PageComponentProps";
import MetricsLayout from "../Pages/Metrics/Layout";
import MetricsViewLayout from "../Pages/Metrics/View/Layout";
import PageMap from "../Utils/PageMap";
import RouteMap, { RouteUtil, MetricsRoutePath } from "../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import React, {
FunctionComponent,
LazyExoticComponent,
ReactElement,
Suspense,
lazy,
} from "react";
import { Route as PageRoute, Routes } from "react-router-dom";
// Lazy Pages
const MetricsPage: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Metrics/Index");
});
const MetricViewPage: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Metrics/View/Index");
});
const MetricsRoutes: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<Routes>
<PageRoute path="/" element={<MetricsLayout {...props} />}>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<MetricsPage
{...props}
pageRoute={RouteMap[PageMap.METRICS] as Route}
/>
</Suspense>
}
/>
</PageRoute>
{/* Metric View */}
<PageRoute
path={MetricsRoutePath[PageMap.METRIC_VIEW] || ""}
element={<MetricsViewLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<MetricViewPage
{...props}
pageRoute={RouteMap[PageMap.METRIC_VIEW] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.METRIC_VIEW)}
element={
<Suspense fallback={Loader}>
<MetricViewPage
{...props}
pageRoute={RouteMap[PageMap.METRIC_VIEW] as Route}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);
};
export default MetricsRoutes;

View file

@ -1,405 +0,0 @@
import Loader from "../Components/Loader/Loader";
import ComponentProps from "../Pages/PageComponentProps";
import TelemetryServiceViewLayout from "../Pages/Telemetry/Services/View/Layout";
import TelemetryMetricLayout from "../Pages/Telemetry/Metrics/View/Layout";
import TelemetryTraceLayout from "../Pages/Telemetry/Traces/View/Layout";
import TelemetryViewLayout from "../Pages/Telemetry/Layout";
import PageMap from "../Utils/PageMap";
import RouteMap, { RouteUtil, TelemetryRoutePath } from "../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import React, {
FunctionComponent,
LazyExoticComponent,
ReactElement,
Suspense,
lazy,
} from "react";
import { Route as PageRoute, Routes } from "react-router-dom";
// Lazy Pages
const TelemetryServices: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services");
});
const TelemetryDocumentation: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Documentation");
});
const TelemetryLogs: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Telemetry/Logs");
});
const TelemetryViewTrace: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Traces/View/Index");
});
const TelemetryTraces: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Telemetry/Traces");
});
const TelemetryMetrics: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Telemetry/Metrics");
});
const TelemetryViewMetric: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Metrics/View/Index");
});
const TelemetryServiceView: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Index");
});
const TelemetryServiceViewDelete: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Delete");
});
const TelemetryServiceViewLogs: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Logs/Index");
});
const TelemetryServiceViewTraces: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Traces/Index");
});
const TelemetryServiceViewTrace: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Traces/View/Index");
});
const TelemetryServiceViewMetric: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Metrics/View/Index");
});
const TelemetryServiceViewMetrics: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Metrics/Index");
});
const TelemetryServicesViewSettings: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Settings");
});
const TelemetryServicesViewDocumentation: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Telemetry/Services/View/Documentation");
});
const TelemetryRoutes: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<Routes>
<PageRoute path="/" element={<TelemetryViewLayout {...props} />}>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TelemetryServices
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_LOGS] || ""}
element={
<Suspense fallback={Loader}>
<TelemetryLogs
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_LOGS] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_TRACES] || ""}
element={
<Suspense fallback={Loader}>
<TelemetryTraces
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_TRACES] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_METRICS] || ""}
element={
<Suspense fallback={Loader}>
<TelemetryMetrics
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_METRICS] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_SERVICES] || ""}
element={
<Suspense fallback={Loader}>
<TelemetryServices
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_SERVICES] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_DOCUMENTATION] || ""}
element={
<Suspense fallback={Loader}>
<TelemetryDocumentation
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_DOCUMENTATION] as Route}
/>
</Suspense>
}
/>
</PageRoute>
{/* Metric View */}
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_METRIC_ROOT] || ""}
element={<TelemetryMetricLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TelemetryViewMetric
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_METRIC_VIEW] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.TELEMETRY_METRIC_VIEW)}
element={
<Suspense fallback={Loader}>
<TelemetryViewMetric
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_METRIC_VIEW] as Route}
/>
</Suspense>
}
/>
</PageRoute>
{/* Trace View */}
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_TRACE_ROOT] || ""}
element={<TelemetryTraceLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TelemetryViewTrace
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_TRACE_VIEW] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.TELEMETRY_TRACE_VIEW)}
element={
<Suspense fallback={Loader}>
<TelemetryViewTrace
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_TRACE_VIEW] as Route}
/>
</Suspense>
}
/>
</PageRoute>
{/* Telemetry Service View */}
<PageRoute
path={TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW] || ""}
element={<TelemetryServiceViewLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TelemetryServiceView
{...props}
pageRoute={RouteMap[PageMap.TELEMETRY_SERVICES_VIEW] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_DELETE,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewDelete
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_DELETE] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_LOGS,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewLogs
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_LOGS] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_TRACE,
2,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewTrace
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_TRACE] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_TRACES,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewTraces
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_TRACES] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_METRIC,
2,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewMetric
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_METRIC] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_METRICS,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServiceViewMetrics
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_METRICS] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServicesViewSettings
{...props}
pageRoute={
RouteMap[PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION,
)}
element={
<Suspense fallback={Loader}>
<TelemetryServicesViewDocumentation
{...props}
pageRoute={
RouteMap[
PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION
] as Route
}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);
};
export default TelemetryRoutes;

View file

@ -0,0 +1,81 @@
import Loader from "../Components/Loader/Loader";
import ComponentProps from "../Pages/PageComponentProps";
import TracesLayout from "../Pages/Traces/Layout";
import TracesViewLayout from "../Pages/Traces/View/Layout";
import PageMap from "../Utils/PageMap";
import RouteMap, { RouteUtil, TracesRoutePath } from "../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import React, {
FunctionComponent,
LazyExoticComponent,
ReactElement,
Suspense,
lazy,
} from "react";
import { Route as PageRoute, Routes } from "react-router-dom";
// Lazy Pages
const TracesPage: LazyExoticComponent<FunctionComponent<ComponentProps>> = lazy(
() => {
return import("../Pages/Traces/Index");
},
);
const TraceViewPage: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Traces/View/Index");
});
const TracesRoutes: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<Routes>
<PageRoute path="/" element={<TracesLayout {...props} />}>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TracesPage
{...props}
pageRoute={RouteMap[PageMap.TRACES] as Route}
/>
</Suspense>
}
/>
</PageRoute>
{/* Trace View */}
<PageRoute
path={TracesRoutePath[PageMap.TRACE_VIEW] || ""}
element={<TracesViewLayout {...props} />}
>
<PageRoute
index
element={
<Suspense fallback={Loader}>
<TraceViewPage
{...props}
pageRoute={RouteMap[PageMap.TRACE_VIEW] as Route}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.TRACE_VIEW)}
element={
<Suspense fallback={Loader}>
<TraceViewPage
{...props}
pageRoute={RouteMap[PageMap.TRACE_VIEW] as Route}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);
};
export default TracesRoutes;

View file

@ -0,0 +1,11 @@
import PageMap from "../PageMap";
import { BuildBreadcrumbLinksByTitles } from "./Helper";
import Dictionary from "Common/Types/Dictionary";
import Link from "Common/Types/Link";
export function getLogsBreadcrumbs(path: string): Array<Link> | undefined {
const breadcrumpLinksMap: Dictionary<Link[]> = {
...BuildBreadcrumbLinksByTitles(PageMap.LOGS, ["Project", "Logs"]),
};
return breadcrumpLinksMap[path];
}

View file

@ -0,0 +1,16 @@
import PageMap from "../PageMap";
import { BuildBreadcrumbLinksByTitles } from "./Helper";
import Dictionary from "Common/Types/Dictionary";
import Link from "Common/Types/Link";
export function getMetricsBreadcrumbs(path: string): Array<Link> | undefined {
const breadcrumpLinksMap: Dictionary<Link[]> = {
...BuildBreadcrumbLinksByTitles(PageMap.METRICS, ["Project", "Metrics"]),
...BuildBreadcrumbLinksByTitles(PageMap.METRIC_VIEW, [
"Project",
"Metrics",
"Metrics Explorer",
]),
};
return breadcrumpLinksMap[path];
}

View file

@ -1,111 +0,0 @@
import PageMap from "../PageMap";
import { BuildBreadcrumbLinksByTitles } from "./Helper";
import Dictionary from "Common/Types/Dictionary";
import Link from "Common/Types/Link";
export function getTelemetryBreadcrumbs(path: string): Array<Link> | undefined {
const breadcrumpLinksMap: Dictionary<Link[]> = {
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES, [
"Project",
"Telemetry",
"Services",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_DOCUMENTATION, [
"Project",
"Telemetry",
"Documentation",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_LOGS, [
"Project",
"Telemetry",
"Logs",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_METRICS, [
"Project",
"Telemetry",
"Metrics",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_METRIC_VIEW, [
"Project",
"Telemetry",
"Metrics",
"Metrics Explorer",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_TRACE_VIEW, [
"Project",
"Telemetry",
"Traces",
"Trace Explorer",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_TRACES, [
"Project",
"Telemetry",
"Traces",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW, [
"Project",
"Telemetry",
"Services",
"View Service",
"Overview",
]),
...BuildBreadcrumbLinksByTitles(
PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION,
["Project", "Telemetry", "Services", "View Service", "Documentation"],
),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_LOGS, [
"Project",
"Telemetry",
"Services",
"View Service",
"Logs",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_METRICS, [
"Project",
"Telemetry",
"Services",
"View Service",
"Metrics",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_TRACES, [
"Project",
"Telemetry",
"Services",
"View Service",
"Traces",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_TRACE, [
"Project",
"Telemetry",
"Services",
"View Service",
"Traces",
"View Trace",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_METRIC, [
"Project",
"Telemetry",
"Services",
"View Service",
"Metrics",
"View Metric",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS, [
"Project",
"Telemetry",
"Services",
"View Service",
"Settings",
]),
...BuildBreadcrumbLinksByTitles(PageMap.TELEMETRY_SERVICES_VIEW_DELETE, [
"Project",
"Telemetry",
"Services",
"View Service",
"Delete Service",
]),
};
return breadcrumpLinksMap[path];
}

View file

@ -0,0 +1,16 @@
import PageMap from "../PageMap";
import { BuildBreadcrumbLinksByTitles } from "./Helper";
import Dictionary from "Common/Types/Dictionary";
import Link from "Common/Types/Link";
export function getTracesBreadcrumbs(path: string): Array<Link> | undefined {
const breadcrumpLinksMap: Dictionary<Link[]> = {
...BuildBreadcrumbLinksByTitles(PageMap.TRACES, ["Project", "Traces"]),
...BuildBreadcrumbLinksByTitles(PageMap.TRACE_VIEW, [
"Project",
"Traces",
"Trace Explorer",
]),
};
return breadcrumpLinksMap[path];
}

View file

@ -4,7 +4,9 @@ export * from "./ScheduledMaintenanceBreadcrumbs";
export * from "./StatusPagesBreadcrumbs";
export * from "./WorkflowsBreadcrumbs";
export * from "./OnCallDutyBreadcrumbs";
export * from "./TelemetryBreadcrumbs";
export * from "./LogsBreadcrumbs";
export * from "./MetricsBreadcrumbs";
export * from "./TracesBreadcrumbs";
export * from "./SettingsBreadcrumbs";
export * from "./MonitorGroupBreadcrumbs";
export * from "./ServiceBreadcrumbs";

View file

@ -8,42 +8,19 @@ enum PageMap {
//SSO
PROJECT_SSO = "PROJECT_SSO",
// Telemetry
TELEMETRY_ROOT = "TELEMETRY_ROOT",
TELEMETRY_METRIC_ROOT = "TELEMETRY_METRIC_ROOT",
TELEMETRY_TRACE_ROOT = "TELEMETRY_TRACE_ROOT",
TELEMETRY_LOG_ROOT = "TELEMETRY_LOG_ROOT",
// Logs (standalone product)
LOGS_ROOT = "LOGS_ROOT",
LOGS = "LOGS",
TELEMETRY_SERVICES_VIEW_ROOT = "TELEMETRY_SERVICES_VIEW_ROOT",
TELEMETRY = "TELEMETRY",
TELEMETRY_SERVICES = "TELEMETRY_SERVICES",
TELEMETRY_DOCUMENTATION = "TELEMETRY_DOCUMENTATION",
// Metrics (standalone product)
METRICS_ROOT = "METRICS_ROOT",
METRICS = "METRICS",
METRIC_VIEW = "METRIC_VIEW",
TELEMETRY_TRACES = "TELEMETRY_TRACES",
TELEMETRY_TRACE_VIEW = "TELEMETRY_TRACE_VIEW",
TELEMETRY_METRICS = "TELEMETRY_METRICS",
TELEMETRY_METRIC_VIEW = "TELEMETRY_METRIC_VIEW",
TELEMETRY_LOGS = "TELEMETRY_LOGS",
TELEMETRY_SERVICES_VIEW = "TELEMETRY_SERVICES_VIEW",
TELEMETRY_SERVICES_VIEW_DELETE = "TELEMETRY_SERVICES_VIEW_DELETE",
TELEMETRY_SERVICES_VIEW_SETTINGS = "TELEMETRY_SERVICES_VIEW_SETTINGS",
// Telemetry - LOGS
TELEMETRY_SERVICES_VIEW_LOGS = "TELEMETRY_SERVICE_VIEW_LOGS",
// Traces
TELEMETRY_SERVICES_VIEW_TRACES = "TELEMETRY_SERVICE_VIEW_TRACES",
TELEMETRY_SERVICES_VIEW_TRACE = "TELEMETRY_SERVICE_VIEW_TRACE",
// Metrics
TELEMETRY_SERVICES_VIEW_METRICS = "TELEMETRY_SERVICE_VIEW_METRICS",
TELEMETRY_SERVICES_VIEW_METRIC = "TELEMETRY_SERVICE_VIEW_METRIC",
// Docuemntation
TELEMETRY_SERVICES_VIEW_DOCUMENTATION = "TELEMETRY_SERVICES_VIEW_DOCUMENTATION",
// Traces (standalone product)
TRACES_ROOT = "TRACES_ROOT",
TRACES = "TRACES",
TRACE_VIEW = "TRACE_VIEW",
HOME = "HOME",
HOME_NOT_OPERATIONAL_MONITORS = "HOME_NOT_OPERATIONAL_MONITORS",
@ -212,8 +189,6 @@ enum PageMap {
STATUS_PAGE_VIEW_SETTINGS = "STATUS_PAGE_VIEW_SETTINGS",
STATUS_PAGE_VIEW_NOTIFICATION_LOGS = "STATUS_PAGE_VIEW_NOTIFICATION_LOGS",
LOGS = "LOGS",
ON_CALL_DUTY_ROOT = "ON_CALL_DUTY_ROOT",
ON_CALL_DUTY = "ON_CALL_DUTY",
ON_CALL_DUTY_POLICIES = "ON_CALL_DUTY_POLICIES",

View file

@ -71,31 +71,21 @@ export const AIAgentTasksRoutePath: Dictionary<string> = {
[PageMap.AI_AGENT_TASK_VIEW_DELETE]: `${RouteParams.ModelID}/delete`,
};
export const TelemetryRoutePath: Dictionary<string> = {
[PageMap.TELEMETRY_SERVICES]: "services",
[PageMap.TELEMETRY_DOCUMENTATION]: "documentation",
[PageMap.TELEMETRY_LOGS]: "logs",
[PageMap.TELEMETRY_TRACES]: "traces",
[PageMap.TELEMETRY_METRICS]: "metrics",
[PageMap.TELEMETRY_SERVICES_VIEW_ROOT]: "services",
// Logs product routes
export const LogsRoutePath: Dictionary<string> = {
[PageMap.LOGS]: "",
};
[PageMap.TELEMETRY_METRIC_ROOT]: `metric`,
[PageMap.TELEMETRY_METRIC_VIEW]: `metric/view`,
// Metrics product routes
export const MetricsRoutePath: Dictionary<string> = {
[PageMap.METRICS]: "",
[PageMap.METRIC_VIEW]: "view",
};
[PageMap.TELEMETRY_TRACE_ROOT]: `traces/view`,
[PageMap.TELEMETRY_TRACE_VIEW]: `traces/view/${RouteParams.ModelID}`, // modelID is spanId
[PageMap.TELEMETRY_LOG_ROOT]: `logs`,
[PageMap.TELEMETRY_SERVICES_VIEW]: `services/${RouteParams.ModelID}`,
[PageMap.TELEMETRY_SERVICES_VIEW_DELETE]: `services/${RouteParams.ModelID}/delete`,
[PageMap.TELEMETRY_SERVICES_VIEW_LOGS]: `services/${RouteParams.ModelID}/logs`,
[PageMap.TELEMETRY_SERVICES_VIEW_TRACES]: `services/${RouteParams.ModelID}/traces`,
[PageMap.TELEMETRY_SERVICES_VIEW_TRACE]: `services/${RouteParams.ModelID}/traces/${RouteParams.SubModelID}`,
[PageMap.TELEMETRY_SERVICES_VIEW_METRICS]: `services/${RouteParams.ModelID}/metrics`,
[PageMap.TELEMETRY_SERVICES_VIEW_METRIC]: `services/${RouteParams.ModelID}/metrics/view`,
[PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS]: `services/${RouteParams.ModelID}/settings`,
[PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION]: `services/${RouteParams.ModelID}/documentation`,
// Traces product routes
export const TracesRoutePath: Dictionary<string> = {
[PageMap.TRACES]: "",
[PageMap.TRACE_VIEW]: `view/${RouteParams.ModelID}`,
};
export const ExceptionsRoutePath: Dictionary<string> = {
@ -1376,124 +1366,34 @@ const RouteMap: Dictionary<Route> = {
`/dashboard/${RouteParams.ProjectID}/error-tracker/`,
),
[PageMap.TELEMETRY_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/*`,
// Logs Product Routes
[PageMap.LOGS_ROOT]: new Route(`/dashboard/${RouteParams.ProjectID}/logs/*`),
[PageMap.LOGS]: new Route(`/dashboard/${RouteParams.ProjectID}/logs`),
// Metrics Product Routes
[PageMap.METRICS_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/metrics/*`,
),
[PageMap.TELEMETRY]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES]
[PageMap.METRICS]: new Route(`/dashboard/${RouteParams.ProjectID}/metrics`),
[PageMap.METRIC_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/metrics/${
MetricsRoutePath[PageMap.METRIC_VIEW]
}`,
),
[PageMap.TELEMETRY_SERVICES]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES]
}`,
// Traces Product Routes
[PageMap.TRACES_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/traces/*`,
),
[PageMap.TELEMETRY_DOCUMENTATION]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_DOCUMENTATION]
}`,
),
[PageMap.TRACES]: new Route(`/dashboard/${RouteParams.ProjectID}/traces`),
[PageMap.TELEMETRY_LOGS]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_LOGS]
}`,
),
[PageMap.TELEMETRY_METRICS]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_METRICS]
}`,
),
[PageMap.TELEMETRY_METRIC_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_METRIC_VIEW]
}`,
),
[PageMap.TELEMETRY_TRACE_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_TRACE_VIEW]
}`,
),
[PageMap.TELEMETRY_TRACE_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_TRACE_ROOT]
}`,
),
[PageMap.TELEMETRY_TRACES]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_TRACES]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_ROOT]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_ROOT]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_DOCUMENTATION]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_TRACE]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_TRACE]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_METRIC]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_METRIC]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_DELETE]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_DELETE]
}`,
),
[PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_SETTINGS]
}`,
),
//TELEMETRY_SERVICE_VIEW_LOGS
[PageMap.TELEMETRY_SERVICES_VIEW_LOGS]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_LOGS]
}`,
),
//TELEMETRY_SERVICE_VIEW_TRACES
[PageMap.TELEMETRY_SERVICES_VIEW_TRACES]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_TRACES]
}`,
),
// Metrics
[PageMap.TELEMETRY_SERVICES_VIEW_METRICS]: new Route(
`/dashboard/${RouteParams.ProjectID}/telemetry/${
TelemetryRoutePath[PageMap.TELEMETRY_SERVICES_VIEW_METRICS]
[PageMap.TRACE_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/traces/${
TracesRoutePath[PageMap.TRACE_VIEW]
}`,
),