From 95cd410825e452f0b4f71928f283098347da366e Mon Sep 17 00:00:00 2001 From: Nicholas Penree Date: Wed, 11 Dec 2024 10:29:09 -0500 Subject: [PATCH 1/2] feat(logs): improvements to searching --- .../dashboard/docker/logs/docker-logs-id.tsx | 22 ++++++++++++------- .../dashboard/docker/logs/terminal-line.tsx | 3 ++- .../server/wss/docker-container-logs.ts | 19 +++++++++++----- .../server/src/wss/docker-container-logs.ts | 4 ++-- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/apps/dokploy/components/dashboard/docker/logs/docker-logs-id.tsx b/apps/dokploy/components/dashboard/docker/logs/docker-logs-id.tsx index e9459849..7c0edf05 100644 --- a/apps/dokploy/components/dashboard/docker/logs/docker-logs-id.tsx +++ b/apps/dokploy/components/dashboard/docker/logs/docker-logs-id.tsx @@ -76,11 +76,18 @@ export const DockerLogsId: React.FC = ({ containerId, serverId }) => { if (!containerId) return; const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; - const wsUrl = `${protocol}//${ - window.location.host - }/docker-container-logs?containerId=${containerId}&tail=${lines}&since=${since}&search=${search}${ - serverId ? `&serverId=${serverId}` : "" - }`; + const params = new globalThis.URLSearchParams({ + containerId, + tail: lines.toString(), + since, + search + }); + + if (serverId) { + params.append('serverId', serverId); + } + + const wsUrl = `${protocol}//${window.location.host}/docker-container-logs?${params.toString()}`; console.log("Connecting to WebSocket:", wsUrl); const ws = new WebSocket(wsUrl); @@ -101,8 +108,7 @@ export const DockerLogsId: React.FC = ({ containerId, serverId }) => { console.log("WebSocket closed:", e.reason); setRawLogs( (prev) => - prev + - `Connection closed!\nReason: ${ + `${prev}Connection closed!\nReason: ${ e.reason || "WebSocket was closed try to refresh" }\n` ); @@ -177,7 +183,7 @@ export const DockerLogsId: React.FC = ({ containerId, serverId }) => { className="inline-flex h-9 text-sm text-white placeholder-gray-400 w-full sm:w-auto" /> { if (!term) return text; - const parts = text.split(new RegExp(`(${term})`, "gi")); + const parts = text.split(new RegExp(`(${escapeRegExp(term)})`, "gi")); return parts.map((part, index) => part.toLowerCase() === term.toLowerCase() ? ( diff --git a/apps/dokploy/server/wss/docker-container-logs.ts b/apps/dokploy/server/wss/docker-container-logs.ts index 882b2b4e..4630d8fe 100644 --- a/apps/dokploy/server/wss/docker-container-logs.ts +++ b/apps/dokploy/server/wss/docker-container-logs.ts @@ -32,7 +32,7 @@ export const setupDockerContainerLogsWebSocketServer = ( const containerId = url.searchParams.get("containerId"); const tail = url.searchParams.get("tail"); const search = url.searchParams.get("search"); - const since = url.searchParams.get("since") + const since = url.searchParams.get("since"); const serverId = url.searchParams.get("serverId"); const { user, session } = await validateWebSocketRequest(req); @@ -53,9 +53,12 @@ export const setupDockerContainerLogsWebSocketServer = ( const client = new Client(); client .once("ready", () => { - const command = ` - bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'" - `; + const baseCommand = `docker container logs --timestamps --tail ${tail} ${ + since === "all" ? "" : `--since ${since}` + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; client.exec(command, (err, stream) => { if (err) { console.error("Execution error:", err); @@ -93,11 +96,17 @@ export const setupDockerContainerLogsWebSocketServer = ( }); } else { const shell = getShell(); + const baseCommand = `docker container logs --timestamps --tail ${tail} ${ + since === "all" ? "" : `--since ${since}` + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; const ptyProcess = spawn( shell, [ "-c", - `docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'`, + command, ], { name: "xterm-256color", diff --git a/packages/server/src/wss/docker-container-logs.ts b/packages/server/src/wss/docker-container-logs.ts index ab3234b7..db9ce90b 100644 --- a/packages/server/src/wss/docker-container-logs.ts +++ b/packages/server/src/wss/docker-container-logs.ts @@ -56,7 +56,7 @@ export const setupDockerContainerLogsWebSocketServer = ( client .once("ready", () => { const command = ` - bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'" + bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -iF '${search}'" `; client.exec(command, (err, stream) => { if (err) { @@ -91,7 +91,7 @@ export const setupDockerContainerLogsWebSocketServer = ( shell, [ "-c", - `docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'`, + `docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -iF '${search}'`, ], { name: "xterm-256color", From 7233667d496379f8730cdd52110e5a6e57855a7c Mon Sep 17 00:00:00 2001 From: Nicholas Penree Date: Wed, 11 Dec 2024 10:35:12 -0500 Subject: [PATCH 2/2] feat(logs): improvements to searching --- .../server/wss/docker-container-logs.ts | 39 ++++++++----------- .../server/src/wss/docker-container-logs.ts | 38 +++++++++--------- 2 files changed, 36 insertions(+), 41 deletions(-) diff --git a/apps/dokploy/server/wss/docker-container-logs.ts b/apps/dokploy/server/wss/docker-container-logs.ts index 4630d8fe..1b28c11b 100644 --- a/apps/dokploy/server/wss/docker-container-logs.ts +++ b/apps/dokploy/server/wss/docker-container-logs.ts @@ -55,10 +55,10 @@ export const setupDockerContainerLogsWebSocketServer = ( .once("ready", () => { const baseCommand = `docker container logs --timestamps --tail ${tail} ${ since === "all" ? "" : `--since ${since}` - } --follow ${containerId}`; - const command = search - ? `${baseCommand} 2>&1 | grep -iF '${search}'` - : baseCommand; + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; client.exec(command, (err, stream) => { if (err) { console.error("Execution error:", err); @@ -98,25 +98,18 @@ export const setupDockerContainerLogsWebSocketServer = ( const shell = getShell(); const baseCommand = `docker container logs --timestamps --tail ${tail} ${ since === "all" ? "" : `--since ${since}` - } --follow ${containerId}`; - const command = search - ? `${baseCommand} 2>&1 | grep -iF '${search}'` - : baseCommand; - const ptyProcess = spawn( - shell, - [ - "-c", - command, - ], - { - name: "xterm-256color", - cwd: process.env.HOME, - env: process.env, - encoding: "utf8", - cols: 80, - rows: 30, - }, - ); + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; + const ptyProcess = spawn(shell, ["-c", command], { + name: "xterm-256color", + cwd: process.env.HOME, + env: process.env, + encoding: "utf8", + cols: 80, + rows: 30, + }); ptyProcess.onData((data) => { ws.send(data); diff --git a/packages/server/src/wss/docker-container-logs.ts b/packages/server/src/wss/docker-container-logs.ts index db9ce90b..7cfdb8d6 100644 --- a/packages/server/src/wss/docker-container-logs.ts +++ b/packages/server/src/wss/docker-container-logs.ts @@ -55,9 +55,12 @@ export const setupDockerContainerLogsWebSocketServer = ( new Promise((resolve, reject) => { client .once("ready", () => { - const command = ` - bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -iF '${search}'" - `; + const baseCommand = `docker container logs --timestamps --tail ${tail} ${ + since === "all" ? "" : `--since ${since}` + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; client.exec(command, (err, stream) => { if (err) { console.error("Execution error:", err); @@ -87,21 +90,20 @@ export const setupDockerContainerLogsWebSocketServer = ( }); } else { const shell = getShell(); - const ptyProcess = spawn( - shell, - [ - "-c", - `docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -iF '${search}'`, - ], - { - name: "xterm-256color", - cwd: process.env.HOME, - env: process.env, - encoding: "utf8", - cols: 80, - rows: 30, - }, - ); + const baseCommand = `docker container logs --timestamps --tail ${tail} ${ + since === "all" ? "" : `--since ${since}` + } --follow ${containerId}`; + const command = search + ? `${baseCommand} 2>&1 | grep -iF '${search}'` + : baseCommand; + const ptyProcess = spawn(shell, ["-c", command], { + name: "xterm-256color", + cwd: process.env.HOME, + env: process.env, + encoding: "utf8", + cols: 80, + rows: 30, + }); ptyProcess.onData((data) => { ws.send(data);