Merge pull request #1 from drudge/log-test

feat(logs): improvements to searching
This commit is contained in:
190km
2024-12-11 16:49:05 +01:00
committed by GitHub
4 changed files with 57 additions and 46 deletions

View File

@@ -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}

View File

@@ -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">

View File

@@ -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);

View File

@@ -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);