forked from Github/frigate
Improve stats (#10911)
* Add overview stats for overall detection and skipped fps * Fix intel memory stats * Fix iOS image long pressing * Cleanup
This commit is contained in:
@@ -19,7 +19,7 @@ export default function CameraMetrics({
|
||||
// stats
|
||||
|
||||
const { data: initialStats } = useSWR<FrigateStats[]>(
|
||||
["stats/history", { keys: "cpu_usages,cameras,service" }],
|
||||
["stats/history", { keys: "cpu_usages,cameras,detection_fps,service" }],
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
},
|
||||
@@ -57,6 +57,44 @@ export default function CameraMetrics({
|
||||
|
||||
// stats data
|
||||
|
||||
const overallFpsSeries = useMemo(() => {
|
||||
if (!statsHistory) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const series: {
|
||||
[key: string]: { name: string; data: { x: number; y: number }[] };
|
||||
} = {};
|
||||
|
||||
series["overall_dps"] = { name: "overall detections per second", data: [] };
|
||||
series["overall_skipped_dps"] = {
|
||||
name: "overall skipped detections per second",
|
||||
data: [],
|
||||
};
|
||||
|
||||
statsHistory.forEach((stats, statsIdx) => {
|
||||
if (!stats) {
|
||||
return;
|
||||
}
|
||||
|
||||
series["overall_dps"].data.push({
|
||||
x: statsIdx,
|
||||
y: stats.detection_fps,
|
||||
});
|
||||
|
||||
let skipped = 0;
|
||||
Object.values(stats.cameras).forEach(
|
||||
(camStat) => (skipped += camStat.skipped_fps),
|
||||
);
|
||||
|
||||
series["overall_skipped_dps"].data.push({
|
||||
x: statsIdx,
|
||||
y: skipped,
|
||||
});
|
||||
});
|
||||
return Object.values(series);
|
||||
}, [statsHistory]);
|
||||
|
||||
const cameraCpuSeries = useMemo(() => {
|
||||
if (!statsHistory || statsHistory.length == 0) {
|
||||
return {};
|
||||
@@ -147,19 +185,36 @@ export default function CameraMetrics({
|
||||
}, [statsHistory]);
|
||||
|
||||
return (
|
||||
<div className="size-full mt-4 flex flex-col overflow-y-auto">
|
||||
<div className="size-full mt-4 flex flex-col gap-3 overflow-y-auto">
|
||||
<div className="text-muted-foreground text-sm font-medium">Overview</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3">
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">DPS</div>
|
||||
<CameraLineGraph
|
||||
graphId="overall-stats"
|
||||
unit=" DPS"
|
||||
dataLabels={["detect", "skipped"]}
|
||||
updateTimes={updateTimes}
|
||||
data={overallFpsSeries}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<Skeleton className="w-full h-32" />
|
||||
)}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{config &&
|
||||
Object.values(config.cameras).map((camera) => {
|
||||
if (camera.enabled) {
|
||||
return (
|
||||
<div className="w-full flex flex-col">
|
||||
<div className="mb-6 capitalize">
|
||||
<div className="w-full flex flex-col gap-3">
|
||||
<div className="capitalize text-muted-foreground text-sm font-medium">
|
||||
{camera.name.replaceAll("_", " ")}
|
||||
</div>
|
||||
<div key={camera.name} className="grid sm:grid-cols-2 gap-2">
|
||||
{Object.keys(cameraCpuSeries).includes(camera.name) ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">CPU</div>
|
||||
<CameraLineGraph
|
||||
graphId={`${camera.name}-cpu`}
|
||||
@@ -175,7 +230,7 @@ export default function CameraMetrics({
|
||||
<Skeleton className="size-full aspect-video" />
|
||||
)}
|
||||
{Object.keys(cameraFpsSeries).includes(camera.name) ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">DPS</div>
|
||||
<CameraLineGraph
|
||||
graphId={`${camera.name}-dps`}
|
||||
|
||||
@@ -193,6 +193,14 @@ export default function GeneralMetrics({
|
||||
return [];
|
||||
}
|
||||
|
||||
if (
|
||||
Object.keys(statsHistory?.at(0)?.gpu_usages ?? {}).length == 1 &&
|
||||
Object.keys(statsHistory?.at(0)?.gpu_usages ?? {})[0].includes("intel")
|
||||
) {
|
||||
// intel gpu stats do not support memory
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const series: {
|
||||
[key: string]: { name: string; data: { x: number; y: string }[] };
|
||||
} = {};
|
||||
@@ -285,7 +293,7 @@ export default function GeneralMetrics({
|
||||
</div>
|
||||
<div className="w-full mt-4 grid grid-cols-1 sm:grid-cols-3 gap-2">
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">Detector Inference Speed</div>
|
||||
{detInferenceTimeSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
@@ -303,7 +311,7 @@ export default function GeneralMetrics({
|
||||
<Skeleton className="w-full aspect-video" />
|
||||
)}
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">Detector CPU Usage</div>
|
||||
{detCpuSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
@@ -321,7 +329,7 @@ export default function GeneralMetrics({
|
||||
<Skeleton className="w-full aspect-video" />
|
||||
)}
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">Detector Memory Usage</div>
|
||||
{detMemSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
@@ -358,7 +366,7 @@ export default function GeneralMetrics({
|
||||
</div>
|
||||
<div className=" mt-4 grid grid-cols-1 sm:grid-cols-2 gap-2">
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">GPU Usage</div>
|
||||
{gpuSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
@@ -376,20 +384,24 @@ export default function GeneralMetrics({
|
||||
<Skeleton className="w-full aspect-video" />
|
||||
)}
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="mb-5">GPU Memory</div>
|
||||
{gpuMemSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
key={series.name}
|
||||
graphId={`${series.name}-mem`}
|
||||
unit=""
|
||||
name={series.name}
|
||||
threshold={GPUMemThreshold}
|
||||
updateTimes={updateTimes}
|
||||
data={[series]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<>
|
||||
{gpuMemSeries && (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">GPU Memory</div>
|
||||
{gpuMemSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
key={series.name}
|
||||
graphId={`${series.name}-mem`}
|
||||
unit=""
|
||||
name={series.name}
|
||||
threshold={GPUMemThreshold}
|
||||
updateTimes={updateTimes}
|
||||
data={[series]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Skeleton className="w-full aspect-video" />
|
||||
)}
|
||||
@@ -402,7 +414,7 @@ export default function GeneralMetrics({
|
||||
</div>
|
||||
<div className="mt-4 grid grid-cols-1 sm:grid-cols-2 gap-2">
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">Process CPU Usage</div>
|
||||
{otherProcessCpuSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
@@ -420,7 +432,7 @@ export default function GeneralMetrics({
|
||||
<Skeleton className="w-full aspect-tall" />
|
||||
)}
|
||||
{statsHistory.length != 0 ? (
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl">
|
||||
<div className="mb-5">Process Memory Usage</div>
|
||||
{otherProcessMemSeries.map((series) => (
|
||||
<ThresholdBarGraph
|
||||
|
||||
@@ -43,9 +43,7 @@ export default function StorageMetrics({
|
||||
|
||||
return (
|
||||
<div className="size-full mt-4 flex flex-col overflow-y-auto">
|
||||
<div className="text-muted-foreground text-sm font-medium">
|
||||
General Storage
|
||||
</div>
|
||||
<div className="text-muted-foreground text-sm font-medium">Overview</div>
|
||||
<div className="mt-4 grid grid-cols-1 sm:grid-cols-3 gap-2">
|
||||
<div className="p-2.5 bg-background_alt rounded-2xl flex-col">
|
||||
<div className="mb-5">Recordings</div>
|
||||
|
||||
Reference in New Issue
Block a user