-
-
-
+
+
系统事件
+
+
diff --git a/web/js/app.js b/web/js/app.js
index 7c41cb5..84b3d0f 100644
--- a/web/js/app.js
+++ b/web/js/app.js
@@ -14,7 +14,7 @@ import {
resetEquipmentForm,
saveEquipment,
} from "./equipment.js";
-import { startLogs, startPointSocket } from "./logs.js";
+import { startPointSocket } from "./logs.js";
import {
clearBatchBinding,
browseAndLoadTree,
@@ -136,7 +136,6 @@ async function bootstrap() {
updateSelectedPointSummary();
updatePointFilterSummary();
renderChart();
- startLogs();
startPointSocket();
await withStatus(loadUnits());
diff --git a/web/js/dom.js b/web/js/dom.js
index 32292de..c55418f 100644
--- a/web/js/dom.js
+++ b/web/js/dom.js
@@ -15,7 +15,6 @@ export const dom = {
pointSourceSelect: byId("pointSourceSelect"),
pointSourceNodeCount: byId("pointSourceNodeCount"),
openPointModalBtn: byId("openPointModal"),
- logView: byId("logView"),
chartCanvas: byId("chartCanvas"),
chartTitle: byId("chartTitle"),
chartSummary: byId("chartSummary"),
diff --git a/web/js/events.js b/web/js/events.js
index e4aa0a4..f796808 100644
--- a/web/js/events.js
+++ b/web/js/events.js
@@ -19,15 +19,8 @@ export function renderEvents() {
state.events.forEach((item) => {
const row = document.createElement("div");
- row.className = "list-item event-card";
- row.innerHTML = `
-
- ${item.event_type}
- ${(item.level || "info").toUpperCase()}
-
-
${item.message}
-
${formatTime(item.created_at)}
- `;
+ row.className = "event-card";
+ row.innerHTML = `
${(item.level || "info").toUpperCase()}${item.event_type}${item.message}${formatTime(item.created_at)}`;
dom.eventList.appendChild(row);
});
}
diff --git a/web/js/logs.js b/web/js/logs.js
index d87f846..f2caeea 100644
--- a/web/js/logs.js
+++ b/web/js/logs.js
@@ -1,73 +1,9 @@
import { appendChartPoint } from "./chart.js";
-import { dom } from "./dom.js";
import { prependEvent } from "./events.js";
import { formatValue } from "./points.js";
import { state } from "./state.js";
import { renderUnits } from "./units.js";
-function escapeHtml(text) {
- return text
- .replaceAll("&", "&")
- .replaceAll("<", "<")
- .replaceAll(">", ">");
-}
-
-function parseLogLine(line) {
- const trimmed = line.trim();
- if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
- return null;
- }
-
- try {
- return JSON.parse(trimmed);
- } catch {
- return null;
- }
-}
-
-export function appendLog(line) {
- const atBottom = dom.logView.scrollTop + dom.logView.clientHeight >= dom.logView.scrollHeight - 10;
- const div = document.createElement("div");
- const parsed = parseLogLine(line);
-
- if (!parsed) {
- div.className = "log-line";
- div.textContent = line;
- } else {
- const levelRaw = (parsed.level || "").toString();
- const level = levelRaw.toLowerCase();
- div.className = `log-line${level ? ` level-${level}` : ""}`;
- div.innerHTML = [
- `
${escapeHtml(levelRaw || "LOG")}`,
- parsed.timestamp ? `
${escapeHtml(parsed.timestamp)}` : "",
- parsed.target ? `
${escapeHtml(parsed.target)}` : "",
- `
${escapeHtml(
- parsed.fields?.message || parsed.message || parsed.msg || line,
- )}`,
- ].join("");
- }
-
- dom.logView.appendChild(div);
- if (atBottom) {
- dom.logView.scrollTop = dom.logView.scrollHeight;
- }
-}
-
-export function startLogs() {
- if (state.logSource) {
- state.logSource.close();
- }
-
- state.logSource = new EventSource("/api/logs/stream");
- state.logSource.addEventListener("log", (event) => {
- const data = JSON.parse(event.data);
- (data.lines || []).forEach(appendLog);
- });
- state.logSource.addEventListener("error", () => {
- appendLog("[log stream error]");
- });
-}
-
export function startPointSocket() {
const protocol = location.protocol === "https:" ? "wss" : "ws";
const ws = new WebSocket(`${protocol}://${location.host}/ws/public`);
diff --git a/web/js/state.js b/web/js/state.js
index 5692ffc..ae317e7 100644
--- a/web/js/state.js
+++ b/web/js/state.js
@@ -18,7 +18,6 @@ export const state = {
chartPointId: null,
chartPointName: "",
chartData: [],
- logSource: null,
pointSocket: null,
apiDocLoaded: false,
runtimes: new Map(), // unit_id -> UnitRuntime
diff --git a/web/styles.css b/web/styles.css
index 62b6583..e6b475f 100644
--- a/web/styles.css
+++ b/web/styles.css
@@ -660,8 +660,7 @@ button.danger:hover { background: var(--danger-hover); }
max-height: 50vh;
}
-.unit-list,
-.event-list {
+.unit-list {
padding-top: 6px;
}
@@ -670,20 +669,32 @@ button.danger:hover { background: var(--danger-hover); }
}
.event-card {
- cursor: default;
+ display: flex;
+ align-items: baseline;
+ gap: 8px;
+ padding: 3px 8px;
+ font-size: 12px;
+ border-bottom: 1px solid var(--border);
+ white-space: nowrap;
}
.event-card:hover {
- background: var(--surface);
- border-color: var(--border);
+ background: var(--surface-hover, var(--surface));
}
-.event-section {
- flex-basis: 42%;
+.event-type {
+ flex-shrink: 0;
}
-.log-section {
- flex-basis: 58%;
+.event-message {
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.event-time {
+ flex-shrink: 0;
+ font-size: 11px;
}
.equipment-select-row {