release: r018 focused log analysis
This commit is contained in:
1 parent
02deec8dc9
commit
47c27b06c4
7 files changed
+48
-13
No files matched your search
@@ -76,10 +76,10 @@ Oder manuell:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# .txz von Gitea laden
|
# .txz von Gitea laden
|
||||||
curl -O http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r017-x86_64-1.txz
|
curl -O http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r018-x86_64-1.txz
|
||||||
|
|
||||||
# Installieren
|
# Installieren
|
||||||
upgradepkg --install-new mua-2026.08.24.r017-x86_64-1.txz
|
upgradepkg --install-new mua-2026.08.24.r018-x86_64-1.txz
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Service starten
|
### 2. Service starten
|
||||||
@@ -94,7 +94,7 @@ Der Service startet automatisch bei jedem Boot (SysVinit).
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://192.168.1.2:3002/health
|
curl http://192.168.1.2:3002/health
|
||||||
# → {"status":"ok","version":"2026.08.24.r017","auth":"required"}
|
# → {"status":"ok","version":"2026.08.24.r018","auth":"required"}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
BIN
Binary file not shown.
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mua",
|
"name": "mua",
|
||||||
"version": "2026.08.24.r017",
|
"version": "2026.08.24.r018",
|
||||||
"description": "Mikes Unraid Agent - MCP over HTTP (Streamable HTTP) for Unraid",
|
"description": "Mikes Unraid Agent - MCP over HTTP (Streamable HTTP) for Unraid",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"build": "bun build ./src/index.ts --compile --target=bun-linux-x64 --outfile dist/mua",
|
"build": "bun build ./src/index.ts --compile --target=bun-linux-x64 --outfile dist/mua",
|
||||||
"build:mac": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/mua-mac",
|
"build:mac": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/mua-mac",
|
||||||
"start": "bun run src/index.ts",
|
"start": "bun run src/index.ts",
|
||||||
"selftest": "bun run src/selftest.ts"
|
"selftest": "bun test src/security.test.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
|
|||||||
+8
-4
@@ -2,13 +2,13 @@
|
|||||||
<!DOCTYPE PLUGIN [
|
<!DOCTYPE PLUGIN [
|
||||||
<!ENTITY name "mua">
|
<!ENTITY name "mua">
|
||||||
<!ENTITY author "Michael">
|
<!ENTITY author "Michael">
|
||||||
<!ENTITY version "2026.08.24.r017">
|
<!ENTITY version "2026.08.24.r018">
|
||||||
<!ENTITY launch "Settings/mua">
|
<!ENTITY launch "Settings/mua">
|
||||||
<!ENTITY pluginURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/plugin/mua.plg">
|
<!ENTITY pluginURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/plugin/mua.plg">
|
||||||
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
|
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
|
||||||
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
|
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
|
||||||
<!ENTITY txzURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r017-x86_64-1.txz">
|
<!ENTITY txzURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r018-x86_64-1.txz">
|
||||||
<!ENTITY txzSHA256 "dd95d28fdcc875ff6d1f8ae317735b724b6d192dd23e7dfd3d866fd07395c7f8">
|
<!ENTITY txzSHA256 "174603af715b3f875a875563b6a67045c6af6b8166b6943780712d8074bc2071">
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<PLUGIN name="&name;"
|
<PLUGIN name="&name;"
|
||||||
@@ -23,6 +23,10 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<CHANGES>
|
<CHANGES>
|
||||||
|
### 2026.08.24.r018
|
||||||
|
- Added focused, batched container-log analysis via `focus_terms` to avoid repeated shell/grep loops.
|
||||||
|
- Repaired the repository self-test command.
|
||||||
|
|
||||||
### 2026.08.24.r017
|
### 2026.08.24.r017
|
||||||
- Community-Applications-Suche akzeptiert bis zu fünf mit `|` getrennte Namens-, Schreib- oder Zweckvarianten in einem einzigen begrenzten Feed-Durchlauf.
|
- Community-Applications-Suche akzeptiert bis zu fünf mit `|` getrennte Namens-, Schreib- oder Zweckvarianten in einem einzigen begrenzten Feed-Durchlauf.
|
||||||
- Treffer nennen die tatsächlich passenden Varianten; kleine Agenten müssen Synonyme nicht mehr in einzelnen Werkzeugrunden abfragen.
|
- Treffer nennen die tatsächlich passenden Varianten; kleine Agenten müssen Synonyme nicht mehr in einzelnen Werkzeugrunden abfragen.
|
||||||
@@ -122,7 +126,7 @@ Das .txz enthält:
|
|||||||
install/doinst.sh (läuft nach Installation)
|
install/doinst.sh (läuft nach Installation)
|
||||||
===========================================
|
===========================================
|
||||||
-->
|
-->
|
||||||
<FILE Name="/boot/config/plugins/&name;/mua-2026.08.24.r017-x86_64-1.txz" Run="upgradepkg --install-new" Mode="755" Min="7.0.0">
|
<FILE Name="/boot/config/plugins/&name;/mua-2026.08.24.r018-x86_64-1.txz" Run="upgradepkg --install-new" Mode="755" Min="7.0.0">
|
||||||
<URL>&txzURL;</URL>
|
<URL>&txzURL;</URL>
|
||||||
<SHA256>&txzSHA256;</SHA256>
|
<SHA256>&txzSHA256;</SHA256>
|
||||||
</FILE>
|
</FILE>
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mua",
|
"name": "mua",
|
||||||
"author": "Michael",
|
"author": "Michael",
|
||||||
"version": "2026.08.24.r017",
|
"version": "2026.08.24.r018",
|
||||||
"minver": "7.0.0",
|
"minver": "7.0.0",
|
||||||
"pluginDirectory": "/usr/local/emhttp/plugins/mua",
|
"pluginDirectory": "/usr/local/emhttp/plugins/mua",
|
||||||
"configDirectory": "/boot/config/plugins/mua",
|
"configDirectory": "/boot/config/plugins/mua",
|
||||||
|
|||||||
+13
-1
@@ -14,7 +14,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|||||||
|
|
||||||
// ── Konstanten ──────────────────────────────────────────────────────────
|
// ── Konstanten ──────────────────────────────────────────────────────────
|
||||||
export const MUA_SERVER_NAME = "mua";
|
export const MUA_SERVER_NAME = "mua";
|
||||||
export const MUA_VERSION = "2026.08.24.r017";
|
export const MUA_VERSION = "2026.08.24.r018";
|
||||||
export const MUA_PROTOCOL_VERSION = "2025-03-26";
|
export const MUA_PROTOCOL_VERSION = "2025-03-26";
|
||||||
export const PHP_HELPER = "/usr/local/bin/unraid-docker-mcp-helper.php";
|
export const PHP_HELPER = "/usr/local/bin/unraid-docker-mcp-helper.php";
|
||||||
export const STATUS_HELPER = "/usr/local/bin/unraid-mcp-status-helper.php";
|
export const STATUS_HELPER = "/usr/local/bin/unraid-mcp-status-helper.php";
|
||||||
@@ -545,6 +545,7 @@ export async function analyzeContainerLogs(
|
|||||||
since: string,
|
since: string,
|
||||||
scanTail: number,
|
scanTail: number,
|
||||||
maxResults: number,
|
maxResults: number,
|
||||||
|
focusTerms: string[] = [],
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const severityLevels: Record<string, string[]> = {
|
const severityLevels: Record<string, string[]> = {
|
||||||
error: ["error", "fatal", "panic", "exception", "traceback", "critical"],
|
error: ["error", "fatal", "panic", "exception", "traceback", "critical"],
|
||||||
@@ -553,6 +554,10 @@ export async function analyzeContainerLogs(
|
|||||||
};
|
};
|
||||||
const patterns = severityLevels[severity] ?? severityLevels["error"];
|
const patterns = severityLevels[severity] ?? severityLevels["error"];
|
||||||
const regex = new RegExp(`(${patterns.join("|")})`, "i");
|
const regex = new RegExp(`(${patterns.join("|")})`, "i");
|
||||||
|
const normalisedFocusTerms = focusTerms
|
||||||
|
.map((term) => term.trim().toLowerCase())
|
||||||
|
.filter((term) => term.length > 0)
|
||||||
|
.slice(0, 12);
|
||||||
|
|
||||||
// Ziel-Container: einzelner Container oder alle laufenden
|
// Ziel-Container: einzelner Container oder alle laufenden
|
||||||
let targets: string[];
|
let targets: string[];
|
||||||
@@ -575,6 +580,12 @@ export async function analyzeContainerLogs(
|
|||||||
const raw = await dockerExec(logCmd, 120);
|
const raw = await dockerExec(logCmd, 120);
|
||||||
let containerMatches = 0;
|
let containerMatches = 0;
|
||||||
for (const line of raw.split("\n")) {
|
for (const line of raw.split("\n")) {
|
||||||
|
if (
|
||||||
|
normalisedFocusTerms.length > 0
|
||||||
|
&& !normalisedFocusTerms.some((term) => line.toLowerCase().includes(term))
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const m = line.match(regex);
|
const m = line.match(regex);
|
||||||
if (m) {
|
if (m) {
|
||||||
const key = m[1].toLowerCase();
|
const key = m[1].toLowerCase();
|
||||||
@@ -594,6 +605,7 @@ export async function analyzeContainerLogs(
|
|||||||
container,
|
container,
|
||||||
since,
|
since,
|
||||||
scan_tail: scanTail,
|
scan_tail: scanTail,
|
||||||
|
focus_terms: normalisedFocusTerms,
|
||||||
total_matches: Object.values(counts).reduce((a, b) => a + b, 0),
|
total_matches: Object.values(counts).reduce((a, b) => a + b, 0),
|
||||||
pattern_counts: counts,
|
pattern_counts: counts,
|
||||||
containers_with_matches: containersWithMatches,
|
containers_with_matches: containersWithMatches,
|
||||||
|
|||||||
+21
-2
@@ -131,7 +131,7 @@ export const TOOLS: ToolDef[] = [
|
|||||||
{
|
{
|
||||||
name: "unraid_docker_analyze_logs",
|
name: "unraid_docker_analyze_logs",
|
||||||
description:
|
description:
|
||||||
"Analyze container logs server-side for errors/warnings. Returns pattern counts and sample matches.",
|
"Analyze container logs server-side for errors/warnings in one bounded call. Use optional focus_terms to restrict results to components such as hass_mcp, yaml or zigbee instead of issuing multiple grep/shell calls. Returns pattern counts and sample matches.",
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
@@ -144,6 +144,13 @@ export const TOOLS: ToolDef[] = [
|
|||||||
since: str("Time filter (default 24h)"),
|
since: str("Time filter (default 24h)"),
|
||||||
scan_tail: int("Max lines to scan (default 1000)"),
|
scan_tail: int("Max lines to scan (default 1000)"),
|
||||||
max_results: int("Max sample matches (default 50)"),
|
max_results: int("Max sample matches (default 50)"),
|
||||||
|
focus_terms: {
|
||||||
|
type: "array",
|
||||||
|
items: { type: "string", minLength: 1, maxLength: 80 },
|
||||||
|
maxItems: 12,
|
||||||
|
description:
|
||||||
|
"Optional literal component/topic terms. A log line must contain at least one term, case-insensitively. Bundle related terms in one call.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: ["severity"],
|
required: ["severity"],
|
||||||
},
|
},
|
||||||
@@ -156,7 +163,19 @@ export const TOOLS: ToolDef[] = [
|
|||||||
const since = (a["since"] as string) ?? "24h";
|
const since = (a["since"] as string) ?? "24h";
|
||||||
const scanTail = Number(a["scan_tail"] ?? 1000);
|
const scanTail = Number(a["scan_tail"] ?? 1000);
|
||||||
const maxResults = Number(a["max_results"] ?? 50);
|
const maxResults = Number(a["max_results"] ?? 50);
|
||||||
return analyzeContainerLogs(severity, container ?? null, since, scanTail, maxResults);
|
const focusTerms = Array.isArray(a["focus_terms"])
|
||||||
|
? (a["focus_terms"] as unknown[]).filter(
|
||||||
|
(item): item is string => typeof item === "string",
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
return analyzeContainerLogs(
|
||||||
|
severity,
|
||||||
|
container ?? null,
|
||||||
|
since,
|
||||||
|
scanTail,
|
||||||
|
maxResults,
|
||||||
|
focusTerms,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user