mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
122 lines
3.3 KiB
TypeScript
122 lines
3.3 KiB
TypeScript
import React, { useState } from "react";
|
|
import { Form, Col } 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) {
|
|
var ret = val.toString();
|
|
if (val <= 9) {
|
|
ret = "0" + ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
var date = new Date(logEntry.time);
|
|
var month = date.getMonth() + 1;
|
|
var day = date.getDate();
|
|
var 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<ILogElementProps> = ({ logEntry }) => {
|
|
// pad to maximum length of level enum
|
|
var level = logEntry.level.padEnd(GQL.LogLevel.Progress.length);
|
|
|
|
return (
|
|
<>
|
|
<span>{logEntry.time}</span>
|
|
<span className={levelClass(logEntry.level)}>{level}</span>
|
|
<span>{logEntry.message}</span>
|
|
<br/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
var 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"];
|
|
|
|
export const SettingsLogsPanel: React.FC = () => {
|
|
const { data, error } = StashService.useLoggingSubscribe();
|
|
const { data: existingData } = StashService.useLogs();
|
|
const [logLevel, setLogLevel] = useState<string>("Info");
|
|
|
|
const oldData = (existingData?.logs ?? []).map(e => new LogEntry(e));
|
|
const newData = (data?.loggingSubscribe ?? []).map(e => new LogEntry(e));
|
|
|
|
const filteredLogEntries = [...newData.reverse(), ...oldData]
|
|
.filter(filterByLogLevel).slice(0, MAX_LOG_ENTRIES);
|
|
|
|
const maybeRenderError = error
|
|
? <div className={"error"}>Error connecting to log server: {error.message}</div>
|
|
: '';
|
|
|
|
function filterByLogLevel(logEntry : LogEntry) {
|
|
if (logLevel === "Debug")
|
|
return true;
|
|
|
|
var logLevelIndex = logLevels.indexOf(logLevel);
|
|
var levelIndex = logLevels.indexOf(logEntry.level);
|
|
|
|
return levelIndex >= logLevelIndex;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<h4>Logs</h4>
|
|
<Form.Row id="log-level">
|
|
<Col xs={1}>
|
|
<Form.Label>Log Level</Form.Label>
|
|
</Col>
|
|
<Col xs={2}>
|
|
<Form.Control
|
|
as="select"
|
|
defaultValue={logLevel}
|
|
onChange={(event) => setLogLevel(event.currentTarget.value)}
|
|
>
|
|
{ logLevels.map(level => (<option key={level} value={level}>{level}</option>)) }
|
|
</Form.Control>
|
|
</Col>
|
|
</Form.Row>
|
|
<div className="logs">
|
|
{maybeRenderError}
|
|
{filteredLogEntries.map((logEntry) =>
|
|
<LogElement logEntry={logEntry} key={logEntry.id}/>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|