mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge pull request #1 from drudge/log-test
feat(logs): improvements to searching
This commit is contained in:
@@ -76,11 +76,18 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
|||||||
if (!containerId) return;
|
if (!containerId) return;
|
||||||
|
|
||||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||||
const wsUrl = `${protocol}//${
|
const params = new globalThis.URLSearchParams({
|
||||||
window.location.host
|
containerId,
|
||||||
}/docker-container-logs?containerId=${containerId}&tail=${lines}&since=${since}&search=${search}${
|
tail: lines.toString(),
|
||||||
serverId ? `&serverId=${serverId}` : ""
|
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);
|
console.log("Connecting to WebSocket:", wsUrl);
|
||||||
const ws = new WebSocket(wsUrl);
|
const ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
@@ -101,8 +108,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
|||||||
console.log("WebSocket closed:", e.reason);
|
console.log("WebSocket closed:", e.reason);
|
||||||
setRawLogs(
|
setRawLogs(
|
||||||
(prev) =>
|
(prev) =>
|
||||||
prev +
|
`${prev}Connection closed!\nReason: ${
|
||||||
`Connection closed!\nReason: ${
|
|
||||||
e.reason || "WebSocket was closed try to refresh"
|
e.reason || "WebSocket was closed try to refresh"
|
||||||
}\n`
|
}\n`
|
||||||
);
|
);
|
||||||
@@ -177,7 +183,7 @@ export const DockerLogsId: React.FC<Props> = ({ containerId, serverId }) => {
|
|||||||
className="inline-flex h-9 text-sm text-white placeholder-gray-400 w-full sm:w-auto"
|
className="inline-flex h-9 text-sm text-white placeholder-gray-400 w-full sm:w-auto"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="search"
|
||||||
placeholder="Search logs..."
|
placeholder="Search logs..."
|
||||||
value={search}
|
value={search}
|
||||||
onChange={handleSearch}
|
onChange={handleSearch}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Badge } from "@/components/ui/badge";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { getLogType, type LogLine } from "./utils";
|
import { getLogType, type LogLine } from "./utils";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { escapeRegExp } from 'lodash';
|
||||||
|
|
||||||
interface LogLineProps {
|
interface LogLineProps {
|
||||||
log: LogLine;
|
log: LogLine;
|
||||||
@@ -27,7 +28,7 @@ export function TerminalLine({ log, searchTerm }: LogLineProps) {
|
|||||||
const highlightMessage = (text: string, term: string) => {
|
const highlightMessage = (text: string, term: string) => {
|
||||||
if (!term) return text;
|
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) =>
|
return parts.map((part, index) =>
|
||||||
part.toLowerCase() === term.toLowerCase() ? (
|
part.toLowerCase() === term.toLowerCase() ? (
|
||||||
<span key={index} className="bg-yellow-200 dark:bg-yellow-900">
|
<span key={index} className="bg-yellow-200 dark:bg-yellow-900">
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
const containerId = url.searchParams.get("containerId");
|
const containerId = url.searchParams.get("containerId");
|
||||||
const tail = url.searchParams.get("tail");
|
const tail = url.searchParams.get("tail");
|
||||||
const search = url.searchParams.get("search");
|
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 serverId = url.searchParams.get("serverId");
|
||||||
const { user, session } = await validateWebSocketRequest(req);
|
const { user, session } = await validateWebSocketRequest(req);
|
||||||
|
|
||||||
@@ -53,9 +53,12 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
const client = new Client();
|
const client = new Client();
|
||||||
client
|
client
|
||||||
.once("ready", () => {
|
.once("ready", () => {
|
||||||
const command = `
|
const baseCommand = `docker container logs --timestamps --tail ${tail} ${
|
||||||
bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'"
|
since === "all" ? "" : `--since ${since}`
|
||||||
`;
|
} --follow ${containerId}`;
|
||||||
|
const command = search
|
||||||
|
? `${baseCommand} 2>&1 | grep -iF '${search}'`
|
||||||
|
: baseCommand;
|
||||||
client.exec(command, (err, stream) => {
|
client.exec(command, (err, stream) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Execution error:", err);
|
console.error("Execution error:", err);
|
||||||
@@ -93,21 +96,20 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const shell = getShell();
|
const shell = getShell();
|
||||||
const ptyProcess = spawn(
|
const baseCommand = `docker container logs --timestamps --tail ${tail} ${
|
||||||
shell,
|
since === "all" ? "" : `--since ${since}`
|
||||||
[
|
} --follow ${containerId}`;
|
||||||
"-c",
|
const command = search
|
||||||
`docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'`,
|
? `${baseCommand} 2>&1 | grep -iF '${search}'`
|
||||||
],
|
: baseCommand;
|
||||||
{
|
const ptyProcess = spawn(shell, ["-c", command], {
|
||||||
name: "xterm-256color",
|
name: "xterm-256color",
|
||||||
cwd: process.env.HOME,
|
cwd: process.env.HOME,
|
||||||
env: process.env,
|
env: process.env,
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
cols: 80,
|
cols: 80,
|
||||||
rows: 30,
|
rows: 30,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
ptyProcess.onData((data) => {
|
ptyProcess.onData((data) => {
|
||||||
ws.send(data);
|
ws.send(data);
|
||||||
|
|||||||
@@ -55,9 +55,12 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
new Promise<void>((resolve, reject) => {
|
new Promise<void>((resolve, reject) => {
|
||||||
client
|
client
|
||||||
.once("ready", () => {
|
.once("ready", () => {
|
||||||
const command = `
|
const baseCommand = `docker container logs --timestamps --tail ${tail} ${
|
||||||
bash -c "docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'"
|
since === "all" ? "" : `--since ${since}`
|
||||||
`;
|
} --follow ${containerId}`;
|
||||||
|
const command = search
|
||||||
|
? `${baseCommand} 2>&1 | grep -iF '${search}'`
|
||||||
|
: baseCommand;
|
||||||
client.exec(command, (err, stream) => {
|
client.exec(command, (err, stream) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Execution error:", err);
|
console.error("Execution error:", err);
|
||||||
@@ -87,21 +90,20 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const shell = getShell();
|
const shell = getShell();
|
||||||
const ptyProcess = spawn(
|
const baseCommand = `docker container logs --timestamps --tail ${tail} ${
|
||||||
shell,
|
since === "all" ? "" : `--since ${since}`
|
||||||
[
|
} --follow ${containerId}`;
|
||||||
"-c",
|
const command = search
|
||||||
`docker container logs --timestamps --tail ${tail} ${since === "all" ? "" : `--since ${since}`} --follow ${containerId} | grep -i '${search}'`,
|
? `${baseCommand} 2>&1 | grep -iF '${search}'`
|
||||||
],
|
: baseCommand;
|
||||||
{
|
const ptyProcess = spawn(shell, ["-c", command], {
|
||||||
name: "xterm-256color",
|
name: "xterm-256color",
|
||||||
cwd: process.env.HOME,
|
cwd: process.env.HOME,
|
||||||
env: process.env,
|
env: process.env,
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
cols: 80,
|
cols: 80,
|
||||||
rows: 30,
|
rows: 30,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
ptyProcess.onData((data) => {
|
ptyProcess.onData((data) => {
|
||||||
ws.send(data);
|
ws.send(data);
|
||||||
|
|||||||
Reference in New Issue
Block a user