forked from Github/frigate
Add GPU stats to the /stats API and debug screen (#3931)
* Add ffprobe endpoint * Get ffprobe for multiple inputs * Copy ffprobe in output * Fix bad if statement * Return full output of ffprobe process * Return full output of ffprobe process * Make ffprobe button show dialog with output and option to copy * Add driver names to consts * Add driver env var name * Setup general tracking for GPU stats * Catch RPi args as well * Add util to get radeontop results * Add real amd GPU stats * Fix missed arg * pass config * Use only the values * Fix vram * Add nvidia gpu stats * Use nvidia stats * Add chart for gpu stats * Format AMD with space between percent * Get correct nvidia % * Start to add support for intel GPU stats * Block out RPi as util is not currently available * Formatting * Fix mypy * Strip for float conversion * Strip for float conversion * Fix percent formatting * Remove name from gpu map * Add tests and fix AMD formatting * Add nvidia gpu stats test * Formatting * Add intel_gpu_top for testing * Formatting * Handle case where hwaccel is not setup * Formatting * Check to remove none * Don't use set * Cleanup and fix types * Handle case where args is list * Fix mypy * Cast to str * Fix type checking * Return none instead of empty * Fix organization * Make keys consistent * Make gpu match style * Get support for vainfo * Add vainfo endpoint * Set vainfo output in error correctly * Remove duplicate function * Fix errors * Do cpu & gpu work asynchonously * Fix async * Fix event loop * Fix crash * Fix naming * Send empty data for gpu if error occurs * Show error if gpu stats could not be retrieved * Fix mypy * Fix test * Don't use json for vainfo * Fix cross references * Strip unicode still * await vainfo response * Add gpu deps * Formatting * remove comments * Use empty string * Add vainfo back in
This commit is contained in:
@@ -21,9 +21,17 @@ export default function System() {
|
||||
} = useWs('stats');
|
||||
const { data: initialStats } = useSWR('stats');
|
||||
|
||||
const { cpu_usages, detectors, service = {}, detection_fps: _, ...cameras } = stats || initialStats || emptyObject;
|
||||
const {
|
||||
cpu_usages,
|
||||
gpu_usages,
|
||||
detectors,
|
||||
service = {},
|
||||
detection_fps: _,
|
||||
...cameras
|
||||
} = stats || initialStats || emptyObject;
|
||||
|
||||
const detectorNames = Object.keys(detectors || emptyObject);
|
||||
const gpuNames = Object.keys(gpu_usages || emptyObject);
|
||||
const cameraNames = Object.keys(cameras || emptyObject);
|
||||
|
||||
const handleCopyConfig = useCallback(() => {
|
||||
@@ -55,9 +63,9 @@ export default function System() {
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
setState({ showFfprobe: true, ffprobe: JSON.stringify(response.data, null, 2) });
|
||||
setState({ ...state, showFfprobe: true, ffprobe: JSON.stringify(response.data, null, 2) });
|
||||
} else {
|
||||
setState({ ...state, ffprobe: 'There was an error getting the ffprobe output.' });
|
||||
setState({ ...state, showFfprobe: true, ffprobe: 'There was an error getting the ffprobe output.' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,11 +74,31 @@ export default function System() {
|
||||
setState({ ...state, ffprobe: '', showFfprobe: false });
|
||||
};
|
||||
|
||||
const onHandleVainfo = async (e) => {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
const response = await axios.get('vainfo');
|
||||
|
||||
if (response.status === 200) {
|
||||
setState({ ...state, showVainfo: true, vainfo: JSON.stringify(response.data, null, 2) });
|
||||
} else {
|
||||
setState({ ...state, showVainfo: true, vainfo: 'There was an error getting the vainfo output.' });
|
||||
}
|
||||
};
|
||||
|
||||
const onCopyVainfo = async () => {
|
||||
await window.navigator.clipboard.writeText(JSON.stringify(state.vaifp, null, 2));
|
||||
setState({ ...state, vainfo: '', showVainfo: false });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4 p-2 px-4">
|
||||
<Heading>
|
||||
System <span className="text-sm">{service.version}</span>
|
||||
</Heading>
|
||||
|
||||
{state.showFfprobe && (
|
||||
<Dialog>
|
||||
<div className="p-4">
|
||||
@@ -92,6 +120,23 @@ export default function System() {
|
||||
</Dialog>
|
||||
)}
|
||||
|
||||
{state.showVainfo && (
|
||||
<Dialog>
|
||||
<div className="p-4">
|
||||
<Heading size="lg">Vainfo Output</Heading>
|
||||
{state.vainfo != '' ? <p className="mb-2">{state.vainfo}</p> : <ActivityIndicator />}
|
||||
</div>
|
||||
<div className="p-2 flex justify-start flex-row-reverse space-x-2">
|
||||
<Button className="ml-2" onClick={() => onCopyVainfo()} type="text">
|
||||
Copy
|
||||
</Button>
|
||||
<Button className="ml-2" onClick={() => setState({ ...state, vainfo: '', showVainfo: false })} type="text">
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog>
|
||||
)}
|
||||
|
||||
{!detectors ? (
|
||||
<div>
|
||||
<ActivityIndicator />
|
||||
@@ -125,6 +170,50 @@ export default function System() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="text-lg flex justify-between p-4">
|
||||
<Heading size="lg">GPUs</Heading>
|
||||
<Button onClick={(e) => onHandleVainfo(e)}>vainfo</Button>
|
||||
</div>
|
||||
|
||||
{!gpu_usages ? (
|
||||
<div className="p-4">
|
||||
<Link href={'https://docs.frigate.video/configuration/hardware_acceleration'}>
|
||||
Hardware acceleration has not been setup, see the docs to setup hardware acceleration.
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div data-testid="gpus" className="grid grid-cols-1 3xl:grid-cols-3 md:grid-cols-2 gap-4">
|
||||
{gpuNames.map((gpu) => (
|
||||
<div key={gpu} className="dark:bg-gray-800 shadow-md hover:shadow-lg rounded-lg transition-shadow">
|
||||
<div className="text-lg flex justify-between p-4">{gpu}</div>
|
||||
<div className="p-2">
|
||||
{gpu_usages[gpu]['gpu'] == -1 ? (
|
||||
<div className="p-4">
|
||||
There was an error getting usage stats. Either your GPU does not support this or frigate does
|
||||
not have proper access.
|
||||
</div>
|
||||
) : (
|
||||
<Table className="w-full">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Gpu %</Th>
|
||||
<Th>Memory %</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
<Tr>
|
||||
<Td>{gpu_usages[gpu]['gpu']}</Td>
|
||||
<Td>{gpu_usages[gpu]['mem']}</Td>
|
||||
</Tr>
|
||||
</Tbody>
|
||||
</Table>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Heading size="lg">Cameras</Heading>
|
||||
<div data-testid="cameras" className="grid grid-cols-1 3xl:grid-cols-3 md:grid-cols-2 gap-4">
|
||||
{cameraNames.map((camera) => (
|
||||
|
||||
Reference in New Issue
Block a user