UNPKG

chkplot

Version:
454 lines (453 loc) 19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parsePlotterLog = void 0; function parsePlotterLog(log) { var _a; const lines = Array.isArray(log) ? log : log.trim().split(/\r\n|\r|\n/); const maxLine = lines.length; const params = {}; const phase1 = {}; const phase2 = {}; const phase3 = {}; const phase4 = {}; const phaseSummary = {}; const copyPhase = {}; let currentPhase = "starting"; let subState = ""; for (let l = 0; l < maxLine; l++) { const lineNo = l + 1; const line = lines[l]; if (currentPhase === "starting") { const regex = /^(.+?)\s+chia.+Creating\s+(\d+)\s+plots of size\s+(\d+),\s+pool public key:\s+([a-fA-F0-9]+)\s+farmer public key:\s+([a-fA-F0-9]+).+$/; let match = regex.exec(line); if (match) { params.start_time = new Date(match[1]); params.k = +match[3]; params.pool_public_key = match[4]; params.farmer_public_key = match[5]; continue; } const regex2 = /^(.+?)\s+chia.+INFO.+Memo:\s+([a-fA-F0-9]+).+$/; match = regex2.exec(line); if (match) { params.memo = match[2]; continue; } const regex3 = /^Starting plotting progress into temporary dirs: (.+) and (.+)$/; match = regex3.exec(line); if (match) { params.temp1_dir = match[1]; params.temp2_dir = match[2]; continue; } const regex4 = /^ID:\s+(.+)$/; match = regex4.exec(line); if (match) { params.id = match[1]; continue; } const regex5 = /^Buffer size is:\s+([\d.]+)(.+)$/; match = regex5.exec(line); if (match) { params.buffer_size = [+match[1], match[2]]; continue; } const regex6 = /^Using (\d+) buckets$/; match = regex6.exec(line); if (match) { params.buckets = +match[1]; continue; } const regex8 = /^Final Directory is: (.+)$/; match = regex8.exec(line); if (match) { params.final_dir = match[1]; continue; } const regex7 = /^Using (\d+) threads of stripe size (\d+)$/; match = regex7.exec(line); if (match) { params.threads = +match[1]; params.stripe_size = +match[2]; currentPhase = "phase1"; // Do not 'continue' here because some version of chiapos may output log like "Process ID is:...". } const line2 = lines[l + 1]; const regex9 = /^Process ID is: (.+)$/; match = regex9.exec(line2); if (match) { params.process_id = match[1]; l += 2; // Skip a blank line currentPhase = "phase1"; continue; } continue; } else if (currentPhase === "phase1") { const regexForPhase1Start = /^Starting phase 1\/4: Forward Propagation into tmp files\.\.\. (.+)$/; let match = regexForPhase1Start.exec(line); if (match) { phase1.start_date = new Date(match[1]); continue; } const regexF1Complete = /^F1 complete, time: (\d+\.?\d*) seconds. CPU \((.+)%\) (.+)$/; match = regexF1Complete.exec(line); if (match) { phase1.table1 = { f1_complete: { time: +match[1], cpu: +match[2], date: new Date(match[3]), } }; continue; } const regexForComputingTable = /^Computing table (\d+)$/; match = regexForComputingTable.exec(line); if (match) { subState = `table${match[1]}`; phase1[subState] = phase1[subState] || {}; continue; } const regexForBuckets = /^\tBucket (\d+) (.+)\. Ram: ([\d.]+)(.+), u_sort min: ([\d.]+)(.+), qs min: ([\d.]+)(.+)\.( force_qs: (.*))?$/; match = regexForBuckets.exec(line); if (match) { phase1[subState].bucketInfo = ((_a = (phase1[subState])) === null || _a === void 0 ? void 0 : _a.bucketInfo) || []; const bucketInfo = { bucket: +match[1], sort: match[2], ram: [+match[3], match[4]], u_sort_min: [+match[5], match[6]], qs_min: [+match[7], match[8]], force_qs: match.length > 10 ? match[10] : undefined, }; phase1[subState].bucketInfo.push(bucketInfo); continue; } const regexForTotalMatches = /^\tTotal matches: (\d+)$/; match = regexForTotalMatches.exec(line); if (match) { phase1[subState].total_matches = +match[1]; continue; } const regexForForwardPropagation = /^Forward propagation table time: (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForForwardPropagation.exec(line); if (match) { phase1[subState].complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexForPhase1Complete = /^Time for phase 1 = (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForPhase1Complete.exec(line); if (match) { phase1.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; currentPhase = "phase2"; subState = ""; l++; // Skip a blank line between phase 1 and 2. continue; } } else if (currentPhase === "phase2") { const regexForPhase2Start = /^Starting phase 2\/4.+\.\.\. (.+)$/; let match = regexForPhase2Start.exec(line); if (match) { phase2.start_date = new Date(match[1]); continue; } const regexIgnoring = /^Backpropagating on table (\d+)$/; const regexIgnoring2 = /^scanned table (\d+)$/; const regexIgnoring3 = /^sorting table (\d+)$/; match = regexIgnoring.exec(line) || regexIgnoring2.exec(line) || regexIgnoring3.exec(line); if (match) { subState = `table${match[1]}`; continue; } const regexScannedTime = /^scanned time\s+=\s+(.+)\s+seconds. CPU\s+\((.+)%\)\s+(.+)$/; match = regexScannedTime.exec(line); if (match) { phase2[subState] = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexTable1NewSize = /^table 1 new size: (\d+)$/; match = regexTable1NewSize.exec(line); if (match) { phase2.table1_new_size = +match[1]; continue; } const regexPhase2Time = /^Time for phase 2 =\s+(.+)\s+seconds. CPU\s+\((.+)%\)\s+(.+)$/; match = regexPhase2Time.exec(line); if (match) { phase2.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexWrote = /^Wrote: (.+)$/; match = regexWrote.exec(line); if (match) { phase2.wrote = +match[1]; currentPhase = "phase3"; subState = ""; l++; // Skip a blank line between phase 2 and 3. } } else if (currentPhase === "phase3") { const regexForPhase3Start = /^Starting phase 3\/4.+from tmp files into "(.+)"\s+\.\.\.\s+(.+)$/; let match = regexForPhase3Start.exec(line); if (match) { phase3.tmp_path = match[1]; phase3.start_date = new Date(match[2]); continue; } const regexForTables1And2 = /^Compressing tables (.+) and (.+)$/; match = regexForTables1And2.exec(line); if (match) { subState = `table${match[1]}and${match[2]}`; phase3[subState] = phase3[subState] || {}; continue; } const regexForBuckets = /^\tBucket (\d+) (.+)\. Ram: ([\d.]+)(.+), u_sort min: ([\d.]+)(.+), qs min: ([\d.]+)(.+)\.( force_qs: (.*))?$/; match = regexForBuckets.exec(line); if (match) { phase3[subState].bucketInfo = phase3[subState].bucketInfo || []; const bucketInfo = { bucket: +match[1], sort: match[2], ram: [+match[3], match[4]], u_sort_min: [+match[5], match[6]], qs_min: [+match[7], match[8]], force_qs: match.length > 10 ? match[10] : undefined, }; (phase3[subState].bucketInfo).push(bucketInfo); continue; } const regexForFirstComputationSummary = /^\tFirst computation pass time: (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForFirstComputationSummary.exec(line); if (match) { phase3[subState].firstComputationSummary = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexForSecondComputationSummary = /^\tSecond computation pass time: (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForSecondComputationSummary.exec(line); if (match) { phase3[subState].secondComputationSummary = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexForWrote = /^\tWrote (.+) entries$/; match = regexForSecondComputationSummary.exec(line); if (match) { phase3[subState].wrote = +match[1]; continue; } const regexForTotalCompressTableTime = /^Total compress table time: (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForTotalCompressTableTime.exec(line); if (match) { phase3[subState].totalCompressSummary = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regexForPhase3Summary = /^Time for phase 3 = (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForPhase3Summary.exec(line); if (match) { phase3.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; currentPhase = "phase4"; subState = ""; l++; // Skip a blank line between phase 2 and 3. continue; } } else if (currentPhase === "phase4") { const regexForPhase4Start = /^Starting phase 4\/4: Write Checkpoint tables into "(.+)"\s+\.\.\.\s+(.+)$/; let match = regexForPhase4Start.exec(line); if (match) { phase4.tmp_path = match[1]; phase4.start_date = new Date(match[2]); continue; } const regexForStartingToWriteC1AndC3 = /^\tStarting to write C1 and C3 tables$/; match = regexForStartingToWriteC1AndC3.exec(line); if (match) { continue; } const regexForBuckets = /^\tBucket (\d+) (.+)\. Ram: ([\d.]+)(.+), u_sort min: ([\d.]+)(.+), qs min: ([\d.]+)(.+)\.( force_qs: (.*))?$/; match = regexForBuckets.exec(line); if (match) { phase4.bucketInfo = phase4.bucketInfo || []; const bucketInfo = { bucket: +match[1], sort: match[2], ram: [+match[3], match[4]], u_sort_min: [+match[5], match[6]], qs_min: [+match[7], match[8]], force_qs: match.length > 10 ? match[10] : undefined, }; phase4.bucketInfo.push(bucketInfo); continue; } const regexForFinishedToWriteC1AndC3 = /^\tFinished writing C1 and C3 tables$/; const regexForWritingC2Table = /^\tWriting C2 table$/; const regexForFinishedWritingC2 = /^\tFinished writing C2 table$/; const regexForFinalTablePointers = /^\tFinal table pointers:$/; match = regexForFinishedToWriteC1AndC3.exec(line) || regexForWritingC2Table.exec(line) || regexForFinishedWritingC2.exec(line) || regexForFinalTablePointers.exec(line); if (match) { continue; } const regexForXX = { P1: /^\tP1: (.+)$/, P2: /^\tP2: (.+)$/, P3: /^\tP3: (.+)$/, P4: /^\tP4: (.+)$/, P5: /^\tP5: (.+)$/, P6: /^\tP6: (.+)$/, P7: /^\tP7: (.+)$/, C1: /^\tC1: (.+)$/, C2: /^\tC2: (.+)$/, C3: /^\tC3: (.+)$/, }; for (const XX in regexForXX) { if (regexForXX.hasOwnProperty(XX)) { match = regexForXX[XX].exec(line); if (match) { phase4[XX] = match[1]; continue; } } } const regexForPhase3Summary = /^Time for phase 4 = (.+) seconds. CPU \((.+)%\) (.+)$/; match = regexForPhase3Summary.exec(line); if (match) { phase4.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; currentPhase = "create_plots_result"; subState = ""; continue; } } else if (currentPhase === "create_plots_result") { const regex1 = /^Approximate working space used \(without final file\): ([\d.]+)(.+)$/; let match = regex1.exec(line); if (match) { phaseSummary.approximate_working_space_used = [+match[1], match[2]]; continue; } const regex2 = /^Final File size: ([\d.]+)(.+)$/; match = regex2.exec(line); if (match) { phaseSummary.final_file_size = [+match[1], match[2]]; continue; } const regex3 = /^Total time = (.+) seconds. CPU \((.+)%\) (.+)$/; match = regex3.exec(line); if (match) { phaseSummary.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regex4 = /^Copied final file from "(.+)" to "(.+)"$/; match = regex4.exec(line); if (match) { copyPhase.from = match[1]; copyPhase.to = match[2]; continue; } const regex5 = /^Copy time = (.+) seconds. CPU \((.+)%\) (.+)$/; match = regex5.exec(line); if (match) { copyPhase.complete = { time: +match[1], cpu: +match[2], date: new Date(match[3]), }; continue; } const regex6 = /^Removed temp2 file "(.+)"\?\s+(.+)$/; match = regex6.exec(line); if (match) { copyPhase.removed_temp2_file = match[1]; continue; } const regex7 = /^Renamed final file from "(.+)" to "(.+)"$/; match = regex7.exec(line); if (match) { copyPhase.renamed_final_file = { from: match[1], to: match[2], }; currentPhase = "finishing"; subState = "1"; continue; } } else if (currentPhase === "finishing") { if (subState === "1") { const regex1 = /^([^\s]+)\s+chia\.plotting\.create_plots\s+:.+INFO\s+.+\s+Summary:.+$/; let match = regex1.exec(line); if (match) { subState = "2"; phaseSummary.finished_time = new Date(match[1]); continue; } const regex2 = /^([^\s]+)\s+chia\.plotting\.create_plots\s+:.+INFO\s+.+Created a total of (\d+) new plots.+$/; match = regex2.exec(line); if (match) { subState = "3"; phaseSummary.finished_time = new Date(match[1]); continue; } const regex3 = /^([^\s]+)\s+chia\.plotting\.create_plots\s+:.+INFO\s+.+Created a total of (\d+) new plots.+$/; match = regex3.exec(line); if (match) { phaseSummary.finished_time = new Date(match[1]); continue; } } } } return { params, phase1, phase2, phase3, phase4, phaseSummary, copyPhase, }; } exports.parsePlotterLog = parsePlotterLog;