mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
Add optional limit to the number of log records to return in the log query request to avoid having the web interface instance console download the entire log for only to show a few hundred lines from it. To make it possible to query the end of the log instead of just the start add an order option as well.
97 lines
2.8 KiB
React
97 lines
2.8 KiB
React
import React, { useEffect, useContext, useRef, useState } from "react";
|
|
import { Typography } from "antd";
|
|
|
|
import { libLink } from "@clusterio/lib";
|
|
|
|
import ControlContext from "./ControlContext";
|
|
|
|
const { Paragraph } = Typography;
|
|
|
|
|
|
function formatParsedOutput(parsed, key) {
|
|
let time = "";
|
|
if (parsed.format === "seconds") {
|
|
time = <span className="factorio-time">{parsed.time.padStart(8)} </span>;
|
|
} else if (parsed.format === "date") {
|
|
time = <span className="factorio-time">{parsed.time} </span>;
|
|
}
|
|
|
|
let info = "";
|
|
if (parsed.type === "log") {
|
|
let level = parsed.level;
|
|
if (level === "Script") {
|
|
level = <span className="factorio-script">{level}</span>;
|
|
} else if (level === "Verbose") {
|
|
level = <span className="factorio-verbose">{level}</span>;
|
|
} else if (level === "Info") {
|
|
level = <span className="factorio-info">{level}</span>;
|
|
} else if (parsed.level === "Warning") {
|
|
level = <span className="factorio-warning">{level}</span>;
|
|
} else if (parsed.level === "Error") {
|
|
level = <span className="factorio-error">{level}</span>;
|
|
}
|
|
|
|
info = <>{level} <span className="factorio-filename">{parsed.file}: </span></>;
|
|
|
|
} else if (parsed.type === "action") {
|
|
info = <>[<span className="factorio-action">{parsed.action}</span>] </>;
|
|
}
|
|
|
|
return <span key={key}>{time}{info}{parsed.message}<br/></span>;
|
|
}
|
|
|
|
function formatLog(info, key) {
|
|
if (info.level === "server" && info.parsed) {
|
|
return formatParsedOutput(info.parsed, key);
|
|
}
|
|
let level = <span className={`log-${info.level}`}>{info.level}</span>;
|
|
return <span key={key}>[{level}] {info.message}<br/></span>;
|
|
}
|
|
|
|
export default function InstanceConsole(props) {
|
|
let control = useContext(ControlContext);
|
|
let anchor = useRef();
|
|
let [pastLines, setPastLines] = useState([<span key={0}>{"Loading past entries..."}<br/></span>]);
|
|
let [lines, setLines] = useState([]);
|
|
|
|
useEffect(() => {
|
|
// Scroll view to the anchor so it sticks to the bottom
|
|
let parent = anchor.current.parentElement;
|
|
parent.scrollTop = parent.scrollHeight - parent.clientHeight;
|
|
|
|
libLink.messages.queryLog.send(control, {
|
|
all: false,
|
|
master: false,
|
|
slave_ids: [],
|
|
instance_ids: [props.id],
|
|
max_level: null,
|
|
limit: 400,
|
|
order: "desc",
|
|
}).then(result => {
|
|
setPastLines(result.log.map((info, index) => formatLog(info, index)).reverse());
|
|
}).catch(err => {
|
|
setPastLines([<span key={0}>{`Error loading log: ${err.message}`}<br/></span>]);
|
|
});
|
|
|
|
function logHandler(info) {
|
|
setLines(currentLines => currentLines.concat(
|
|
[formatLog(info, currentLines.length)]
|
|
));
|
|
}
|
|
|
|
control.onInstanceLog(props.id, logHandler);
|
|
return () => {
|
|
control.offInstanceLog(props.id, logHandler);
|
|
};
|
|
}, [props.id]);
|
|
|
|
return <>
|
|
<Paragraph code className="instance-console">
|
|
{pastLines}
|
|
{lines}
|
|
<div className="scroll-anchor" ref={anchor} />
|
|
</Paragraph>
|
|
</>;
|
|
}
|
|
|