import React, { useEffect, useReducer, useState } from "react"; import { Form } from "react-bootstrap"; import * as GQL from "src/core/generated-graphql"; import { StashService } from "src/core/StashService"; function convertTime(logEntry: GQL.LogEntryDataFragment) { function pad(val: number) { let ret = val.toString(); if (val <= 9) { ret = `0${ret}`; } return ret; } const date = new Date(logEntry.time); const month = date.getMonth() + 1; const day = date.getDate(); let dateStr = `${date.getFullYear()}-${pad(month)}-${pad(day)}`; dateStr += ` ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad( date.getSeconds() )}`; return dateStr; } function levelClass(level: string) { return level.toLowerCase().trim(); } interface ILogElementProps { logEntry: LogEntry; } const LogElement: React.FC = ({ logEntry }) => { // pad to maximum length of level enum const level = logEntry.level.padEnd(GQL.LogLevel.Progress.length); return (
{logEntry.time} {level} {logEntry.message}
); }; class LogEntry { public time: string; public level: string; public message: string; public id: string; private static nextId: number = 0; public constructor(logEntry: GQL.LogEntryDataFragment) { this.time = convertTime(logEntry); this.level = logEntry.level; this.message = logEntry.message; const id = LogEntry.nextId++; this.id = id.toString(); } } // maximum number of log entries to display. Subsequent entries will truncate // the list, dropping off the oldest entries first. const MAX_LOG_ENTRIES = 200; const logLevels = ["Debug", "Info", "Warning", "Error"]; const logReducer = (existingEntries:LogEntry[], newEntries:LogEntry[]) => ( [...newEntries.reverse(), ...existingEntries] ); export const SettingsLogsPanel: React.FC = () => { const { data, error } = StashService.useLoggingSubscribe(); const { data: existingData } = StashService.useLogs(); const [currentData, dispatchLogUpdate] = useReducer(logReducer, []); const [logLevel, setLogLevel] = useState("Info"); useEffect(() => { const newData = (data?.loggingSubscribe ?? []).map((e) => new LogEntry(e)); dispatchLogUpdate(newData) }, [data]); const oldData = (existingData?.logs ?? []).map((e) => new LogEntry(e)); const filteredLogEntries = [...currentData, ...oldData] .filter(filterByLogLevel) .slice(0, MAX_LOG_ENTRIES); const maybeRenderError = error ? (
Error connecting to log server: {error.message}
) : ( "" ); function filterByLogLevel(logEntry: LogEntry) { if (logLevel === "Debug") return true; const logLevelIndex = logLevels.indexOf(logLevel); const levelIndex = logLevels.indexOf(logEntry.level); return levelIndex >= logLevelIndex; } return ( <>

Logs

Log Level setLogLevel(event.currentTarget.value)} > {logLevels.map((level) => ( ))}
{maybeRenderError} {filteredLogEntries.map((logEntry) => ( ))}
); };