From 6165167f1b745e01fdc435d477b8fbaa07275aa2 Mon Sep 17 00:00:00 2001 From: Aadarsh Nagrath <92307537+aadarsh-nagrath@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:25:17 +0530 Subject: [PATCH] enhancements for system logs UI 1> Color Coding by Log Level [INFO] (green) [ERROR] (red) [WARNING] (yellow) 2> Highlighted Key Actions GET, POST, PUT requests could be bolded or highlighted to stand out. 3> Interactive UI with Filtering If the logs are displayed in a UI, add interactive filters to show/hide specific log levels (e.g., only errors, warnings). 4> Search Functionality: Allow searching by timestamp, HTTP status codes, or keywords. --- web-server/src/content/Service/SystemLogs.tsx | 105 +++++++++++++++--- 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/web-server/src/content/Service/SystemLogs.tsx b/web-server/src/content/Service/SystemLogs.tsx index c098b7ebb..2ed136246 100644 --- a/web-server/src/content/Service/SystemLogs.tsx +++ b/web-server/src/content/Service/SystemLogs.tsx @@ -1,19 +1,24 @@ import CircularProgress from '@mui/material/CircularProgress'; -import { useEffect, useRef, useMemo } from 'react'; - +import { useEffect, useRef, useMemo, useState } from 'react'; import { FlexBox } from '@/components/FlexBox'; import { Line } from '@/components/Text'; import { ServiceNames } from '@/constants/service'; import { useSelector } from '@/store'; +import { TextField, MenuItem } from '@mui/material'; export const SystemLogs = ({ serviceName }: { serviceName: ServiceNames }) => { const services = useSelector((state) => state.service.services); const loading = useSelector((state) => state.service.loading); - const logs = useMemo(() => { - return services[serviceName].logs || []; - }, [serviceName, services]); + const logs = useMemo(() => services[serviceName].logs || [], [serviceName, services]); const containerRef = useRef(null); + const [filter, setFilter] = useState({ + info: true, + error: true, + warning: true, + }); + const [searchTerm, setSearchTerm] = useState(''); + const [selectedLevel, setSelectedLevel] = useState('all'); useEffect(() => { if (containerRef.current) { @@ -21,6 +26,46 @@ export const SystemLogs = ({ serviceName }: { serviceName: ServiceNames }) => { } }, [logs]); + const getStyledLog = (log: string) => { + const level = log.match(/\[(INFO|ERROR|WARNING|LOG)\]/); + const logLevel = level ? level[0] : ''; + let logLevelColor = 'white'; + + if (logLevel.includes('ERROR')) logLevelColor = '#ed131e'; + if (logLevel.includes('WARNING')) logLevelColor = '#eded13'; + if (logLevel.includes('INFO')) logLevelColor = '#13ed3b'; + + const restOfLog = log.replace(logLevel, ''); + return `${logLevel}${restOfLog}`; + }; + + // Highlight HTTP methods, timestamps, and searched keywords + const highlightKeywords = (log: string) => { + const highlightedLog = searchTerm + ? log.replace( + new RegExp(searchTerm, 'gi'), + (match) => `${match}` + ) + : log; + + return highlightedLog + .replace(/\b(GET|POST|PUT|DELETE|LOG)\b/g, '$1') + .replace( + /(\d{2}\/[A-Za-z]+\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})|(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}(?: UTC)?(?: \[\d+\])?)|(\d{2}:\w{1} \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2}\.\d{3})/g, + '$1$2$3' + ); + }; + + // Filter logs + const filteredLogs = logs.filter((log) => { + if (selectedLevel !== 'all' && !log.includes(`[${selectedLevel.toUpperCase()}]`)) return false; + if (searchTerm && !log.toLowerCase().includes(searchTerm.toLowerCase())) return false; + if (log.includes('[INFO]') && !filter.info) return false; + if (log.includes('[ERROR]') && !filter.error) return false; + if (log.includes('[WARNING]') && !filter.warning) return false; + return true; + }); + return ( {loading ? ( @@ -29,19 +74,45 @@ export const SystemLogs = ({ serviceName }: { serviceName: ServiceNames }) => { Loading... ) : ( - services && - logs.map((log, index) => ( - - {log} - - )) + services && ( + <> + + setSearchTerm(e.target.value)} + style={{ marginRight: '16px', flex: 1 }} + /> + setSelectedLevel(e.target.value)} + style={{ marginRight: '16px' }} + > + ALL + INFO + ERROR + WARNING + + + + {/* Display Logs */} + {filteredLogs.map((log, index) => ( + + ))} + + + + ) )} - ); };