diff --git a/src/components/Controls/TRexLogs/index.jsx b/src/components/Controls/TRexLogs/index.jsx index 678cbdf..29e78d3 100644 --- a/src/components/Controls/TRexLogs/index.jsx +++ b/src/components/Controls/TRexLogs/index.jsx @@ -8,6 +8,13 @@ import { TablePagination, TableRow } from "@material-ui/core"; +import LinearProgress from '@mui/material/LinearProgress'; +import Checkbox from '@mui/material/Checkbox'; +import FormGroup from '@mui/material/FormGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import FormLabel from '@mui/material/FormLabel'; + import { KeyboardDatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; @@ -52,6 +59,33 @@ const tableColumns = [ }, ]; +const logLevelCheckBoxes = [ + { + "id": "trace", + "label": "Trace" + }, + { + "id": "debug", + "label": "Debug" + }, + { + "id": "info", + "label": "Info" + }, + { + "id": "warning", + "label": "Warning" + }, + { + "id": "error", + "label": "Error" + }, + { + "id": "critical", + "label": "Critical" + }, +] + const transformLogs = (logs) => logs.map((log) => { const { level, timestamp, received_timestamp, line_number, filename, msg } = log; @@ -75,14 +109,22 @@ const fromatDateForRequest = (date) => { return getYear + "-" + getMonth + "-" + getDay }; -//read at least 30000 bytes per one API request -const ONE_READ_SIZE = 30000 +//read at least 50000 bytes per one API request +const ONE_READ_SIZE = 50000 const DEFAULT_PAGE_SIZE = 25 const TRexLogsTable = ({ vin, token, classes }) => { const [allLogsFetched, setAllLogsFetched] = useState(false) const [blobSize, setBlobSize] = useState(0) const [currentOffset, setCurrentOffset] = useState(0) + const [currectLogLevels, setCurrentLogLevels] = useState({ + trace: true, + debug: true, + info: true, + warning: true, + error: true, + critical: true + }) const [logs, setLogs] = useState([]); const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE); @@ -90,24 +132,25 @@ const TRexLogsTable = ({ vin, token, classes }) => { const [total, setTotal] = useState(0); const { setMessage } = useStatusContext(); + let controller = new AbortController() const readBlob = async (offset, count) => { console.log(`reading from offset: ${offset}`) - return await api.getTRexLogs(vin, fromatDateForRequest(selectedDate), offset, count, "UP", token) + return await api.getTRexLogs(vin, fromatDateForRequest(selectedDate), offset, count, "UP", token, controller) } const getDesiredSize = () => { return pageSize * pageIndex + pageSize } const getReadPercentage = () => { - if (blobSize === 0) { - return `No logs for ${fromatDateForRequest(selectedDate)}` - } - return `Read ${(currentOffset * 100 / blobSize).toFixed(2)}% of logs` + return (currentOffset * 100 / blobSize).toFixed(2); } - const fetchLogs = async (desiredSize) => { + const getFilteredLogs = (logs) => { + return logs.filter(log => currectLogLevels[log.level] === true) + } + const fetchAllLogs = async () => { let fetched = [] let offset = currentOffset let readSize = ONE_READ_SIZE - do { + for (; ;) { const result = await readBlob(offset, readSize) if (result.error) { fetched.error = result.error @@ -115,19 +158,18 @@ const TRexLogsTable = ({ vin, token, classes }) => { } console.log(`ret.RealOffset ${result.RealOffset}\nret.bytesRead ${result.bytesRead}\ndesired offset ${offset}\ndesired read size ${readSize}\nblobsize: ${result.blobSize}`) setBlobSize(result.blobSize) - //if read two times less then neccessary, then adjust read size - if (fetched.length < desiredSize / 2) { - readSize *= 2 - console.log(`new read size: ${readSize}`) - } + readSize *= 2 + console.log(`new read size: ${readSize}`) offset = result.RealOffset + result.bytesRead + setCurrentOffset(offset) fetched = transformLogs(result.data).concat(fetched) + setLogs(fetched) if (offset >= result.blobSize) { setMessage(`All log for ${fromatDateForRequest(selectedDate)} fetched`) setAllLogsFetched(true) break } - } while (fetched.length <= desiredSize) + } if (fetched.length === 0) { if (logs.length !== 0) { @@ -152,25 +194,26 @@ const TRexLogsTable = ({ vin, token, classes }) => { console.log(`desired size: ${desiredSize}, actual size: ${logs.length}`) if (desiredSize < logs.length || allLogsFetched) { console.log(`enough logs in cache`) + setTotal(getFilteredLogs(logs).length) return } - let fetched = await fetchLogs(desiredSize) + let fetched = await fetchAllLogs() if (!fetched || fetched.length === 0) { return } - fetched = fetched.concat(logs) - setLogs(fetched); - setTotal(fetched.length); + setTotal(getFilteredLogs(fetched).length); } catch (e) { setMessage(e.message); logger.warn(e.stack); } })(); + return () => controller?.abort() // eslint-disable-next-line react-hooks/exhaustive-deps - }, [vin, token, pageIndex, pageSize, selectedDate]); + }, [vin, token, pageIndex, pageSize, selectedDate, currectLogLevels]); const handleChangePageSize = (event) => { setPageSize(parseInt(event.target.value, 10)); + setTotal(getFilteredLogs(logs).length) setPageIndex(0); }; @@ -183,12 +226,37 @@ const TRexLogsTable = ({ vin, token, classes }) => { setSelectedDate(newValue) }; + const handleNewFilter = (event) => { + setPageIndex(0) + console.log(event) + setCurrentLogLevels({ + ...currectLogLevels, + [event.target.defaultValue]: event.target.checked, + }); + }; return (
+ + + Log levels + + {logLevelCheckBoxes.map((box) => ( + } + label={box.label} + labelPlacement="bottom" + onChange={handleNewFilter} + /> + ))} + + + + { - {getReadPercentage()} + { + blobSize === 0 ? `No logs for ${fromatDateForRequest(selectedDate)}` : + `Read ${getReadPercentage()}% of logs` + } + { + + }
+ @@ -222,11 +300,11 @@ const TRexLogsTable = ({ vin, token, classes }) => { - {logs.slice(-getDesiredSize(), (pageIndex === 0 ? undefined : -(pageSize * pageIndex))).map((log, i) => ( + {getFilteredLogs(logs).slice(-getDesiredSize(), (pageIndex === 0 ? undefined : -(pageSize * pageIndex))).map((log, i) => ( {log.level} - {log.trex_timestamp} - {log.cloud_timestamp} + {log.trex_timestamp} + {log.cloud_timestamp} {log.line_number} {log.filename} {log.msg} diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index e2c4a11..8d38faa 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -173,13 +173,14 @@ const vehiclesAPI = { .then(fetchRespHandler) .catch(errorHandler), - getTRexLogs: async (vin, date, offset, count, direction, token) => + getTRexLogs: async (vin, date, offset, count, direction, token, controller) => fetch(`${API_ENDPOINT}/vehicle/${vin}/trex-logs?date=${date}&offset=${offset}&count=${count}&direction=${direction}`, { method: "GET", headers: Object.assign( { "Content-Type": "application/json" }, getAuthHeaderOptions(token) ), + signal: controller.signal }) .then(fetchRespHandler) .catch(errorHandler),