From 2830cbc267c54504c9adf7260972f06bcd19b000 Mon Sep 17 00:00:00 2001 From: James Summers Date: Thu, 7 Mar 2024 15:28:49 +0100 Subject: [PATCH 1/4] add filters --- package-lock.json | 4 +-- package.json | 2 +- public/app.jsx | 92 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb05d5c..0897c8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "logscreen", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "logscreen", - "version": "0.0.3", + "version": "0.0.4", "license": "ISC", "dependencies": { "express": "^4.18.2", diff --git a/package.json b/package.json index 81cadd4..0579b57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "logscreen", - "version": "0.0.4", + "version": "0.0.5", "description": "", "main": "index.js", "scripts": { diff --git a/public/app.jsx b/public/app.jsx index 951969e..87bbaeb 100644 --- a/public/app.jsx +++ b/public/app.jsx @@ -76,7 +76,7 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => {
-                {truncateMessage(log.message)}
+                {parseLogToJSX(truncateMessage(log.message))}
               
@@ -107,7 +107,8 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => {
-              {JSON.stringify(selectedLog.message, null, 2)}
+              {parseLogToJSX(JSON.stringify(selectedLog.message, null, 2))}
+              {/* {JSON.stringify(selectedLog.message, null, 2)} */}
             
@@ -116,9 +117,49 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => { ); }; +function parseLogToJSX(log) { + // Regular expression to match ANSI escape codes + const ansiRegex = /\u001b\[\d+m/g; + + // Remove ANSI escape codes from the log string + const cleanedLog = log.replace(ansiRegex, ''); + + // Continue with your existing parsing logic + const regex = /(\w+): (.*)/; + const match = cleanedLog.match(regex); + + if (!match) { + // If the cleaned log does not match the expected format, return it as plain text + return {cleanedLog}; + } + + const [level, message] = match.slice(1); // Adjusted to match the new regex groups + + // Convert level to a CSS color + const color = (() => { + switch (level.toLowerCase()) { // Ensure case-insensitive matching + case 'info': return 'green'; + case 'error': return 'red'; + case 'warning': return 'orange'; + default: return 'black'; + } + })(); + + // Return a JSX element with the styled log message + return ( + + {level}: {message} + + ); +} + + function App() { const [logs, setLogs] = useState([]); + const [logLevels, setLogLevels] = useState(new Set(['unknown'])); + const [selectedLevel, setSelectedLevel] = useState(''); const [searchTerm, setSearchTerm] = useState(""); + const [startDateTime, setStartDateTime] = useState(''); useEffect(() => { const socket = io(); @@ -127,19 +168,28 @@ function App() { const [timestamp, ...loglineParts] = data.split(" :: "); const logline = loglineParts.join(" :: "); + const regex = /(\w+):/; // Regular expression to match the log level + const match = logline.match(regex); + + let level = 'unknown'; // Default log level + if (match) { + level = match[1].toLowerCase(); // Extract log level + } + setLogs((prevLogs) => [ ...prevLogs, - { key: uuidv4(), timestamp, message: logline }, + { key: uuidv4(), timestamp, message: logline, level }, ]); + + setLogLevels(prevLevels => new Set([...prevLevels, level])); } socket.on("input", parseAndRenderLog); return () => { - // Clean up the socket connection on component unmount socket.off("input", parseAndRenderLog); }; - }, []); // Empty dependency array ensures the effect runs once on mount + }, []); return (
@@ -172,9 +222,37 @@ function App() { onChange={(e) => setSearchTerm(e.target.value)} className="p-2 border border-gray-300 text-gray-800 bg-white rounded w-1/4" /> +
+ +
+
+ setStartDateTime(e.target.value)} + className="p-2 border border-gray-300 text-gray-800 bg-white rounded" + /> +
+
+ { + const logDateTime = new Date(log.timestamp); + const filterDateTime = startDateTime ? new Date(startDateTime) : null; + return ( + (selectedLevel === '' || log.level === selectedLevel) && + (searchTerm === '' || log.message.toLowerCase().includes(searchTerm.toLowerCase())) && + (!filterDateTime || logDateTime >= filterDateTime) + ); + })} searchTerm={searchTerm} /> - - ); } From 65524bfab67a0030748ba0a844333ae77470c676 Mon Sep 17 00:00:00 2001 From: James Summers Date: Tue, 12 Mar 2024 13:22:11 +0100 Subject: [PATCH 2/4] memo and log level fixes --- public/app.jsx | 81 ++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/public/app.jsx b/public/app.jsx index 87bbaeb..42465e0 100644 --- a/public/app.jsx +++ b/public/app.jsx @@ -76,7 +76,7 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => {
-                {parseLogToJSX(truncateMessage(log.message))}
+                
               
@@ -107,7 +107,7 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => {
-              {parseLogToJSX(JSON.stringify(selectedLog.message, null, 2))}
+              
               {/* {JSON.stringify(selectedLog.message, null, 2)} */}
             
@@ -117,42 +117,35 @@ const LogViewer = ({ logs: rawLogs, searchTerm }) => { ); }; -function parseLogToJSX(log) { - // Regular expression to match ANSI escape codes - const ansiRegex = /\u001b\[\d+m/g; +const ParsedLog = ({ log }) => { + const parsedLog = useMemo(() => { + const ansiRegex = /\u001b\[\d+m/g; + const cleanedLog = log.replace(ansiRegex, ''); - // Remove ANSI escape codes from the log string - const cleanedLog = log.replace(ansiRegex, ''); + const regex = /(\w+): (.*)/; + const match = cleanedLog.match(regex); - // Continue with your existing parsing logic - const regex = /(\w+): (.*)/; - const match = cleanedLog.match(regex); - - if (!match) { - // If the cleaned log does not match the expected format, return it as plain text - return {cleanedLog}; - } + if (!match) { + return {cleanedLog}; + } - const [level, message] = match.slice(1); // Adjusted to match the new regex groups + const [_, level, message] = match; - // Convert level to a CSS color - const color = (() => { - switch (level.toLowerCase()) { // Ensure case-insensitive matching - case 'info': return 'green'; - case 'error': return 'red'; - case 'warning': return 'orange'; - default: return 'black'; - } - })(); + const color = { + info: 'green', + error: 'red', + warning: 'orange', + }[level.toLowerCase()] || 'black'; - // Return a JSX element with the styled log message - return ( - - {level}: {message} - - ); -} + return ( + + {level}: {message} + + ); + }, [log]); + return parsedLog; +}; function App() { const [logs, setLogs] = useState([]); @@ -168,7 +161,7 @@ function App() { const [timestamp, ...loglineParts] = data.split(" :: "); const logline = loglineParts.join(" :: "); - const regex = /(\w+):/; // Regular expression to match the log level + const regex = /\b(Error|Warning|Info|Critical|Debug):|\b(::)/i; const match = logline.match(regex); let level = 'unknown'; // Default log level @@ -191,6 +184,18 @@ function App() { }; }, []); + const filteredLogs = useMemo(() => { + return logs.filter(log => { + const logDateTime = new Date(log.timestamp); + const filterDateTime = startDateTime ? new Date(startDateTime) : null; + return ( + (selectedLevel === '' || log.level === selectedLevel) && + (searchTerm === '' || log.message.toLowerCase().includes(searchTerm.toLowerCase())) && + (!filterDateTime || logDateTime >= filterDateTime) + ); + }); + }, [logs, selectedLevel, searchTerm, startDateTime]); + return (
@@ -243,15 +248,7 @@ function App() { />
- { - const logDateTime = new Date(log.timestamp); - const filterDateTime = startDateTime ? new Date(startDateTime) : null; - return ( - (selectedLevel === '' || log.level === selectedLevel) && - (searchTerm === '' || log.message.toLowerCase().includes(searchTerm.toLowerCase())) && - (!filterDateTime || logDateTime >= filterDateTime) - ); - })} searchTerm={searchTerm} /> + ); } From fb85006b20c56ae4497e7e5b0df2ff1e29dd4cbf Mon Sep 17 00:00:00 2001 From: James Summers Date: Tue, 12 Mar 2024 13:35:37 +0100 Subject: [PATCH 3/4] fix log level --- public/app.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app.jsx b/public/app.jsx index 42465e0..143c67c 100644 --- a/public/app.jsx +++ b/public/app.jsx @@ -161,7 +161,7 @@ function App() { const [timestamp, ...loglineParts] = data.split(" :: "); const logline = loglineParts.join(" :: "); - const regex = /\b(Error|Warning|Info|Critical|Debug):|\b(::)/i; + const regex = /\b(Error|Warning|Info|Critical|Debug)\s*::?\s*/i; const match = logline.match(regex); let level = 'unknown'; // Default log level From 70ebe0f849a23413e0d854866c9050d4a3082db3 Mon Sep 17 00:00:00 2001 From: James Summers Date: Tue, 12 Mar 2024 13:35:59 +0100 Subject: [PATCH 4/4] trim log level --- public/app.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app.jsx b/public/app.jsx index 143c67c..ffcb017 100644 --- a/public/app.jsx +++ b/public/app.jsx @@ -166,7 +166,7 @@ function App() { let level = 'unknown'; // Default log level if (match) { - level = match[1].toLowerCase(); // Extract log level + level = match[1].trim().toLowerCase(); // Extract log level } setLogs((prevLogs) => [