Skip to content

Commit

Permalink
Export Logs draft
Browse files Browse the repository at this point in the history
  • Loading branch information
Henry8192 committed Sep 15, 2024
1 parent cfa9274 commit b127bbf
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 15 deletions.
10 changes: 9 additions & 1 deletion new-log-viewer/src/components/MenuBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "@mui/joy";

import Description from "@mui/icons-material/Description";
import Download from "@mui/icons-material/Download";
import FileOpenIcon from "@mui/icons-material/FileOpen";
import Settings from "@mui/icons-material/Settings";

Expand All @@ -30,7 +31,7 @@ import "./index.css";
* @return
*/
const MenuBar = () => {
const {fileName, loadFile} = useContext(StateContext);
const {fileName, exportLogs, loadFile} = useContext(StateContext);

const [isSettingsModalOpen, setIsSettingsModalOpen] = useState<boolean>(false);

Expand All @@ -48,6 +49,10 @@ const MenuBar = () => {
setIsSettingsModalOpen(true);
};

const handleExportLogsButtonClick = () => {
exportLogs();
};

return (
<>
<Sheet className={"menu-bar"}>
Expand Down Expand Up @@ -76,6 +81,9 @@ const MenuBar = () => {
>
<Settings/>
</SmallIconButton>
<SmallIconButton onClick={handleExportLogsButtonClick}>
<Download/>
</SmallIconButton>
</Sheet>
<SettingsModal
isOpen={isSettingsModalOpen}
Expand Down
72 changes: 58 additions & 14 deletions new-log-viewer/src/contexts/StateContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import {
WORKER_RESP_CODE,
WorkerReq,
} from "../typings/worker";
import {getConfig} from "../utils/config";
import {
EXPORT_LOGS_CHUNK_SIZE,
getConfig,
} from "../utils/config";
import {
clamp,
getChunkNum,
Expand All @@ -37,12 +40,14 @@ import {
interface StateContextType {
beginLineNumToLogEventNum: BeginLineNumToLogEventNumMap,
fileName: string,
loadFile: (fileSrc: FileSrcType, cursor: CursorType) => void,
loadPage: (newPageNum: number) => void,
logData: string,
numEvents: number,
numPages: number,
pageNum: Nullable<number>
pageNum: Nullable<number>,

exportLogs: () => void,
loadFile: (fileSrc: FileSrcType, cursor: CursorType) => void,
loadPage: (newPageNum: number) => void,
}
const StateContext = createContext<StateContextType>({} as StateContextType);

Expand All @@ -52,12 +57,14 @@ const StateContext = createContext<StateContextType>({} as StateContextType);
const STATE_DEFAULT: Readonly<StateContextType> = Object.freeze({
beginLineNumToLogEventNum: new Map<number, number>(),
fileName: "",
loadFile: () => null,
loadPage: () => null,
logData: "Loading...",
numEvents: 0,
numPages: 0,
pageNum: 0,

exportLogs: () => null,
loadFile: () => null,
loadPage: () => null,
});

interface StateContextProviderProps {
Expand Down Expand Up @@ -138,36 +145,71 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
const logEventNumRef = useRef(logEventNum);
const numPagesRef = useRef<number>(STATE_DEFAULT.numPages);
const pageNumRef = useRef<Nullable<number>>(STATE_DEFAULT.pageNum);
const receivedNumChunksRef = useRef<number>(0);

const mainWorkerRef = useRef<null|Worker>(null);

const handleMainWorkerResp = useCallback((ev: MessageEvent<MainWorkerRespMessage>) => {
const {code, args} = ev.data;

// Create a file blob and push the data inside
const blob = new Blob();
const url = URL.createObjectURL(blob);
const numChunks = Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE);

console.log(`[MainWorker -> Renderer] code=${code}`);
switch (code) {
case WORKER_RESP_CODE.CHUNK_DATA:
receivedNumChunksRef.current += 1;
console.log(receivedNumChunksRef.current, args.logs);

// If all chunks are received, trigger the download of the file
if (numChunks === receivedNumChunksRef.current) {
const link = document.createElement("a");
link.href = url;
link.download = `${fileName}-exported-${new Date().toISOString()
.replace(/[:.]/g, "-")}.log`;
link.click();
URL.revokeObjectURL(url);
}
break;
case WORKER_RESP_CODE.LOG_FILE_INFO:
setFileName(args.fileName);
setNumEvents(args.numEvents);
break;
case WORKER_RESP_CODE.NOTIFICATION:
// eslint-disable-next-line no-warning-comments
// TODO: notifications should be shown in the UI when the NotificationProvider
// is added
console.error(args.logLevel, args.message);
break;
case WORKER_RESP_CODE.PAGE_DATA: {
setLogData(args.logs);
beginLineNumToLogEventNumRef.current = args.beginLineNumToLogEventNum;
const lastLogEventNum = getLastLogEventNum(args.beginLineNumToLogEventNum);
updateLogEventNumInUrl(lastLogEventNum, logEventNumRef.current);
break;
}
case WORKER_RESP_CODE.NOTIFICATION:
// eslint-disable-next-line no-warning-comments
// TODO: notifications should be shown in the UI when the NotificationProvider
// is added
console.error(args.logLevel, args.message);
break;
default:
console.error(`Unexpected ev.data: ${JSON.stringify(ev.data)}`);
break;
}
}, []);

const exportLogs = useCallback(() => {
if (null === mainWorkerRef.current) {
console.error("Unexpected null mainWorkerRef.current");

return;
}
receivedNumChunksRef.current = 0;
workerPostReq(
mainWorkerRef.current,
WORKER_REQ_CODE.EXPORT_LOG,
{decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS)}
);
}, []);

const loadFile = useCallback((fileSrc: FileSrcType, cursor: CursorType) => {
if ("string" !== typeof fileSrc) {
updateWindowUrlSearchParams({[SEARCH_PARAM_NAMES.FILE_PATH]: null});
Expand Down Expand Up @@ -275,12 +317,14 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
value={{
beginLineNumToLogEventNum: beginLineNumToLogEventNumRef.current,
fileName: fileName,
loadFile: loadFile,
loadPage: loadPage,
logData: logData,
numEvents: numEvents,
numPages: numPagesRef.current,
pageNum: pageNumRef.current,

exportLogs: exportLogs,
loadFile: loadFile,
loadPage: loadPage,
}}
>
{children}
Expand Down
25 changes: 25 additions & 0 deletions new-log-viewer/src/services/LogFileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
CursorType,
FileSrcType,
} from "../typings/worker";
import {EXPORT_LOGS_CHUNK_SIZE} from "../utils/config";
import {getUint8ArrayFrom} from "../utils/http";
import {getChunkNum} from "../utils/math";
import {formatSizeInBytes} from "../utils/units";
Expand Down Expand Up @@ -152,6 +153,30 @@ class LogFileManager {
this.#decoder.setDecoderOptions(options);
}

loadChunk (eventIdx: number): {
logs: string,
} {
const results = this.#decoder.decode(
eventIdx,
Math.min(eventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents)
);

if (null === results) {
throw new Error("Error occurred during decoding chunk. " +
`eventIdx=${eventIdx});`);
}

const messages: string[] = [];
results.forEach((r) => {
const [msg] = r;
messages.push(msg);
});

return {
logs: messages.join(""),
};
}

/**
* Loads a page of log events based on the provided cursor.
*
Expand Down
14 changes: 14 additions & 0 deletions new-log-viewer/src/services/MainWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
WORKER_RESP_CODE,
WorkerResp,
} from "../typings/worker";
import {EXPORT_LOGS_CHUNK_SIZE} from "../utils/config";
import LogFileManager from "./LogFileManager";


Expand All @@ -17,6 +18,7 @@ dayjs.extend(dayjsUtc);
dayjs.extend(dayjsTimezone);
/* eslint-enable import/no-named-as-default-member */


/**
* Manager for the currently opened log file.
*/
Expand All @@ -41,6 +43,18 @@ onmessage = async (ev: MessageEvent<MainWorkerReqMessage>) => {

try {
switch (code) {
case WORKER_REQ_CODE.EXPORT_LOG: {
if (null === LOG_FILE_MANAGER) {
throw new Error("Log file manager hasn't been initialized");
}

let decodedEventIdx = 0;
while (LOG_FILE_MANAGER.numEvents > decodedEventIdx) {
postResp(WORKER_RESP_CODE.CHUNK_DATA, LOG_FILE_MANAGER.loadChunk(decodedEventIdx));
decodedEventIdx += EXPORT_LOGS_CHUNK_SIZE;
}
break;
}
case WORKER_REQ_CODE.LOAD_FILE: {
LOG_FILE_MANAGER = await LogFileManager.create(
args.fileSrc,
Expand Down
8 changes: 8 additions & 0 deletions new-log-viewer/src/typings/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,22 @@ type BeginLineNumToLogEventNumMap = Map<number, number>;
* Enum of the protocol code for communications between the renderer and MainWorker.
*/
enum WORKER_REQ_CODE {
EXPORT_LOG = "exportLog",
LOAD_FILE = "loadFile",
LOAD_PAGE = "loadPage",
}

enum WORKER_RESP_CODE {
CHUNK_DATA = "chunkData",
LOG_FILE_INFO = "fileInfo",
PAGE_DATA = "pageData",
NOTIFICATION = "notification",
}

type WorkerReqMap = {
[WORKER_REQ_CODE.EXPORT_LOG]: {
decoderOptions: DecoderOptionsType
}
[WORKER_REQ_CODE.LOAD_FILE]: {
fileSrc: FileSrcType,
pageSize: number,
Expand All @@ -62,6 +67,9 @@ type WorkerReqMap = {
};

type WorkerRespMap = {
[WORKER_RESP_CODE.CHUNK_DATA]: {
logs: string
},
[WORKER_RESP_CODE.LOG_FILE_INFO]: {
fileName: string,
numEvents: number,
Expand Down
2 changes: 2 additions & 0 deletions new-log-viewer/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {DecoderOptionsType} from "../typings/decoders";


const MAX_PAGE_SIZE = 1_000_000;
const EXPORT_LOGS_CHUNK_SIZE = 10_000;

/**
* The default configuration values.
Expand Down Expand Up @@ -148,6 +149,7 @@ const getConfig = <T extends CONFIG_KEY>(key: T): ConfigMap[T] => {

export {
CONFIG_DEFAULT,
EXPORT_LOGS_CHUNK_SIZE,
getConfig,
setConfig,
testConfig,
Expand Down

0 comments on commit b127bbf

Please sign in to comment.