mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Logs in UI (#4562)
* Log all services to RAM * Gracefully handle shutdown * Add logs route * Remove tail * Return logs for services * Display log chooser with copy button * show logs for specific services * Clean up settings logs * Add copy functionality to logs * Add copy functionality to logs * Fix merge * Set archive count to 0 Co-authored-by: Felipe Santos <felipecassiors@gmail.com>
This commit is contained in:
parent
4f79ca1bf0
commit
964bcc0733
@ -180,8 +180,8 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||
# But this is not working currently because of:
|
||||
# https://github.com/just-containers/s6-overlay/issues/503
|
||||
ENV S6_SERVICES_GRACETIME=30000
|
||||
# Configure logging to prepend timestamps, log to stdout, keep 1 archive and rotate on 10MB
|
||||
ENV S6_LOGGING_SCRIPT="T 1 n1 s10000000 T"
|
||||
# Configure logging to prepend timestamps, log to stdout, keep 0 archives and rotate on 10MB
|
||||
ENV S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
|
||||
# TODO: remove after a new version of s6-overlay is released. See:
|
||||
# https://github.com/just-containers/s6-overlay/issues/460#issuecomment-1327127006
|
||||
ENV S6_SERVICES_READYTIME=50
|
||||
|
@ -1142,3 +1142,24 @@ def vainfo():
|
||||
else "",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/logs/<service>", methods=["GET"])
|
||||
def logs(service: str):
|
||||
log_locations = {
|
||||
"frigate": "/dev/shm/logs/frigate/current",
|
||||
"go2rtc": "/dev/shm/logs/go2rtc/current",
|
||||
"nginx": "/dev/shm/logs/nginx/current",
|
||||
}
|
||||
service_location = log_locations.get(service)
|
||||
|
||||
if not service:
|
||||
return f"{service} is not a valid service", 404
|
||||
|
||||
try:
|
||||
file = open(service_location, "r")
|
||||
contents = file.read()
|
||||
file.close()
|
||||
return contents, 200
|
||||
except FileNotFoundError as e:
|
||||
return f"Could not find log file: {e}", 500
|
||||
|
@ -48,6 +48,7 @@ export default function Sidebar() {
|
||||
<Destination href="/storage" text="Storage" />
|
||||
<Destination href="/system" text="System" />
|
||||
<Destination href="/config" text="Config" />
|
||||
<Destination href="/logs" text="Logs" />
|
||||
<Separator />
|
||||
<div className="flex flex-grow" />
|
||||
{ENV !== 'production' ? (
|
||||
|
@ -38,6 +38,7 @@ export default function App() {
|
||||
<AsyncRoute path="/storage" getComponent={Routes.getStorage} />
|
||||
<AsyncRoute path="/system" getComponent={Routes.getSystem} />
|
||||
<AsyncRoute path="/config" getComponent={Routes.getConfig} />
|
||||
<AsyncRoute path="/logs" getComponent={Routes.getLogs} />
|
||||
<AsyncRoute path="/styleguide" getComponent={Routes.getStyleGuide} />
|
||||
<Cameras default path="/" />
|
||||
</Router>
|
||||
|
51
web/src/routes/Logs.jsx
Normal file
51
web/src/routes/Logs.jsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { h } from 'preact';
|
||||
import Heading from '../components/Heading';
|
||||
import { useCallback, useEffect, useState } from 'preact/hooks';
|
||||
import ButtonsTabbed from '../components/ButtonsTabbed';
|
||||
import useSWR from 'swr';
|
||||
import Button from '../components/Button';
|
||||
|
||||
export default function Logs() {
|
||||
const [logService, setLogService] = useState('frigate');
|
||||
const [logs, setLogs] = useState('frigate');
|
||||
|
||||
const { data: frigateLogs } = useSWR('logs/frigate');
|
||||
const { data: go2rtcLogs } = useSWR('logs/go2rtc');
|
||||
const { data: nginxLogs } = useSWR('logs/nginx');
|
||||
|
||||
const handleCopyLogs = useCallback(() => {
|
||||
async function copy() {
|
||||
await window.navigator.clipboard.writeText(logs);
|
||||
}
|
||||
copy();
|
||||
}, [logs]);
|
||||
|
||||
useEffect(() => {
|
||||
switch (logService) {
|
||||
case 'frigate':
|
||||
setLogs(frigateLogs);
|
||||
break;
|
||||
case 'go2rtc':
|
||||
setLogs(go2rtcLogs);
|
||||
break;
|
||||
case 'nginx':
|
||||
setLogs(nginxLogs);
|
||||
break;
|
||||
}
|
||||
}, [frigateLogs, go2rtcLogs, nginxLogs, logService, setLogs]);
|
||||
|
||||
return (
|
||||
<div className="space-y-4 p-2 px-4">
|
||||
<Heading>Logs</Heading>
|
||||
|
||||
<ButtonsTabbed viewModes={['frigate', 'go2rtc', 'nginx']} setViewMode={setLogService} />
|
||||
|
||||
<div className='overflow-auto font-mono text-sm text-gray-900 dark:text-gray-100 rounded bg-gray-100 dark:bg-gray-800 p-2 whitespace-pre-wrap'>
|
||||
{logs}
|
||||
</div>
|
||||
<Button className="" onClick={handleCopyLogs}>
|
||||
Copy to Clipboard
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -43,6 +43,11 @@ export async function getConfig(_url, _cb, _props) {
|
||||
return module.default;
|
||||
}
|
||||
|
||||
export async function getLogs(_url, _cb, _props) {
|
||||
const module = await import('./Logs.jsx');
|
||||
return module.default;
|
||||
}
|
||||
|
||||
export async function getStyleGuide(_url, _cb, _props) {
|
||||
const module = await import('./StyleGuide.jsx');
|
||||
return module.default;
|
||||
|
Loading…
Reference in New Issue
Block a user