@lage-run/reporters 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/AdoReporter.js +2 -2
- package/lib/AdoReporter.js.map +1 -1
- package/lib/BasicReporter.d.ts +3 -0
- package/lib/BasicReporter.js +9 -5
- package/lib/BasicReporter.js.map +1 -1
- package/lib/GithubActionsReporter.js +2 -2
- package/lib/GithubActionsReporter.js.map +1 -1
- package/lib/GroupedReporter.d.ts +5 -0
- package/lib/GroupedReporter.js +15 -7
- package/lib/GroupedReporter.js.map +1 -1
- package/lib/JsonReporter.d.ts +1 -0
- package/lib/JsonReporter.js +3 -3
- package/lib/JsonReporter.js.map +1 -1
- package/lib/LogReporter.d.ts +3 -0
- package/lib/LogReporter.js +15 -8
- package/lib/LogReporter.js.map +1 -1
- package/lib/ProgressReporter.d.ts +3 -0
- package/lib/ProgressReporter.js +14 -7
- package/lib/ProgressReporter.js.map +1 -1
- package/lib/VerboseFileLogReporter.d.ts +4 -1
- package/lib/VerboseFileLogReporter.js +18 -9
- package/lib/VerboseFileLogReporter.js.map +1 -1
- package/lib/formatDuration.d.ts +6 -0
- package/lib/formatDuration.js +55 -0
- package/lib/formatDuration.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +10 -0
- package/lib/index.js.map +1 -1
- package/lib/slowestTargetRuns.js +2 -2
- package/lib/slowestTargetRuns.js.map +1 -1
- package/lib/types/TargetLogData.d.ts +5 -0
- package/package.json +4 -4
package/lib/AdoReporter.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "AdoReporter", {
|
|
|
8
8
|
return AdoReporter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
13
13
|
const _GroupedReporter = require("./GroupedReporter.js");
|
|
14
14
|
function _interop_require_default(obj) {
|
|
@@ -18,7 +18,7 @@ function _interop_require_default(obj) {
|
|
|
18
18
|
}
|
|
19
19
|
class AdoReporter extends _GroupedReporter.GroupedReporter {
|
|
20
20
|
formatGroupStart(packageName, task, status, duration) {
|
|
21
|
-
return `##[group] ${_GroupedReporter.colors.pkg(packageName)} ${_GroupedReporter.colors.task(task)} ${status}${duration ? `, took ${(0,
|
|
21
|
+
return `##[group] ${_GroupedReporter.colors.pkg(packageName)} ${_GroupedReporter.colors.task(task)} ${status}${duration ? `, took ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))}` : ""}\n`;
|
|
22
22
|
}
|
|
23
23
|
formatGroupEnd() {
|
|
24
24
|
return `##[endgroup]\n`;
|
package/lib/AdoReporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AdoReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"
|
|
1
|
+
{"version":3,"sources":["../src/AdoReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"./formatDuration.js\";\nimport chalk from \"chalk\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { colors, GroupedReporter } from \"./GroupedReporter.js\";\n\nexport class AdoReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `##[group] ${colors.pkg(packageName)} ${colors.task(task)} ${status}${\n duration ? `, took ${formatDuration(hrToSeconds(duration))}` : \"\"\n }\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `##[endgroup]\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(chalk.cyanBright(`##[section]Summary\\n`));\n }\n\n protected writeSummaryFooter(): void {\n // ADO sections have no closing marker\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n let packagesMessage = `##vso[task.logissue type=error]Your build failed on the following packages => `;\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n packagesMessage += `[${packageName} ${task}], `;\n\n this.logStream.write(`##[error] [${chalk.magenta(packageName)} ${chalk.cyan(task)}] ${chalk.redBright(\"ERROR DETECTED\")}\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n // Log each entry separately to prevent truncation\n this.logStream.write(`##[error] ${entry.msg}\\n`);\n }\n }\n }\n }\n\n packagesMessage += \"find the error logs above with the prefix '##[error]!'\\n\";\n this.logStream.write(packagesMessage);\n }\n}\n"],"names":["AdoReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","colors","pkg","formatDuration","hrToSeconds","formatGroupEnd","writeSummaryHeader","logStream","write","chalk","cyanBright","writeSummaryFooter","writeFailures","failed","targetRuns","packagesMessage","targetId","target","get","taskLogs","logEntries","magenta","cyan","redBright","entry","msg"],"mappings":";;;;+BAKaA;;;eAAAA;;;gCAL+B;8DAC1B;iCAEsB;;;;;;AAEjC,MAAMA,oBAAoBC,gCAAe;IACpCC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,UAAU,EAAEC,uBAAM,CAACC,GAAG,CAACL,aAAa,CAAC,EAAEI,uBAAM,CAACH,IAAI,CAACA,MAAM,CAAC,EAAEC,SAClEC,WAAW,CAAC,OAAO,EAAEG,IAAAA,8BAAc,EAACC,IAAAA,2BAAW,EAACJ,YAAY,GAAG,GAChE,EAAE,CAAC;IACN;IAEUK,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAACC,cAAK,CAACC,UAAU,CAAC,CAAC,oBAAoB,CAAC;IAC9D;IAEUC,qBAA2B;IACnC,sCAAsC;IACxC;IAEUC,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,IAAIC,kBAAkB,CAAC,8EAA8E,CAAC;QAEtG,KAAK,MAAMC,YAAYH,OAAQ;YAC7B,MAAMI,SAASH,WAAWI,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEpB,WAAW,EAAEC,IAAI,EAAE,GAAGmB;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErCD,mBAAmB,CAAC,CAAC,EAAElB,YAAY,CAAC,EAAEC,KAAK,GAAG,CAAC;gBAE/C,IAAI,CAACS,SAAS,CAACC,KAAK,CAAC,CAAC,WAAW,EAAEC,cAAK,CAACY,OAAO,CAACxB,aAAa,CAAC,EAAEY,cAAK,CAACa,IAAI,CAACxB,MAAM,EAAE,EAAEW,cAAK,CAACc,SAAS,CAAC,kBAAkB,EAAE,CAAC;gBAE3H,IAAIJ,UAAU;oBACZ,KAAK,MAAMK,SAASL,SAAU;wBAC5B,kDAAkD;wBAClD,IAAI,CAACZ,SAAS,CAACC,KAAK,CAAC,CAAC,UAAU,EAAEgB,MAAMC,GAAG,CAAC,EAAE,CAAC;oBACjD;gBACF;YACF;QACF;QAEAV,mBAAmB;QACnB,IAAI,CAACR,SAAS,CAACC,KAAK,CAACO;IACvB;AACF"}
|
package/lib/BasicReporter.d.ts
CHANGED
|
@@ -4,10 +4,13 @@ export declare class BasicReporter implements Reporter {
|
|
|
4
4
|
private taskData;
|
|
5
5
|
private updateTimer;
|
|
6
6
|
private startTimer;
|
|
7
|
+
private logMemory;
|
|
7
8
|
constructor(params?: {
|
|
8
9
|
concurrency?: number;
|
|
9
10
|
version?: string;
|
|
10
11
|
frequency?: number;
|
|
12
|
+
/** Whether to capture and report main process memory usage on target completion */
|
|
13
|
+
logMemory?: boolean;
|
|
11
14
|
});
|
|
12
15
|
log(entry: LogEntry): void;
|
|
13
16
|
summarize(schedulerRunSummary: SchedulerRunSummary): void;
|
package/lib/BasicReporter.js
CHANGED
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "BasicReporter", {
|
|
|
10
10
|
});
|
|
11
11
|
const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
12
12
|
const _gradient = require("./gradient.js");
|
|
13
|
-
const
|
|
13
|
+
const _formatDuration = require("./formatDuration.js");
|
|
14
14
|
const _formatBytes = require("./formatBytes.js");
|
|
15
15
|
function _define_property(obj, key, value) {
|
|
16
16
|
if (key in obj) {
|
|
@@ -91,7 +91,8 @@ class BasicReporter {
|
|
|
91
91
|
this.reportCompletion({
|
|
92
92
|
target: data.target,
|
|
93
93
|
status: data.status,
|
|
94
|
-
duration: data.duration
|
|
94
|
+
duration: data.duration,
|
|
95
|
+
memoryUsage: data.memoryUsage
|
|
95
96
|
});
|
|
96
97
|
}
|
|
97
98
|
}
|
|
@@ -127,13 +128,14 @@ class BasicReporter {
|
|
|
127
128
|
...targetRuns.values()
|
|
128
129
|
].filter((run)=>!run.target.hidden).length === skipped.length;
|
|
129
130
|
const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : "";
|
|
130
|
-
print(`Took a total of ${(0,
|
|
131
|
+
print(`Took a total of ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))} to complete. ${allCacheHitText}`);
|
|
131
132
|
}
|
|
132
133
|
reportCompletion(completion) {
|
|
133
134
|
const icon = icons[completion.status];
|
|
134
135
|
const statusColor = colors[completion.status];
|
|
135
|
-
const durationText = completion.duration ? ` (${(0,
|
|
136
|
-
const
|
|
136
|
+
const durationText = completion.duration ? ` (${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(completion.duration))})` : "";
|
|
137
|
+
const memText = this.logMemory && completion.memoryUsage ? ` [rss: ${(0, _formatBytes.formatBytes)(completion.memoryUsage.rss)}, heap: ${(0, _formatBytes.formatBytes)(completion.memoryUsage.heapUsed)}]` : "";
|
|
138
|
+
const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText)}${colors.duration(memText)}`;
|
|
137
139
|
this.renderStatus(message);
|
|
138
140
|
}
|
|
139
141
|
renderStatus(completedTaskMessage) {
|
|
@@ -162,7 +164,9 @@ class BasicReporter {
|
|
|
162
164
|
_define_property(this, "taskData", new Map());
|
|
163
165
|
_define_property(this, "updateTimer", void 0);
|
|
164
166
|
_define_property(this, "startTimer", void 0);
|
|
167
|
+
_define_property(this, "logMemory", void 0);
|
|
165
168
|
const { concurrency = 0, version = "0.0.0", frequency = 500 } = params;
|
|
169
|
+
this.logMemory = !!params.logMemory;
|
|
166
170
|
print(`${fancy("lage")} - Version ${version} - ${concurrency} Workers`);
|
|
167
171
|
this.startTimer = ()=>{
|
|
168
172
|
this.updateTimer = setInterval(()=>this.renderStatus(), frequency);
|
package/lib/BasicReporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/BasicReporter.ts"],"sourcesContent":["import { type LogEntry, type Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport chalk from \"chalk\";\nimport { gradient } from \"./gradient.js\";\nimport { formatDuration, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport { formatBytes } from \"./formatBytes.js\";\n\ntype CoarseStatus = \"completed\" | \"running\" | \"pending\";\n\nconst coarseStatus: Record<TargetStatus, CoarseStatus> = {\n success: \"completed\",\n failed: \"completed\",\n skipped: \"completed\",\n aborted: \"completed\",\n running: \"running\",\n pending: \"pending\",\n queued: \"pending\",\n};\n\ntype CompletionStatus = \"success\" | \"failed\" | \"skipped\" | \"aborted\";\nconst isCompletionStatus = (status: TargetStatus): status is CompletionStatus => coarseStatus[status] === \"completed\";\n\nconst colors = {\n label: chalk.white,\n timestamp: chalk.gray,\n duration: chalk.gray,\n success: chalk.green,\n failed: chalk.red,\n skipped: chalk.gray,\n aborted: chalk.yellow,\n summary: chalk.cyanBright,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n};\n\nconst hrLine = \"┈\".repeat(80);\n\nconst icons: Record<CompletionStatus, string> = {\n success: \"✓\",\n failed: \"✗\",\n skipped: \"-\",\n aborted: \"-\",\n};\n\nconst terminal = {\n hideCursor: \"\\x1b[?25l\",\n showCursor: \"\\x1b[?25h\",\n clearLine: \"\\x1b[2K\\r\",\n};\n\nconst fancy = (str: string) => gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(str);\nconst print = (message: string) => process.stdout.write(message + \"\\n\");\n\nexport class BasicReporter implements Reporter {\n private taskData = new Map<string, { target: Target; status: TargetStatus; logEntries: LogEntry[] }>();\n private updateTimer: NodeJS.Timeout | undefined;\n private startTimer: () => void;\n\n constructor(params: { concurrency?: number; version?: string; frequency?: number } = {}) {\n const { concurrency = 0, version = \"0.0.0\", frequency = 500 } = params;\n print(`${fancy(\"lage\")} - Version ${version} - ${concurrency} Workers`);\n\n this.startTimer = () => {\n this.updateTimer = setInterval(() => this.renderStatus(), frequency);\n this.updateTimer.unref();\n this.startTimer = () => {};\n };\n\n process.stdout.write(terminal.hideCursor);\n process.on(\"exit\", () => process.stdout.write(terminal.showCursor));\n }\n\n public log(entry: LogEntry): void {\n const data = entry.data;\n if (!data?.target || data.target.hidden) return;\n\n let taskData = this.taskData.get(data.target.id);\n if (!taskData) {\n taskData = { target: data.target, status: \"pending\", logEntries: [] };\n this.taskData.set(data.target.id, taskData);\n }\n\n this.startTimer();\n taskData.logEntries.push(entry);\n\n if (data.status) {\n taskData.status = data.status;\n if (isCompletionStatus(data.status)) {\n this.reportCompletion({ target: data.target, status: data.status, duration: data.duration });\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n clearInterval(this.updateTimer);\n process.stdout.write(terminal.clearLine);\n\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n if (targetRuns.size > 0) {\n print(colors.summary(`\\nSummary`));\n print(hrLine);\n print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(schedulerRunSummary.maxWorkerMemoryUsage)}`\n );\n } else {\n print(\"Nothing has been run.\");\n }\n\n print(hrLine);\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n if (target) {\n const failureLogs = this.taskData.get(targetId)?.logEntries;\n\n print(`[${colors.pkg(target.packageName ?? \"<root>\")} ${colors.task(target.task)}] ${colors.failed(\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n print(entry.msg);\n }\n }\n print(hrLine);\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : \"\";\n\n print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n\n private reportCompletion(completion: { target: Target; status: CompletionStatus; duration?: [number, number] }) {\n const icon = icons[completion.status];\n const statusColor = colors[completion.status];\n const durationText = completion.duration ? ` (${formatDuration(hrToSeconds(completion.duration))})` : \"\";\n\n const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText)}`;\n this.renderStatus(message);\n }\n\n private renderStatus(completedTaskMessage?: string) {\n const counts: Record<CoarseStatus, number> = { completed: 0, running: 0, pending: 0 };\n for (const data of this.taskData.values()) {\n counts[coarseStatus[data.status]]++;\n }\n const { completed, running, pending } = counts;\n const total = this.taskData.size;\n const timestamp = colors.timestamp(`[${new Date().toLocaleTimeString(\"en-US\", { hour12: false })}]`);\n\n let output = terminal.clearLine;\n if (completedTaskMessage) {\n output += `${timestamp} ${completedTaskMessage}\\n`;\n }\n const percentage = Math.round((completed / total) * 100);\n output += `${timestamp} Completed: ${completed}/${total} (${percentage}%) [${running} running, ${pending} pending]`;\n process.stdout.write(output);\n }\n}\n"],"names":["BasicReporter","coarseStatus","success","failed","skipped","aborted","running","pending","queued","isCompletionStatus","status","colors","label","chalk","white","timestamp","gray","duration","green","red","yellow","summary","cyanBright","task","hex","pkg","hrLine","repeat","icons","terminal","hideCursor","showCursor","clearLine","fancy","str","gradient","r","g","b","print","message","process","stdout","write","log","entry","data","target","hidden","taskData","get","id","logEntries","set","startTimer","push","reportCompletion","summarize","schedulerRunSummary","clearInterval","updateTimer","targetRuns","targetRunByStatus","size","length","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","failureLogs","packageName","msg","allCacheHits","values","filter","run","allCacheHitText","formatDuration","hrToSeconds","completion","icon","statusColor","durationText","padEnd","renderStatus","completedTaskMessage","counts","completed","total","Date","toLocaleTimeString","hour12","output","percentage","Math","round","params","Map","concurrency","version","frequency","setInterval","unref","on"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/BasicReporter.ts"],"sourcesContent":["import { type LogEntry, type Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport chalk from \"chalk\";\nimport { gradient } from \"./gradient.js\";\nimport { formatDuration, hrToSeconds } from \"./formatDuration.js\";\nimport { formatBytes } from \"./formatBytes.js\";\n\ntype CoarseStatus = \"completed\" | \"running\" | \"pending\";\n\nconst coarseStatus: Record<TargetStatus, CoarseStatus> = {\n success: \"completed\",\n failed: \"completed\",\n skipped: \"completed\",\n aborted: \"completed\",\n running: \"running\",\n pending: \"pending\",\n queued: \"pending\",\n};\n\ntype CompletionStatus = \"success\" | \"failed\" | \"skipped\" | \"aborted\";\nconst isCompletionStatus = (status: TargetStatus): status is CompletionStatus => coarseStatus[status] === \"completed\";\n\nconst colors = {\n label: chalk.white,\n timestamp: chalk.gray,\n duration: chalk.gray,\n success: chalk.green,\n failed: chalk.red,\n skipped: chalk.gray,\n aborted: chalk.yellow,\n summary: chalk.cyanBright,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n};\n\nconst hrLine = \"┈\".repeat(80);\n\nconst icons: Record<CompletionStatus, string> = {\n success: \"✓\",\n failed: \"✗\",\n skipped: \"-\",\n aborted: \"-\",\n};\n\nconst terminal = {\n hideCursor: \"\\x1b[?25l\",\n showCursor: \"\\x1b[?25h\",\n clearLine: \"\\x1b[2K\\r\",\n};\n\nconst fancy = (str: string) => gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(str);\nconst print = (message: string) => process.stdout.write(message + \"\\n\");\n\nexport class BasicReporter implements Reporter {\n private taskData = new Map<string, { target: Target; status: TargetStatus; logEntries: LogEntry[] }>();\n private updateTimer: NodeJS.Timeout | undefined;\n private startTimer: () => void;\n private logMemory: boolean;\n\n constructor(\n params: {\n concurrency?: number;\n version?: string;\n frequency?: number;\n /** Whether to capture and report main process memory usage on target completion */\n logMemory?: boolean;\n } = {}\n ) {\n const { concurrency = 0, version = \"0.0.0\", frequency = 500 } = params;\n this.logMemory = !!params.logMemory;\n print(`${fancy(\"lage\")} - Version ${version} - ${concurrency} Workers`);\n\n this.startTimer = () => {\n this.updateTimer = setInterval(() => this.renderStatus(), frequency);\n this.updateTimer.unref();\n this.startTimer = () => {};\n };\n\n process.stdout.write(terminal.hideCursor);\n process.on(\"exit\", () => process.stdout.write(terminal.showCursor));\n }\n\n public log(entry: LogEntry): void {\n const data = entry.data;\n if (!data?.target || data.target.hidden) return;\n\n let taskData = this.taskData.get(data.target.id);\n if (!taskData) {\n taskData = { target: data.target, status: \"pending\", logEntries: [] };\n this.taskData.set(data.target.id, taskData);\n }\n\n this.startTimer();\n taskData.logEntries.push(entry);\n\n if (data.status) {\n taskData.status = data.status;\n if (isCompletionStatus(data.status)) {\n this.reportCompletion({ target: data.target, status: data.status, duration: data.duration, memoryUsage: data.memoryUsage });\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n clearInterval(this.updateTimer);\n process.stdout.write(terminal.clearLine);\n\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n if (targetRuns.size > 0) {\n print(colors.summary(`\\nSummary`));\n print(hrLine);\n print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(schedulerRunSummary.maxWorkerMemoryUsage)}`\n );\n } else {\n print(\"Nothing has been run.\");\n }\n\n print(hrLine);\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n if (target) {\n const failureLogs = this.taskData.get(targetId)?.logEntries;\n\n print(`[${colors.pkg(target.packageName ?? \"<root>\")} ${colors.task(target.task)}] ${colors.failed(\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n print(entry.msg);\n }\n }\n print(hrLine);\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : \"\";\n\n print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n\n private reportCompletion(completion: {\n target: Target;\n status: CompletionStatus;\n duration?: [number, number];\n memoryUsage?: NodeJS.MemoryUsage;\n }) {\n const icon = icons[completion.status];\n const statusColor = colors[completion.status];\n const durationText = completion.duration ? ` (${formatDuration(hrToSeconds(completion.duration))})` : \"\";\n const memText =\n this.logMemory && completion.memoryUsage\n ? ` [rss: ${formatBytes(completion.memoryUsage.rss)}, heap: ${formatBytes(completion.memoryUsage.heapUsed)}]`\n : \"\";\n\n const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText)}${colors.duration(memText)}`;\n this.renderStatus(message);\n }\n\n private renderStatus(completedTaskMessage?: string) {\n const counts: Record<CoarseStatus, number> = { completed: 0, running: 0, pending: 0 };\n for (const data of this.taskData.values()) {\n counts[coarseStatus[data.status]]++;\n }\n const { completed, running, pending } = counts;\n const total = this.taskData.size;\n const timestamp = colors.timestamp(`[${new Date().toLocaleTimeString(\"en-US\", { hour12: false })}]`);\n\n let output = terminal.clearLine;\n if (completedTaskMessage) {\n output += `${timestamp} ${completedTaskMessage}\\n`;\n }\n const percentage = Math.round((completed / total) * 100);\n output += `${timestamp} Completed: ${completed}/${total} (${percentage}%) [${running} running, ${pending} pending]`;\n process.stdout.write(output);\n }\n}\n"],"names":["BasicReporter","coarseStatus","success","failed","skipped","aborted","running","pending","queued","isCompletionStatus","status","colors","label","chalk","white","timestamp","gray","duration","green","red","yellow","summary","cyanBright","task","hex","pkg","hrLine","repeat","icons","terminal","hideCursor","showCursor","clearLine","fancy","str","gradient","r","g","b","print","message","process","stdout","write","log","entry","data","target","hidden","taskData","get","id","logEntries","set","startTimer","push","reportCompletion","memoryUsage","summarize","schedulerRunSummary","clearInterval","updateTimer","targetRuns","targetRunByStatus","size","length","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","failureLogs","packageName","msg","allCacheHits","values","filter","run","allCacheHitText","formatDuration","hrToSeconds","completion","icon","statusColor","durationText","memText","logMemory","rss","heapUsed","padEnd","renderStatus","completedTaskMessage","counts","completed","total","Date","toLocaleTimeString","hour12","output","percentage","Math","round","params","Map","concurrency","version","frequency","setInterval","unref","on"],"mappings":"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"}
|
|
@@ -8,11 +8,11 @@ Object.defineProperty(exports, "GithubActionsReporter", {
|
|
|
8
8
|
return GithubActionsReporter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
const _GroupedReporter = require("./GroupedReporter.js");
|
|
13
13
|
class GithubActionsReporter extends _GroupedReporter.GroupedReporter {
|
|
14
14
|
formatGroupStart(packageName, task, status, duration) {
|
|
15
|
-
return `::group::${packageName} ${task} ${status}${duration ? `, took ${(0,
|
|
15
|
+
return `::group::${packageName} ${task} ${status}${duration ? `, took ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))}` : ""}\n`;
|
|
16
16
|
}
|
|
17
17
|
formatGroupEnd() {
|
|
18
18
|
return `::endgroup::\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/GithubActionsReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"
|
|
1
|
+
{"version":3,"sources":["../src/GithubActionsReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"./formatDuration.js\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { GroupedReporter } from \"./GroupedReporter.js\";\n\nexport class GithubActionsReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `::group::${packageName} ${task} ${status}${duration ? `, took ${formatDuration(hrToSeconds(duration))}` : \"\"}\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `::endgroup::\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(`::group::Summary\\n`);\n }\n\n protected writeSummaryFooter(): void {\n this.logStream.write(`::endgroup::\\n`);\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n this.logStream.write(`::error title=${packageName} ${task}::Build failed\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n if (entry.msg.trim() !== \"\") {\n this.logStream.write(`::error::${entry.msg}\\n`);\n }\n }\n }\n }\n }\n }\n}\n"],"names":["GithubActionsReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","formatDuration","hrToSeconds","formatGroupEnd","writeSummaryHeader","logStream","write","writeSummaryFooter","writeFailures","failed","targetRuns","targetId","target","get","taskLogs","logEntries","entry","msg","trim"],"mappings":";;;;+BAIaA;;;eAAAA;;;gCAJ+B;iCAEZ;AAEzB,MAAMA,8BAA8BC,gCAAe;IAC9CC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,SAAS,EAAEH,YAAY,CAAC,EAAEC,KAAK,CAAC,EAAEC,SAASC,WAAW,CAAC,OAAO,EAAEC,IAAAA,8BAAc,EAACC,IAAAA,2BAAW,EAACF,YAAY,GAAG,GAAG,EAAE,CAAC;IAC1H;IAEUG,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAAC,CAAC,kBAAkB,CAAC;IAC3C;IAEUC,qBAA2B;QACnC,IAAI,CAACF,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,CAAC;IACvC;IAEUE,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,KAAK,MAAMC,YAAYF,OAAQ;YAC7B,MAAMG,SAASF,WAAWG,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEf,WAAW,EAAEC,IAAI,EAAE,GAAGc;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErC,IAAI,CAACN,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,EAAET,YAAY,CAAC,EAAEC,KAAK,gBAAgB,CAAC;gBAE3E,IAAIgB,UAAU;oBACZ,KAAK,MAAME,SAASF,SAAU;wBAC5B,IAAIE,MAAMC,GAAG,CAACC,IAAI,OAAO,IAAI;4BAC3B,IAAI,CAACb,SAAS,CAACC,KAAK,CAAC,CAAC,SAAS,EAAEU,MAAMC,GAAG,CAAC,EAAE,CAAC;wBAChD;oBACF;gBACF;YACF;QACF;IACF;AACF"}
|
package/lib/GroupedReporter.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export declare abstract class GroupedReporter implements Reporter {
|
|
|
29
29
|
protected options: {
|
|
30
30
|
logLevel?: LogLevel;
|
|
31
31
|
grouped?: boolean;
|
|
32
|
+
/** Whether to capture and report main process memory usage on target completion */
|
|
33
|
+
logMemory?: boolean;
|
|
32
34
|
/** stream for testing */
|
|
33
35
|
logStream?: Writable;
|
|
34
36
|
};
|
|
@@ -38,10 +40,13 @@ export declare abstract class GroupedReporter implements Reporter {
|
|
|
38
40
|
constructor(options: {
|
|
39
41
|
logLevel?: LogLevel;
|
|
40
42
|
grouped?: boolean;
|
|
43
|
+
/** Whether to capture and report main process memory usage on target completion */
|
|
44
|
+
logMemory?: boolean;
|
|
41
45
|
/** stream for testing */
|
|
42
46
|
logStream?: Writable;
|
|
43
47
|
});
|
|
44
48
|
log(entry: LogEntry<any>): boolean | void;
|
|
49
|
+
private formatMemory;
|
|
45
50
|
protected logTargetEntry(entry: LogEntry<TargetLogData>): boolean | void;
|
|
46
51
|
private logTargetEntryByGroup;
|
|
47
52
|
summarize(schedulerRunSummary: SchedulerRunSummary): void;
|
package/lib/GroupedReporter.js
CHANGED
|
@@ -25,11 +25,12 @@ _export(exports, {
|
|
|
25
25
|
return logLevelLabel;
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
|
-
const
|
|
28
|
+
const _formatDuration = require("./formatDuration.js");
|
|
29
29
|
const _isTargetStatusLogEntry = require("./isTargetStatusLogEntry.js");
|
|
30
30
|
const _logger = require("@lage-run/logger");
|
|
31
31
|
const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
32
32
|
const _slowestTargetRuns = require("./slowestTargetRuns.js");
|
|
33
|
+
const _formatBytes = require("./formatBytes.js");
|
|
33
34
|
function _define_property(obj, key, value) {
|
|
34
35
|
if (key in obj) {
|
|
35
36
|
Object.defineProperty(obj, key, {
|
|
@@ -103,23 +104,30 @@ class GroupedReporter {
|
|
|
103
104
|
return this.logTargetEntry(entry);
|
|
104
105
|
}
|
|
105
106
|
}
|
|
107
|
+
formatMemory(memoryUsage) {
|
|
108
|
+
if (!this.options.logMemory || !memoryUsage) {
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
return ` [rss: ${(0, _formatBytes.formatBytes)(memoryUsage.rss)}, heap: ${(0, _formatBytes.formatBytes)(memoryUsage.heapUsed)}]`;
|
|
112
|
+
}
|
|
106
113
|
logTargetEntry(entry) {
|
|
107
114
|
const colorFn = colors[entry.level];
|
|
108
115
|
const data = entry.data;
|
|
109
116
|
if ((0, _isTargetStatusLogEntry.isTargetStatusLogEntry)(data)) {
|
|
110
|
-
const { target, hash, duration } = data;
|
|
117
|
+
const { target, hash, duration, memoryUsage } = data;
|
|
111
118
|
const { packageName, task } = target;
|
|
119
|
+
const mem = this.formatMemory(memoryUsage);
|
|
112
120
|
const normalizedArgs = this.options.grouped ? normalize(entry.msg) : normalize(getTaskLogPrefix(packageName ?? "<root>", task), entry.msg);
|
|
113
121
|
const pkgTask = this.options.grouped ? `${_chalk.default.magenta(packageName)} ${_chalk.default.cyan(task)}` : "";
|
|
114
122
|
switch(data.status){
|
|
115
123
|
case "running":
|
|
116
124
|
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("➔")} start ${pkgTask}`)));
|
|
117
125
|
case "success":
|
|
118
|
-
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("✓")} done ${pkgTask} - ${(0,
|
|
126
|
+
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("✓")} done ${pkgTask} - ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))}${mem}`)));
|
|
119
127
|
case "failed":
|
|
120
|
-
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.error("✖")} fail ${pkgTask}`)));
|
|
128
|
+
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.error("✖")} fail ${pkgTask}${mem}`)));
|
|
121
129
|
case "skipped":
|
|
122
|
-
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("»")} skip ${pkgTask} - ${hash}`)));
|
|
130
|
+
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("»")} skip ${pkgTask} - ${hash}${mem}`)));
|
|
123
131
|
case "aborted":
|
|
124
132
|
return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn("-")} aborted ${pkgTask}`)));
|
|
125
133
|
case "queued":
|
|
@@ -172,7 +180,7 @@ class GroupedReporter {
|
|
|
172
180
|
for (const wrappedTarget of slowestTargets){
|
|
173
181
|
const colorFn = statusColorFn[wrappedTarget.status];
|
|
174
182
|
const target = wrappedTarget.target;
|
|
175
|
-
this.logStream.write(format(_logger.LogLevel.info, getTaskLogPrefix(target.packageName || "[GLOBAL]", target.task), colorFn(`${wrappedTarget.status}${wrappedTarget.duration ? `, took ${(0,
|
|
183
|
+
this.logStream.write(format(_logger.LogLevel.info, getTaskLogPrefix(target.packageName || "[GLOBAL]", target.task), colorFn(`${wrappedTarget.status}${wrappedTarget.duration ? `, took ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(wrappedTarget.duration))}` : ""}`)));
|
|
176
184
|
}
|
|
177
185
|
this.logStream.write(`[Tasks Count] success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}\n`);
|
|
178
186
|
} else {
|
|
@@ -182,7 +190,7 @@ class GroupedReporter {
|
|
|
182
190
|
if (failed && failed.length > 0) {
|
|
183
191
|
this.writeFailures(failed, targetRuns);
|
|
184
192
|
}
|
|
185
|
-
this.logStream.write(format(_logger.LogLevel.info, "", `Took a total of ${(0,
|
|
193
|
+
this.logStream.write(format(_logger.LogLevel.info, "", `Took a total of ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))} to complete`));
|
|
186
194
|
}
|
|
187
195
|
constructor(options){
|
|
188
196
|
_define_property(this, "options", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/GroupedReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport { isTargetStatusLogEntry } from \"./isTargetStatusLogEntry.js\";\nimport { LogLevel, type LogStructuredData } from \"@lage-run/logger\";\nimport chalk from \"chalk\";\nimport type { Reporter, LogEntry } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { TargetLogData, TargetStatusData } from \"./types/TargetLogData.js\";\nimport type { Writable } from \"stream\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\n\nexport const colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.white,\n [LogLevel.silly]: chalk.green,\n task: chalk.cyan,\n pkg: chalk.magenta,\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\nexport const logLevelLabel = {\n [LogLevel.info]: \"INFO\",\n [LogLevel.warn]: \"WARN\",\n [LogLevel.error]: \"ERR!\",\n [LogLevel.silly]: \"SILLY\",\n [LogLevel.verbose]: \"VERB\",\n};\n\nexport function getTaskLogPrefix(pkg: string, task: string): string {\n return `${colors.pkg(pkg)} ${colors.task(task)}`;\n}\n\nfunction normalize(prefixOrMessage: string, message?: string) {\n if (typeof message === \"string\") {\n return { prefix: prefixOrMessage, message };\n }\n return { prefix: \"\", message: prefixOrMessage };\n}\n\nexport function format(level: LogLevel, prefix: string, message: string): string {\n return `${logLevelLabel[level]}: ${prefix} ${message}\\n`;\n}\n\nexport abstract class GroupedReporter implements Reporter {\n protected logStream: Writable;\n protected logEntries = new Map<string, LogEntry[]>();\n private readonly groupedEntries: Map<string, LogEntry<LogStructuredData>[]> = new Map<string, LogEntry[]>();\n\n constructor(\n protected options: {\n logLevel?: LogLevel;\n grouped?: boolean;\n /** stream for testing */\n logStream?: Writable;\n }\n ) {\n options.logLevel = options.logLevel || LogLevel.info;\n this.logStream = options.logStream || process.stdout;\n }\n\n public log(entry: LogEntry<any>): boolean | void {\n if (entry.data && entry.data.target && entry.data.target.hidden) {\n return;\n }\n\n if (entry.data && entry.data.target) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n if (this.options.logLevel! >= entry.level) {\n if (this.options.grouped && entry.data?.target) {\n return this.logTargetEntryByGroup(entry);\n }\n\n return this.logTargetEntry(entry);\n }\n }\n\n protected logTargetEntry(entry: LogEntry<TargetLogData>): boolean | void {\n const colorFn = colors[entry.level];\n const data = entry.data!;\n\n if (isTargetStatusLogEntry(data)) {\n const { target, hash, duration } = data;\n const { packageName, task } = target;\n\n const normalizedArgs = this.options.grouped\n ? normalize(entry.msg)\n : normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), entry.msg);\n\n const pkgTask = this.options.grouped ? `${chalk.magenta(packageName)} ${chalk.cyan(task)}` : \"\";\n\n switch (data.status) {\n case \"running\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok(\"➔\")} start ${pkgTask}`)));\n\n case \"success\":\n return this.logStream.write(\n format(\n entry.level,\n normalizedArgs.prefix,\n colorFn(`${colors.ok(\"✓\")} done ${pkgTask} - ${formatDuration(hrToSeconds(duration!))}`)\n )\n );\n\n case \"failed\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.error(\"✖\")} fail ${pkgTask}`)));\n\n case \"skipped\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok(\"»\")} skip ${pkgTask} - ${hash!}`)));\n\n case \"aborted\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn(\"-\")} aborted ${pkgTask}`)));\n\n case \"queued\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn(\"…\")} queued ${pkgTask}`)));\n }\n } else if (entry?.data?.target) {\n const { target } = data;\n const { packageName, task } = target;\n const normalizedArgs = this.options.grouped\n ? normalize(entry.msg)\n : normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), entry.msg);\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(\"| \" + normalizedArgs.message)));\n } else if (entry?.msg.trim() !== \"\") {\n return this.logStream.write(format(entry.level, \"\", entry.msg));\n }\n }\n\n private logTargetEntryByGroup(entry: LogEntry<TargetLogData>) {\n const data = entry.data!;\n\n const target = data.target;\n const { id } = target;\n\n this.groupedEntries.set(id, this.groupedEntries.get(id) || []);\n this.groupedEntries.get(id)?.push(entry);\n\n if (isTargetStatusLogEntry(data)) {\n if (data.status === \"success\" || data.status === \"failed\" || data.status === \"skipped\" || data.status === \"aborted\") {\n const { status, duration } = data;\n this.logStream.write(this.formatGroupStart(data.target.packageName ?? \"<root>\", data.target.task, status, duration));\n\n const entries = this.groupedEntries.get(id)! as LogEntry<TargetStatusData>[];\n for (const targetEntry of entries) {\n this.logTargetEntry(targetEntry);\n }\n\n this.logStream.write(this.formatGroupEnd());\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n const statusColorFn: { [status in TargetStatus]: chalk.Chalk } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n this.writeSummaryHeader();\n\n if (targetRuns.size > 0) {\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n const colorFn = statusColorFn[wrappedTarget.status];\n const target = wrappedTarget.target;\n\n this.logStream.write(\n format(\n LogLevel.info,\n getTaskLogPrefix(target.packageName || \"[GLOBAL]\", target.task),\n colorFn(\n `${wrappedTarget.status}${wrappedTarget.duration ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}` : \"\"}`\n )\n )\n );\n }\n\n this.logStream.write(\n `[Tasks Count] success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}\\n`\n );\n } else {\n this.logStream.write(\"Nothing has been run.\\n\");\n }\n\n this.writeSummaryFooter();\n\n if (failed && failed.length > 0) {\n this.writeFailures(failed, targetRuns);\n }\n\n this.logStream.write(format(LogLevel.info, \"\", `Took a total of ${formatDuration(hrToSeconds(duration))} to complete`));\n }\n\n /** Returns the opening line for a grouped target log block, including trailing newline. */\n protected abstract formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string;\n\n /** Returns the closing line for a grouped target log block, including trailing newline. */\n protected abstract formatGroupEnd(): string;\n\n /** Writes the summary section header. */\n protected abstract writeSummaryHeader(): void;\n\n /** Writes anything needed after the summary target list (e.g. closing a group). */\n protected abstract writeSummaryFooter(): void;\n\n /** Writes per-CI-system error annotations for all failed targets. */\n protected abstract writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void;\n}\n"],"names":["GroupedReporter","colors","format","getTaskLogPrefix","logLevelLabel","LogLevel","info","chalk","white","verbose","gray","warn","error","silly","green","task","cyan","pkg","magenta","ok","red","yellow","normalize","prefixOrMessage","message","prefix","level","log","entry","data","target","hidden","logEntries","has","id","set","get","push","options","logLevel","grouped","logTargetEntryByGroup","logTargetEntry","colorFn","isTargetStatusLogEntry","hash","duration","packageName","normalizedArgs","msg","pkgTask","status","logStream","write","formatDuration","hrToSeconds","trim","groupedEntries","formatGroupStart","entries","targetEntry","formatGroupEnd","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","failed","aborted","skipped","success","pending","statusColorFn","greenBright","redBright","running","queued","writeSummaryHeader","size","slowestTargets","slowestTargetRuns","values","wrappedTarget","length","writeSummaryFooter","writeFailures","Map","process","stdout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/GroupedReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"./formatDuration.js\";\nimport { isTargetStatusLogEntry } from \"./isTargetStatusLogEntry.js\";\nimport { LogLevel, type LogStructuredData } from \"@lage-run/logger\";\nimport chalk from \"chalk\";\nimport type { Reporter, LogEntry } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { TargetLogData, TargetStatusData } from \"./types/TargetLogData.js\";\nimport type { Writable } from \"stream\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\nimport { formatBytes } from \"./formatBytes.js\";\n\nexport const colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.white,\n [LogLevel.silly]: chalk.green,\n task: chalk.cyan,\n pkg: chalk.magenta,\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\nexport const logLevelLabel = {\n [LogLevel.info]: \"INFO\",\n [LogLevel.warn]: \"WARN\",\n [LogLevel.error]: \"ERR!\",\n [LogLevel.silly]: \"SILLY\",\n [LogLevel.verbose]: \"VERB\",\n};\n\nexport function getTaskLogPrefix(pkg: string, task: string): string {\n return `${colors.pkg(pkg)} ${colors.task(task)}`;\n}\n\nfunction normalize(prefixOrMessage: string, message?: string) {\n if (typeof message === \"string\") {\n return { prefix: prefixOrMessage, message };\n }\n return { prefix: \"\", message: prefixOrMessage };\n}\n\nexport function format(level: LogLevel, prefix: string, message: string): string {\n return `${logLevelLabel[level]}: ${prefix} ${message}\\n`;\n}\n\nexport abstract class GroupedReporter implements Reporter {\n protected logStream: Writable;\n protected logEntries = new Map<string, LogEntry[]>();\n private readonly groupedEntries: Map<string, LogEntry<LogStructuredData>[]> = new Map<string, LogEntry[]>();\n\n constructor(\n protected options: {\n logLevel?: LogLevel;\n grouped?: boolean;\n /** Whether to capture and report main process memory usage on target completion */\n logMemory?: boolean;\n /** stream for testing */\n logStream?: Writable;\n }\n ) {\n options.logLevel = options.logLevel || LogLevel.info;\n this.logStream = options.logStream || process.stdout;\n }\n\n public log(entry: LogEntry<any>): boolean | void {\n if (entry.data && entry.data.target && entry.data.target.hidden) {\n return;\n }\n\n if (entry.data && entry.data.target) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n if (this.options.logLevel! >= entry.level) {\n if (this.options.grouped && entry.data?.target) {\n return this.logTargetEntryByGroup(entry);\n }\n\n return this.logTargetEntry(entry);\n }\n }\n\n private formatMemory(memoryUsage?: NodeJS.MemoryUsage): string {\n if (!this.options.logMemory || !memoryUsage) {\n return \"\";\n }\n return ` [rss: ${formatBytes(memoryUsage.rss)}, heap: ${formatBytes(memoryUsage.heapUsed)}]`;\n }\n\n protected logTargetEntry(entry: LogEntry<TargetLogData>): boolean | void {\n const colorFn = colors[entry.level];\n const data = entry.data!;\n\n if (isTargetStatusLogEntry(data)) {\n const { target, hash, duration, memoryUsage } = data;\n const { packageName, task } = target;\n const mem = this.formatMemory(memoryUsage);\n\n const normalizedArgs = this.options.grouped\n ? normalize(entry.msg)\n : normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), entry.msg);\n\n const pkgTask = this.options.grouped ? `${chalk.magenta(packageName)} ${chalk.cyan(task)}` : \"\";\n\n switch (data.status) {\n case \"running\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok(\"➔\")} start ${pkgTask}`)));\n\n case \"success\":\n return this.logStream.write(\n format(\n entry.level,\n normalizedArgs.prefix,\n colorFn(`${colors.ok(\"✓\")} done ${pkgTask} - ${formatDuration(hrToSeconds(duration!))}${mem}`)\n )\n );\n\n case \"failed\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.error(\"✖\")} fail ${pkgTask}${mem}`)));\n\n case \"skipped\":\n return this.logStream.write(\n format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok(\"»\")} skip ${pkgTask} - ${hash!}${mem}`))\n );\n\n case \"aborted\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn(\"-\")} aborted ${pkgTask}`)));\n\n case \"queued\":\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn(\"…\")} queued ${pkgTask}`)));\n }\n } else if (entry?.data?.target) {\n const { target } = data;\n const { packageName, task } = target;\n const normalizedArgs = this.options.grouped\n ? normalize(entry.msg)\n : normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), entry.msg);\n return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(\"| \" + normalizedArgs.message)));\n } else if (entry?.msg.trim() !== \"\") {\n return this.logStream.write(format(entry.level, \"\", entry.msg));\n }\n }\n\n private logTargetEntryByGroup(entry: LogEntry<TargetLogData>) {\n const data = entry.data!;\n\n const target = data.target;\n const { id } = target;\n\n this.groupedEntries.set(id, this.groupedEntries.get(id) || []);\n this.groupedEntries.get(id)?.push(entry);\n\n if (isTargetStatusLogEntry(data)) {\n if (data.status === \"success\" || data.status === \"failed\" || data.status === \"skipped\" || data.status === \"aborted\") {\n const { status, duration } = data;\n this.logStream.write(this.formatGroupStart(data.target.packageName ?? \"<root>\", data.target.task, status, duration));\n\n const entries = this.groupedEntries.get(id)! as LogEntry<TargetStatusData>[];\n for (const targetEntry of entries) {\n this.logTargetEntry(targetEntry);\n }\n\n this.logStream.write(this.formatGroupEnd());\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n const statusColorFn: { [status in TargetStatus]: chalk.Chalk } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n this.writeSummaryHeader();\n\n if (targetRuns.size > 0) {\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n const colorFn = statusColorFn[wrappedTarget.status];\n const target = wrappedTarget.target;\n\n this.logStream.write(\n format(\n LogLevel.info,\n getTaskLogPrefix(target.packageName || \"[GLOBAL]\", target.task),\n colorFn(\n `${wrappedTarget.status}${wrappedTarget.duration ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}` : \"\"}`\n )\n )\n );\n }\n\n this.logStream.write(\n `[Tasks Count] success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}\\n`\n );\n } else {\n this.logStream.write(\"Nothing has been run.\\n\");\n }\n\n this.writeSummaryFooter();\n\n if (failed && failed.length > 0) {\n this.writeFailures(failed, targetRuns);\n }\n\n this.logStream.write(format(LogLevel.info, \"\", `Took a total of ${formatDuration(hrToSeconds(duration))} to complete`));\n }\n\n /** Returns the opening line for a grouped target log block, including trailing newline. */\n protected abstract formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string;\n\n /** Returns the closing line for a grouped target log block, including trailing newline. */\n protected abstract formatGroupEnd(): string;\n\n /** Writes the summary section header. */\n protected abstract writeSummaryHeader(): void;\n\n /** Writes anything needed after the summary target list (e.g. closing a group). */\n protected abstract writeSummaryFooter(): void;\n\n /** Writes per-CI-system error annotations for all failed targets. */\n protected abstract writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void;\n}\n"],"names":["GroupedReporter","colors","format","getTaskLogPrefix","logLevelLabel","LogLevel","info","chalk","white","verbose","gray","warn","error","silly","green","task","cyan","pkg","magenta","ok","red","yellow","normalize","prefixOrMessage","message","prefix","level","log","entry","data","target","hidden","logEntries","has","id","set","get","push","options","logLevel","grouped","logTargetEntryByGroup","logTargetEntry","formatMemory","memoryUsage","logMemory","formatBytes","rss","heapUsed","colorFn","isTargetStatusLogEntry","hash","duration","packageName","mem","normalizedArgs","msg","pkgTask","status","logStream","write","formatDuration","hrToSeconds","trim","groupedEntries","formatGroupStart","entries","targetEntry","formatGroupEnd","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","failed","aborted","skipped","success","pending","statusColorFn","greenBright","redBright","running","queued","writeSummaryHeader","size","slowestTargets","slowestTargetRuns","values","wrappedTarget","length","writeSummaryFooter","writeFailures","Map","process","stdout"],"mappings":"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"}
|
package/lib/JsonReporter.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class JsonReporter implements Reporter {
|
|
|
24
24
|
constructor(options: {
|
|
25
25
|
logLevel: LogLevel;
|
|
26
26
|
indented: boolean;
|
|
27
|
+
logMemory?: boolean;
|
|
27
28
|
});
|
|
28
29
|
log(entry: LogEntry<TargetLogData>): void;
|
|
29
30
|
summarize(schedulerRunSummary: SchedulerRunSummary): void;
|
package/lib/JsonReporter.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "JsonReporter", {
|
|
|
8
8
|
return JsonReporter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
function _define_property(obj, key, value) {
|
|
13
13
|
if (key in obj) {
|
|
14
14
|
Object.defineProperty(obj, key, {
|
|
@@ -34,13 +34,13 @@ class JsonReporter {
|
|
|
34
34
|
summarize(schedulerRunSummary) {
|
|
35
35
|
const { duration, targetRuns, targetRunByStatus } = schedulerRunSummary;
|
|
36
36
|
const summary = {
|
|
37
|
-
duration: (0,
|
|
37
|
+
duration: (0, _formatDuration.hrToSeconds)(duration),
|
|
38
38
|
taskStats: [
|
|
39
39
|
...targetRuns.values()
|
|
40
40
|
].map((targetRun)=>({
|
|
41
41
|
package: targetRun.target.packageName,
|
|
42
42
|
task: targetRun.target.task,
|
|
43
|
-
duration: (0,
|
|
43
|
+
duration: (0, _formatDuration.hrToSeconds)(targetRun.duration),
|
|
44
44
|
status: targetRun.status
|
|
45
45
|
}))
|
|
46
46
|
};
|
package/lib/JsonReporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/JsonReporter.ts"],"sourcesContent":["/* eslint-disable no-console */\n\nimport { hrToSeconds } from \"
|
|
1
|
+
{"version":3,"sources":["../src/JsonReporter.ts"],"sourcesContent":["/* eslint-disable no-console */\n\nimport { hrToSeconds } from \"./formatDuration.js\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { LogLevel } from \"@lage-run/logger\";\nimport { type LogEntry, type Reporter } from \"@lage-run/logger\";\nimport type { TargetLogData } from \"./types/TargetLogData.js\";\n\ninterface JsonReporterTaskStats {\n package: string | undefined;\n task: string;\n duration: string;\n status: string;\n}\n\n/** Final entry logged by `JsonReporter.summarize()` */\nexport interface JsonReporterSummaryData {\n summary: {\n duration: string;\n taskStats: JsonReporterTaskStats[];\n } & {\n [status in `${TargetStatus}Targets`]?: number;\n };\n}\n\n/** `LogEntry.data` types for the `JsonReporter` */\nexport type JsonReporterLogData = JsonReporterSummaryData | TargetLogData;\n\nexport class JsonReporter implements Reporter {\n constructor(private options: { logLevel: LogLevel; indented: boolean; logMemory?: boolean }) {}\n\n public log(entry: LogEntry<TargetLogData>): void {\n if (entry.data && entry.data.target && entry.data.target.hidden) {\n return;\n }\n\n if (this.options.logLevel >= entry.level) {\n console.log(this.options.indented ? JSON.stringify(entry, null, 2) : JSON.stringify(entry));\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { duration, targetRuns, targetRunByStatus } = schedulerRunSummary;\n\n const summary: JsonReporterSummaryData[\"summary\"] = {\n duration: hrToSeconds(duration),\n taskStats: [...targetRuns.values()].map((targetRun) => ({\n package: targetRun.target.packageName,\n task: targetRun.target.task,\n duration: hrToSeconds(targetRun.duration),\n status: targetRun.status,\n })),\n };\n\n for (const status of Object.keys(targetRunByStatus) as TargetStatus[]) {\n if (targetRunByStatus[status] && targetRunByStatus[status].length) {\n summary[`${status}Targets`] = targetRunByStatus[status].length;\n }\n }\n\n console.log(JSON.stringify({ summary }));\n }\n}\n"],"names":["JsonReporter","log","entry","data","target","hidden","options","logLevel","level","console","indented","JSON","stringify","summarize","schedulerRunSummary","duration","targetRuns","targetRunByStatus","summary","hrToSeconds","taskStats","values","map","targetRun","package","packageName","task","status","Object","keys","length"],"mappings":"AAAA,6BAA6B;;;;+BA4BhBA;;;eAAAA;;;gCA1Be;;;;;;;;;;;;;;AA0BrB,MAAMA;IAGJC,IAAIC,KAA8B,EAAQ;QAC/C,IAAIA,MAAMC,IAAI,IAAID,MAAMC,IAAI,CAACC,MAAM,IAAIF,MAAMC,IAAI,CAACC,MAAM,CAACC,MAAM,EAAE;YAC/D;QACF;QAEA,IAAI,IAAI,CAACC,OAAO,CAACC,QAAQ,IAAIL,MAAMM,KAAK,EAAE;YACxCC,QAAQR,GAAG,CAAC,IAAI,CAACK,OAAO,CAACI,QAAQ,GAAGC,KAAKC,SAAS,CAACV,OAAO,MAAM,KAAKS,KAAKC,SAAS,CAACV;QACtF;IACF;IAEOW,UAAUC,mBAAwC,EAAQ;QAC/D,MAAM,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,iBAAiB,EAAE,GAAGH;QAEpD,MAAMI,UAA8C;YAClDH,UAAUI,IAAAA,2BAAW,EAACJ;YACtBK,WAAW;mBAAIJ,WAAWK,MAAM;aAAG,CAACC,GAAG,CAAC,CAACC,YAAe,CAAA;oBACtDC,SAASD,UAAUnB,MAAM,CAACqB,WAAW;oBACrCC,MAAMH,UAAUnB,MAAM,CAACsB,IAAI;oBAC3BX,UAAUI,IAAAA,2BAAW,EAACI,UAAUR,QAAQ;oBACxCY,QAAQJ,UAAUI,MAAM;gBAC1B,CAAA;QACF;QAEA,KAAK,MAAMA,UAAUC,OAAOC,IAAI,CAACZ,mBAAsC;YACrE,IAAIA,iBAAiB,CAACU,OAAO,IAAIV,iBAAiB,CAACU,OAAO,CAACG,MAAM,EAAE;gBACjEZ,OAAO,CAAC,GAAGS,OAAO,OAAO,CAAC,CAAC,GAAGV,iBAAiB,CAACU,OAAO,CAACG,MAAM;YAChE;QACF;QAEArB,QAAQR,GAAG,CAACU,KAAKC,SAAS,CAAC;YAAEM;QAAQ;IACvC;IAhCA,YAAY,AAAQZ,OAAuE,CAAE;;aAAzEA,UAAAA;IAA0E;AAiChG"}
|
package/lib/LogReporter.d.ts
CHANGED
|
@@ -9,12 +9,15 @@ export declare class LogReporter implements Reporter {
|
|
|
9
9
|
constructor(options: {
|
|
10
10
|
logLevel?: LogLevel;
|
|
11
11
|
grouped?: boolean;
|
|
12
|
+
/** Whether to capture and report main process memory usage on target completion */
|
|
13
|
+
logMemory?: boolean;
|
|
12
14
|
/** stream for testing */
|
|
13
15
|
logStream?: Writable;
|
|
14
16
|
});
|
|
15
17
|
log(entry: LogEntry<any>): void;
|
|
16
18
|
private printEntry;
|
|
17
19
|
private print;
|
|
20
|
+
private formatMemory;
|
|
18
21
|
private logTargetEntry;
|
|
19
22
|
private logTargetEntryByGroup;
|
|
20
23
|
private hr;
|
package/lib/LogReporter.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "LogReporter", {
|
|
|
8
8
|
return LogReporter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
const _isTargetStatusLogEntry = require("./isTargetStatusLogEntry.js");
|
|
13
13
|
const _logger = require("@lage-run/logger");
|
|
14
14
|
const _ansiregex = /*#__PURE__*/ _interop_require_default(require("ansi-regex"));
|
|
@@ -134,20 +134,27 @@ class LogReporter {
|
|
|
134
134
|
print(message) {
|
|
135
135
|
this.logStream.write(message + "\n");
|
|
136
136
|
}
|
|
137
|
+
formatMemory(memoryUsage) {
|
|
138
|
+
if (!this.options.logMemory || !memoryUsage) {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
return ` [rss: ${(0, _formatBytes.formatBytes)(memoryUsage.rss)}, heap: ${(0, _formatBytes.formatBytes)(memoryUsage.heapUsed)}]`;
|
|
142
|
+
}
|
|
137
143
|
logTargetEntry(entry) {
|
|
138
144
|
const colorFn = colors[entry.level];
|
|
139
145
|
const data = entry.data;
|
|
140
146
|
if ((0, _isTargetStatusLogEntry.isTargetStatusLogEntry)(data)) {
|
|
141
|
-
const { hash, duration } = data;
|
|
147
|
+
const { hash, duration, memoryUsage } = data;
|
|
148
|
+
const mem = this.formatMemory(memoryUsage);
|
|
142
149
|
switch(data.status){
|
|
143
150
|
case "running":
|
|
144
151
|
return this.printEntry(entry, colorFn(`${colors.ok("➔")} start`));
|
|
145
152
|
case "success":
|
|
146
|
-
return this.printEntry(entry, colorFn(`${colors.ok("✓")} done - ${(0,
|
|
153
|
+
return this.printEntry(entry, colorFn(`${colors.ok("✓")} done - ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))}${mem}`));
|
|
147
154
|
case "failed":
|
|
148
|
-
return this.printEntry(entry, colorFn(`${colors.error("✖")} fail`));
|
|
155
|
+
return this.printEntry(entry, colorFn(`${colors.error("✖")} fail${mem}`));
|
|
149
156
|
case "skipped":
|
|
150
|
-
return this.printEntry(entry, colorFn(`${colors.ok("»")} skip - ${hash}`));
|
|
157
|
+
return this.printEntry(entry, colorFn(`${colors.ok("»")} skip - ${hash}${mem}`));
|
|
151
158
|
case "aborted":
|
|
152
159
|
return this.printEntry(entry, colorFn(`${colors.warn("-")} aborted`));
|
|
153
160
|
case "queued":
|
|
@@ -199,11 +206,11 @@ class LogReporter {
|
|
|
199
206
|
const colorFn = statusColorFn[wrappedTarget.status] ?? _chalk.default.white;
|
|
200
207
|
const target = wrappedTarget.target;
|
|
201
208
|
const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;
|
|
202
|
-
const queueDuration = hasDurations ? (0,
|
|
209
|
+
const queueDuration = hasDurations ? (0, _formatDuration.hrtimeDiff)(wrappedTarget.queueTime, wrappedTarget.startTime) : [
|
|
203
210
|
0,
|
|
204
211
|
0
|
|
205
212
|
];
|
|
206
|
-
this.print(`${getTaskLogPrefix(target.packageName || "<root>", target.task)} ${colorFn(`${wrappedTarget.status === "running" ? "running - incomplete" : wrappedTarget.status}${hasDurations ? `, took ${(0,
|
|
213
|
+
this.print(`${getTaskLogPrefix(target.packageName || "<root>", target.task)} ${colorFn(`${wrappedTarget.status === "running" ? "running - incomplete" : wrappedTarget.status}${hasDurations ? `, took ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(wrappedTarget.duration))}, queued for ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(queueDuration))}` : ""}`)}`);
|
|
207
214
|
}
|
|
208
215
|
this.print(`success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`);
|
|
209
216
|
this.print(`worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${(0, _formatBytes.formatBytes)(schedulerRunSummary.maxWorkerMemoryUsage)}`);
|
|
@@ -236,7 +243,7 @@ class LogReporter {
|
|
|
236
243
|
g: 178,
|
|
237
244
|
b: 77
|
|
238
245
|
}, "cyan")(`All targets skipped!`) : "";
|
|
239
|
-
this.print(`Took a total of ${(0,
|
|
246
|
+
this.print(`Took a total of ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))} to complete. ${allCacheHitText}`);
|
|
240
247
|
}
|
|
241
248
|
resetLogEntries() {
|
|
242
249
|
this.logEntries.clear();
|
package/lib/LogReporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LogReporter.ts"],"sourcesContent":["import { formatDuration, hrtimeDiff, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport { isTargetStatusLogEntry } from \"./isTargetStatusLogEntry.js\";\nimport { LogLevel } from \"@lage-run/logger\";\nimport ansiRegex from \"ansi-regex\";\nimport chalk from \"chalk\";\nimport type { Chalk } from \"chalk\";\nimport { gradient } from \"./gradient.js\";\nimport type { Reporter, LogEntry } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { TargetLogData, TargetStatusData } from \"./types/TargetLogData.js\";\nimport type { Writable } from \"stream\";\nimport crypto from \"crypto\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\n\nconst colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.hex(\"#FF1010\"),\n [LogLevel.silly]: chalk.green,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\n// Monokai color scheme\nconst pkgColors: Chalk[] = [\n chalk.hex(\"#e5b567\"),\n chalk.hex(\"#b4d273\"),\n chalk.hex(\"#e87d3e\"),\n chalk.hex(\"#9e86c8\"),\n chalk.hex(\"#b05279\"),\n chalk.hex(\"#6c99bb\"),\n];\n\nfunction hashStringToNumber(str: string): number {\n const hash = crypto.createHash(\"md5\");\n hash.update(str);\n const hex = hash.digest(\"hex\").substring(0, 6);\n return parseInt(hex, 16);\n}\n\nconst pkgNameToIndexInPkgColorArray = new Map<string, number>();\n\nfunction getColorForPkg(pkg: string): Chalk {\n if (!pkgNameToIndexInPkgColorArray.has(pkg)) {\n const index = hashStringToNumber(pkg) % pkgColors.length;\n pkgNameToIndexInPkgColorArray.set(pkg, index);\n }\n\n return pkgColors[pkgNameToIndexInPkgColorArray.get(pkg)!];\n}\n\nconst stripAnsiRegex = ansiRegex();\n\nfunction getTaskLogPrefix(pkg: string, task: string) {\n const pkgColor = getColorForPkg(pkg);\n return `${pkgColor(pkg)} ${colors.task(task)}`;\n}\n\nfunction stripAnsi(message: string) {\n return message.replace(stripAnsiRegex, \"\");\n}\n\nfunction normalize(prefixOrMessage: string, message?: string) {\n if (typeof message === \"string\") {\n return { prefix: prefixOrMessage, message };\n }\n return { prefix: \"\", message: prefixOrMessage };\n}\n\nexport class LogReporter implements Reporter {\n private logStream: Writable;\n private logEntries = new Map<string, LogEntry[]>();\n\n constructor(\n private options: {\n logLevel?: LogLevel;\n grouped?: boolean;\n /** stream for testing */\n logStream?: Writable;\n }\n ) {\n options.logLevel = options.logLevel || LogLevel.info;\n this.logStream = options.logStream || process.stdout;\n }\n\n public log(entry: LogEntry<any>): void {\n // if \"hidden\", do not even attempt to record or report the entry\n if (entry?.data?.target?.hidden) {\n return;\n }\n\n // save the logs for errors\n if (entry.data?.target?.id) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n // if loglevel is not high enough, do not report the entry\n if (this.options.logLevel! < entry.level) {\n return;\n }\n\n // log to grouped entries\n if (this.options.grouped && entry.data?.target) {\n return this.logTargetEntryByGroup(entry);\n }\n\n // log normal target entries\n if (entry.data && entry.data.target) {\n return this.logTargetEntry(entry);\n }\n\n // log generic entries (not related to target)\n if (entry.msg) {\n return this.print(entry.msg);\n }\n }\n\n private printEntry(entry: LogEntry<any>, message: string) {\n let prefix = \"\";\n let msg = message;\n\n if (entry?.data?.target) {\n const { packageName, task } = entry.data.target;\n const normalizedArgs = normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), msg);\n prefix = normalizedArgs.prefix;\n msg = normalizedArgs.message;\n }\n\n this.print(`${prefix ? prefix + \" \" : \"\"}${msg}`);\n }\n\n private print(message: string) {\n this.logStream.write(message + \"\\n\");\n }\n\n private logTargetEntry(entry: LogEntry<TargetLogData>) {\n const colorFn = colors[entry.level];\n const data = entry.data!;\n\n if (isTargetStatusLogEntry(data)) {\n const { hash, duration } = data;\n switch (data.status) {\n case \"running\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"➔\")} start`));\n\n case \"success\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"✓\")} done - ${formatDuration(hrToSeconds(duration!))}`));\n\n case \"failed\":\n return this.printEntry(entry, colorFn(`${colors.error(\"✖\")} fail`));\n\n case \"skipped\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"»\")} skip - ${hash!}`));\n\n case \"aborted\":\n return this.printEntry(entry, colorFn(`${colors.warn(\"-\")} aborted`));\n\n case \"queued\":\n return this.printEntry(entry, colorFn(`${colors.warn(\"…\")} queued`));\n }\n } else {\n return this.printEntry(entry, colorFn(\": \" + stripAnsi(entry.msg)));\n }\n }\n\n private logTargetEntryByGroup(entry: LogEntry<TargetLogData>) {\n const data = entry.data!;\n\n const target = data.target;\n const { id } = target;\n\n if (\n isTargetStatusLogEntry(data) &&\n (data.status === \"success\" || data.status === \"failed\" || data.status === \"skipped\" || data.status === \"aborted\")\n ) {\n const entries = this.logEntries.get(id)! as LogEntry<TargetStatusData>[];\n\n for (const targetEntry of entries) {\n this.logTargetEntry(targetEntry);\n }\n\n if (entries.length > 2) {\n this.hr();\n }\n }\n }\n\n private hr(): void {\n this.print(\"┈\".repeat(80));\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n const statusColorFn: {\n [status in TargetStatus]: chalk.Chalk;\n } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n if (targetRuns.size > 0) {\n this.print(chalk.cyanBright(`\\nSummary`));\n\n this.hr();\n\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n if (wrappedTarget.target.hidden) {\n continue;\n }\n\n const colorFn = statusColorFn[wrappedTarget.status] ?? chalk.white;\n const target = wrappedTarget.target;\n const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;\n const queueDuration: [number, number] = hasDurations ? hrtimeDiff(wrappedTarget.queueTime, wrappedTarget.startTime) : [0, 0];\n\n this.print(\n `${getTaskLogPrefix(target.packageName || \"<root>\", target.task)} ${colorFn(\n `${wrappedTarget.status === \"running\" ? \"running - incomplete\" : wrappedTarget.status}${\n hasDurations\n ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}, queued for ${formatDuration(hrToSeconds(queueDuration))}`\n : \"\"\n }`\n )}`\n );\n }\n\n this.print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n\n this.print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(\n schedulerRunSummary.maxWorkerMemoryUsage\n )}`\n );\n } else {\n this.print(\"Nothing has been run.\");\n }\n\n this.hr();\n\n if (failed && failed.length > 0) {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const failureLogs = this.logEntries.get(targetId);\n\n this.print(`[${colors.pkg(packageName ?? \"<root>\")} ${colors.task(task)}] ${colors[LogLevel.error](\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n // Log each entry separately to prevent truncation\n this.print(entry.msg);\n }\n }\n\n this.hr();\n }\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(`All targets skipped!`) : \"\";\n\n this.print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n\n public resetLogEntries(): void {\n this.logEntries.clear();\n }\n}\n"],"names":["LogReporter","colors","LogLevel","info","chalk","white","verbose","gray","warn","error","hex","silly","green","task","pkg","ok","red","yellow","pkgColors","hashStringToNumber","str","hash","crypto","createHash","update","digest","substring","parseInt","pkgNameToIndexInPkgColorArray","Map","getColorForPkg","has","index","length","set","get","stripAnsiRegex","ansiRegex","getTaskLogPrefix","pkgColor","stripAnsi","message","replace","normalize","prefixOrMessage","prefix","log","entry","data","target","hidden","id","logEntries","push","options","logLevel","level","grouped","logTargetEntryByGroup","logTargetEntry","msg","print","printEntry","packageName","normalizedArgs","logStream","write","colorFn","isTargetStatusLogEntry","duration","status","formatDuration","hrToSeconds","entries","targetEntry","hr","repeat","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","failed","aborted","skipped","success","pending","statusColorFn","greenBright","redBright","running","queued","magenta","size","cyanBright","slowestTargets","slowestTargetRuns","values","wrappedTarget","hasDurations","queueTime","queueDuration","hrtimeDiff","startTime","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","failureLogs","allCacheHits","filter","run","allCacheHitText","gradient","r","g","b","resetLogEntries","clear","process","stdout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/LogReporter.ts"],"sourcesContent":["import { formatDuration, hrtimeDiff, hrToSeconds } from \"./formatDuration.js\";\nimport { isTargetStatusLogEntry } from \"./isTargetStatusLogEntry.js\";\nimport { LogLevel } from \"@lage-run/logger\";\nimport ansiRegex from \"ansi-regex\";\nimport chalk from \"chalk\";\nimport type { Chalk } from \"chalk\";\nimport { gradient } from \"./gradient.js\";\nimport type { Reporter, LogEntry } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { TargetLogData, TargetStatusData } from \"./types/TargetLogData.js\";\nimport type { Writable } from \"stream\";\nimport crypto from \"crypto\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\n\nconst colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.hex(\"#FF1010\"),\n [LogLevel.silly]: chalk.green,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\n// Monokai color scheme\nconst pkgColors: Chalk[] = [\n chalk.hex(\"#e5b567\"),\n chalk.hex(\"#b4d273\"),\n chalk.hex(\"#e87d3e\"),\n chalk.hex(\"#9e86c8\"),\n chalk.hex(\"#b05279\"),\n chalk.hex(\"#6c99bb\"),\n];\n\nfunction hashStringToNumber(str: string): number {\n const hash = crypto.createHash(\"md5\");\n hash.update(str);\n const hex = hash.digest(\"hex\").substring(0, 6);\n return parseInt(hex, 16);\n}\n\nconst pkgNameToIndexInPkgColorArray = new Map<string, number>();\n\nfunction getColorForPkg(pkg: string): Chalk {\n if (!pkgNameToIndexInPkgColorArray.has(pkg)) {\n const index = hashStringToNumber(pkg) % pkgColors.length;\n pkgNameToIndexInPkgColorArray.set(pkg, index);\n }\n\n return pkgColors[pkgNameToIndexInPkgColorArray.get(pkg)!];\n}\n\nconst stripAnsiRegex = ansiRegex();\n\nfunction getTaskLogPrefix(pkg: string, task: string) {\n const pkgColor = getColorForPkg(pkg);\n return `${pkgColor(pkg)} ${colors.task(task)}`;\n}\n\nfunction stripAnsi(message: string) {\n return message.replace(stripAnsiRegex, \"\");\n}\n\nfunction normalize(prefixOrMessage: string, message?: string) {\n if (typeof message === \"string\") {\n return { prefix: prefixOrMessage, message };\n }\n return { prefix: \"\", message: prefixOrMessage };\n}\n\nexport class LogReporter implements Reporter {\n private logStream: Writable;\n private logEntries = new Map<string, LogEntry[]>();\n\n constructor(\n private options: {\n logLevel?: LogLevel;\n grouped?: boolean;\n /** Whether to capture and report main process memory usage on target completion */\n logMemory?: boolean;\n /** stream for testing */\n logStream?: Writable;\n }\n ) {\n options.logLevel = options.logLevel || LogLevel.info;\n this.logStream = options.logStream || process.stdout;\n }\n\n public log(entry: LogEntry<any>): void {\n // if \"hidden\", do not even attempt to record or report the entry\n if (entry?.data?.target?.hidden) {\n return;\n }\n\n // save the logs for errors\n if (entry.data?.target?.id) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n // if loglevel is not high enough, do not report the entry\n if (this.options.logLevel! < entry.level) {\n return;\n }\n\n // log to grouped entries\n if (this.options.grouped && entry.data?.target) {\n return this.logTargetEntryByGroup(entry);\n }\n\n // log normal target entries\n if (entry.data && entry.data.target) {\n return this.logTargetEntry(entry);\n }\n\n // log generic entries (not related to target)\n if (entry.msg) {\n return this.print(entry.msg);\n }\n }\n\n private printEntry(entry: LogEntry<any>, message: string) {\n let prefix = \"\";\n let msg = message;\n\n if (entry?.data?.target) {\n const { packageName, task } = entry.data.target;\n const normalizedArgs = normalize(getTaskLogPrefix(packageName ?? \"<root>\", task), msg);\n prefix = normalizedArgs.prefix;\n msg = normalizedArgs.message;\n }\n\n this.print(`${prefix ? prefix + \" \" : \"\"}${msg}`);\n }\n\n private print(message: string) {\n this.logStream.write(message + \"\\n\");\n }\n\n private formatMemory(memoryUsage?: NodeJS.MemoryUsage): string {\n if (!this.options.logMemory || !memoryUsage) {\n return \"\";\n }\n return ` [rss: ${formatBytes(memoryUsage.rss)}, heap: ${formatBytes(memoryUsage.heapUsed)}]`;\n }\n\n private logTargetEntry(entry: LogEntry<TargetLogData>) {\n const colorFn = colors[entry.level];\n const data = entry.data!;\n\n if (isTargetStatusLogEntry(data)) {\n const { hash, duration, memoryUsage } = data;\n const mem = this.formatMemory(memoryUsage);\n\n switch (data.status) {\n case \"running\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"➔\")} start`));\n\n case \"success\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"✓\")} done - ${formatDuration(hrToSeconds(duration!))}${mem}`));\n\n case \"failed\":\n return this.printEntry(entry, colorFn(`${colors.error(\"✖\")} fail${mem}`));\n\n case \"skipped\":\n return this.printEntry(entry, colorFn(`${colors.ok(\"»\")} skip - ${hash!}${mem}`));\n\n case \"aborted\":\n return this.printEntry(entry, colorFn(`${colors.warn(\"-\")} aborted`));\n\n case \"queued\":\n return this.printEntry(entry, colorFn(`${colors.warn(\"…\")} queued`));\n }\n } else {\n return this.printEntry(entry, colorFn(\": \" + stripAnsi(entry.msg)));\n }\n }\n\n private logTargetEntryByGroup(entry: LogEntry<TargetLogData>) {\n const data = entry.data!;\n\n const target = data.target;\n const { id } = target;\n\n if (\n isTargetStatusLogEntry(data) &&\n (data.status === \"success\" || data.status === \"failed\" || data.status === \"skipped\" || data.status === \"aborted\")\n ) {\n const entries = this.logEntries.get(id)! as LogEntry<TargetStatusData>[];\n\n for (const targetEntry of entries) {\n this.logTargetEntry(targetEntry);\n }\n\n if (entries.length > 2) {\n this.hr();\n }\n }\n }\n\n private hr(): void {\n this.print(\"┈\".repeat(80));\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n const statusColorFn: {\n [status in TargetStatus]: chalk.Chalk;\n } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n if (targetRuns.size > 0) {\n this.print(chalk.cyanBright(`\\nSummary`));\n\n this.hr();\n\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n if (wrappedTarget.target.hidden) {\n continue;\n }\n\n const colorFn = statusColorFn[wrappedTarget.status] ?? chalk.white;\n const target = wrappedTarget.target;\n const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;\n const queueDuration: [number, number] = hasDurations ? hrtimeDiff(wrappedTarget.queueTime, wrappedTarget.startTime) : [0, 0];\n\n this.print(\n `${getTaskLogPrefix(target.packageName || \"<root>\", target.task)} ${colorFn(\n `${wrappedTarget.status === \"running\" ? \"running - incomplete\" : wrappedTarget.status}${\n hasDurations\n ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}, queued for ${formatDuration(hrToSeconds(queueDuration))}`\n : \"\"\n }`\n )}`\n );\n }\n\n this.print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n\n this.print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(\n schedulerRunSummary.maxWorkerMemoryUsage\n )}`\n );\n } else {\n this.print(\"Nothing has been run.\");\n }\n\n this.hr();\n\n if (failed && failed.length > 0) {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const failureLogs = this.logEntries.get(targetId);\n\n this.print(`[${colors.pkg(packageName ?? \"<root>\")} ${colors.task(task)}] ${colors[LogLevel.error](\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n // Log each entry separately to prevent truncation\n this.print(entry.msg);\n }\n }\n\n this.hr();\n }\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(`All targets skipped!`) : \"\";\n\n this.print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n\n public resetLogEntries(): void {\n this.logEntries.clear();\n }\n}\n"],"names":["LogReporter","colors","LogLevel","info","chalk","white","verbose","gray","warn","error","hex","silly","green","task","pkg","ok","red","yellow","pkgColors","hashStringToNumber","str","hash","crypto","createHash","update","digest","substring","parseInt","pkgNameToIndexInPkgColorArray","Map","getColorForPkg","has","index","length","set","get","stripAnsiRegex","ansiRegex","getTaskLogPrefix","pkgColor","stripAnsi","message","replace","normalize","prefixOrMessage","prefix","log","entry","data","target","hidden","id","logEntries","push","options","logLevel","level","grouped","logTargetEntryByGroup","logTargetEntry","msg","print","printEntry","packageName","normalizedArgs","logStream","write","formatMemory","memoryUsage","logMemory","formatBytes","rss","heapUsed","colorFn","isTargetStatusLogEntry","duration","mem","status","formatDuration","hrToSeconds","entries","targetEntry","hr","repeat","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","failed","aborted","skipped","success","pending","statusColorFn","greenBright","redBright","running","queued","magenta","size","cyanBright","slowestTargets","slowestTargetRuns","values","wrappedTarget","hasDurations","queueTime","queueDuration","hrtimeDiff","startTime","workerRestarts","maxWorkerMemoryUsage","targetId","failureLogs","allCacheHits","filter","run","allCacheHitText","gradient","r","g","b","resetLogEntries","clear","process","stdout"],"mappings":"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"}
|
|
@@ -7,9 +7,12 @@ export declare class ProgressReporter implements Reporter {
|
|
|
7
7
|
private logEntries;
|
|
8
8
|
private taskReporter;
|
|
9
9
|
private tasks;
|
|
10
|
+
private logMemory;
|
|
10
11
|
constructor(options?: {
|
|
11
12
|
concurrency: number;
|
|
12
13
|
version: string;
|
|
14
|
+
/** Whether to capture and report main process memory usage on target completion */
|
|
15
|
+
logMemory?: boolean;
|
|
13
16
|
});
|
|
14
17
|
private createTaskReporter;
|
|
15
18
|
log(entry: LogEntry<any>): void;
|
package/lib/ProgressReporter.js
CHANGED
|
@@ -12,7 +12,7 @@ const _logger = require("@lage-run/logger");
|
|
|
12
12
|
const _taskreporter = require("@ms-cloudpack/task-reporter");
|
|
13
13
|
const _gradient = require("./gradient.js");
|
|
14
14
|
const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
15
|
-
const
|
|
15
|
+
const _formatDuration = require("./formatDuration.js");
|
|
16
16
|
const _formatBytes = require("./formatBytes.js");
|
|
17
17
|
const _slowestTargetRuns = require("./slowestTargetRuns.js");
|
|
18
18
|
function _define_property(obj, key, value) {
|
|
@@ -89,13 +89,16 @@ class ProgressReporter {
|
|
|
89
89
|
const reporterTask = this.tasks.has(target.id) ? this.tasks.get(target.id) : this.taskReporter.addTask(target.label, true);
|
|
90
90
|
if (reporterTask) {
|
|
91
91
|
this.tasks.set(target.id, reporterTask);
|
|
92
|
+
const mem = entry.data.memoryUsage;
|
|
93
|
+
const memoryMessage = this.logMemory && mem ? `[rss: ${(0, _formatBytes.formatBytes)(mem.rss)}, heap: ${(0, _formatBytes.formatBytes)(mem.heapUsed)}]` : "";
|
|
92
94
|
switch(status){
|
|
93
95
|
case "running":
|
|
94
96
|
reporterTask.start();
|
|
95
97
|
break;
|
|
96
98
|
case "success":
|
|
97
99
|
reporterTask.complete({
|
|
98
|
-
status: "complete"
|
|
100
|
+
status: "complete",
|
|
101
|
+
message: memoryMessage
|
|
99
102
|
});
|
|
100
103
|
break;
|
|
101
104
|
case "aborted":
|
|
@@ -105,12 +108,14 @@ class ProgressReporter {
|
|
|
105
108
|
break;
|
|
106
109
|
case "skipped":
|
|
107
110
|
reporterTask.complete({
|
|
108
|
-
status: "skip"
|
|
111
|
+
status: "skip",
|
|
112
|
+
message: memoryMessage
|
|
109
113
|
});
|
|
110
114
|
break;
|
|
111
115
|
case "failed":
|
|
112
116
|
reporterTask.complete({
|
|
113
|
-
status: "fail"
|
|
117
|
+
status: "fail",
|
|
118
|
+
message: memoryMessage
|
|
114
119
|
});
|
|
115
120
|
break;
|
|
116
121
|
}
|
|
@@ -157,7 +162,7 @@ class ProgressReporter {
|
|
|
157
162
|
const colorFn = statusColorFn[wrappedTarget.status] ?? _chalk.default.white;
|
|
158
163
|
const target = wrappedTarget.target;
|
|
159
164
|
const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;
|
|
160
|
-
const queueDuration = hasDurations ? (0,
|
|
165
|
+
const queueDuration = hasDurations ? (0, _formatDuration.hrtimeDiff)(wrappedTarget.queueTime, wrappedTarget.startTime) : [
|
|
161
166
|
0,
|
|
162
167
|
0
|
|
163
168
|
];
|
|
@@ -169,7 +174,7 @@ class ProgressReporter {
|
|
|
169
174
|
});
|
|
170
175
|
}
|
|
171
176
|
}
|
|
172
|
-
this.print(`${target.label} ${colorFn(`${wrappedTarget.status === "running" ? "running - incomplete" : wrappedTarget.status}${hasDurations ? `, took ${(0,
|
|
177
|
+
this.print(`${target.label} ${colorFn(`${wrappedTarget.status === "running" ? "running - incomplete" : wrappedTarget.status}${hasDurations ? `, took ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(wrappedTarget.duration))}, queued for ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(queueDuration))}` : ""}`)}`);
|
|
173
178
|
}
|
|
174
179
|
this.print(`success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`);
|
|
175
180
|
this.print(`worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${(0, _formatBytes.formatBytes)(schedulerRunSummary.maxWorkerMemoryUsage)}`);
|
|
@@ -198,7 +203,7 @@ class ProgressReporter {
|
|
|
198
203
|
...targetRuns.values()
|
|
199
204
|
].filter((run)=>!run.target.hidden).length === skipped.length;
|
|
200
205
|
const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : "";
|
|
201
|
-
this.print(`Took a total of ${(0,
|
|
206
|
+
this.print(`Took a total of ${(0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))} to complete. ${allCacheHitText}`);
|
|
202
207
|
}
|
|
203
208
|
constructor(options = {
|
|
204
209
|
concurrency: 0,
|
|
@@ -209,10 +214,12 @@ class ProgressReporter {
|
|
|
209
214
|
_define_property(this, "logEntries", void 0);
|
|
210
215
|
_define_property(this, "taskReporter", void 0);
|
|
211
216
|
_define_property(this, "tasks", void 0);
|
|
217
|
+
_define_property(this, "logMemory", void 0);
|
|
212
218
|
this.options = options;
|
|
213
219
|
this.logStream = process.stdout;
|
|
214
220
|
this.logEntries = new Map();
|
|
215
221
|
this.tasks = new Map();
|
|
222
|
+
this.logMemory = !!options.logMemory;
|
|
216
223
|
this.taskReporter = this.createTaskReporter();
|
|
217
224
|
this.print(`${fancy("lage")} - Version ${options.version} - ${options.concurrency} Workers`);
|
|
218
225
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ProgressReporter.ts"],"sourcesContent":["import { type LogEntry, LogLevel, type Reporter, type LogStructuredData } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\n\nimport { TaskReporter, type TaskReporterTask } from \"@ms-cloudpack/task-reporter\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport { gradient } from \"./gradient.js\";\nimport chalk from \"chalk\";\nimport type { Writable } from \"stream\";\nimport { formatDuration, hrToSeconds, hrtimeDiff } from \"@lage-run/format-hrtime\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\n\nconst colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.hex(\"#FF1010\"),\n [LogLevel.silly]: chalk.green,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\nfunction fancy(str: string) {\n return gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(str);\n}\n\nexport class ProgressReporter implements Reporter {\n public logStream: Writable = process.stdout;\n\n private logEntries: Map<string, LogEntry<LogStructuredData>[]> = new Map<string, LogEntry[]>();\n\n private taskReporter: TaskReporter;\n private tasks: Map<string, TaskReporterTask> = new Map();\n\n constructor(private options: { concurrency: number; version: string } = { concurrency: 0, version: \"0.0.0\" }) {\n this.taskReporter = this.createTaskReporter();\n\n this.print(`${fancy(\"lage\")} - Version ${options.version} - ${options.concurrency} Workers`);\n }\n\n private createTaskReporter(): TaskReporter {\n return new TaskReporter({\n productName: \"lage\",\n version: this.options.version,\n\n showCompleted: true,\n showConsoleDebug: true,\n showConsoleError: true,\n showConsoleInfo: true,\n showConsoleLog: true,\n showConsoleWarn: true,\n showErrors: true,\n showPending: true,\n showStarted: true,\n showSummary: true,\n showTaskDetails: true,\n showTaskExtended: true,\n });\n }\n\n public log(entry: LogEntry<any>): void {\n // save the logs for errors\n if (entry.data?.target?.id) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n // if \"hidden\", do not even attempt to record or report the entry\n if (entry?.data?.target?.hidden) {\n return;\n }\n\n if (entry.data && entry.data.status && entry.data.target) {\n const target: Target = entry.data.target;\n const status: TargetStatus = entry.data.status;\n\n const reporterTask = this.tasks.has(target.id) ? this.tasks.get(target.id) : this.taskReporter.addTask(target.label, true);\n\n if (reporterTask) {\n this.tasks.set(target.id, reporterTask);\n switch (status) {\n case \"running\":\n reporterTask.start();\n break;\n\n case \"success\":\n reporterTask.complete({ status: \"complete\" });\n break;\n\n case \"aborted\":\n reporterTask.complete({ status: \"abort\" });\n break;\n\n case \"skipped\":\n reporterTask.complete({ status: \"skip\" });\n break;\n\n case \"failed\":\n reporterTask.complete({ status: \"fail\" });\n break;\n }\n }\n }\n }\n\n private print(message: string) {\n this.logStream.write(message + \"\\n\");\n }\n\n private hr(): void {\n this.print(\"┈\".repeat(80));\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending, running, queued } = targetRunByStatus;\n\n // If we are printing summary, and there are still some running / queued tasks - report them as aborted\n for (const wrappedTarget of running.concat(queued)) {\n const reporterTask = this.tasks.get(wrappedTarget);\n if (reporterTask) {\n reporterTask.complete({ status: \"abort\" });\n }\n }\n\n const statusColorFn: {\n [status in TargetStatus]: chalk.Chalk;\n } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n if (targetRuns.size > 0) {\n this.print(chalk.cyanBright(`\\nSummary`));\n\n this.hr();\n\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n if (wrappedTarget.target.hidden) {\n continue;\n }\n\n const colorFn = statusColorFn[wrappedTarget.status] ?? chalk.white;\n const target = wrappedTarget.target;\n const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;\n const queueDuration: [number, number] = hasDurations ? hrtimeDiff(wrappedTarget.queueTime, wrappedTarget.startTime) : [0, 0];\n\n if (wrappedTarget.status === \"running\") {\n const reporterTask = this.tasks.get(wrappedTarget.target.id);\n if (reporterTask) {\n reporterTask.complete({ status: \"fail\" });\n }\n }\n\n this.print(\n `${target.label} ${colorFn(\n `${wrappedTarget.status === \"running\" ? \"running - incomplete\" : wrappedTarget.status}${\n hasDurations\n ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}, queued for ${formatDuration(hrToSeconds(queueDuration))}`\n : \"\"\n }`\n )}`\n );\n }\n\n this.print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n\n this.print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(\n schedulerRunSummary.maxWorkerMemoryUsage\n )}`\n );\n } else {\n this.print(\"Nothing has been run.\");\n }\n\n this.hr();\n\n if (failed && failed.length > 0) {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const failureLogs = this.logEntries.get(targetId);\n\n this.print(`[${colors.pkg(packageName ?? \"<root>\")} ${colors.task(task)}] ${colors[LogLevel.error](\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n // Log each entry separately to prevent truncation\n this.print(entry.msg);\n }\n }\n\n this.hr();\n }\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : \"\";\n\n this.print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n}\n"],"names":["ProgressReporter","colors","LogLevel","info","chalk","white","verbose","gray","warn","error","hex","silly","green","task","pkg","ok","red","yellow","fancy","str","gradient","r","g","b","createTaskReporter","TaskReporter","productName","version","options","showCompleted","showConsoleDebug","showConsoleError","showConsoleInfo","showConsoleLog","showConsoleWarn","showErrors","showPending","showStarted","showSummary","showTaskDetails","showTaskExtended","log","entry","data","target","id","logEntries","has","set","get","push","hidden","status","reporterTask","tasks","taskReporter","addTask","label","start","complete","print","message","logStream","write","hr","repeat","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","duration","failed","aborted","skipped","success","pending","running","queued","wrappedTarget","concat","statusColorFn","greenBright","redBright","magenta","size","cyanBright","slowestTargets","slowestTargetRuns","values","colorFn","hasDurations","queueTime","queueDuration","hrtimeDiff","startTime","formatDuration","hrToSeconds","length","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","packageName","failureLogs","msg","allCacheHits","filter","run","allCacheHitText","concurrency","process","stdout","Map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/ProgressReporter.ts"],"sourcesContent":["import { type LogEntry, LogLevel, type Reporter, type LogStructuredData } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\n\nimport { TaskReporter, type TaskReporterTask } from \"@ms-cloudpack/task-reporter\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport { gradient } from \"./gradient.js\";\nimport chalk from \"chalk\";\nimport type { Writable } from \"stream\";\nimport { formatDuration, hrToSeconds, hrtimeDiff } from \"./formatDuration.js\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { slowestTargetRuns } from \"./slowestTargetRuns.js\";\n\nconst colors = {\n [LogLevel.info]: chalk.white,\n [LogLevel.verbose]: chalk.gray,\n [LogLevel.warn]: chalk.white,\n [LogLevel.error]: chalk.hex(\"#FF1010\"),\n [LogLevel.silly]: chalk.green,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n ok: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n};\n\nfunction fancy(str: string) {\n return gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(str);\n}\n\nexport class ProgressReporter implements Reporter {\n public logStream: Writable = process.stdout;\n\n private logEntries: Map<string, LogEntry<LogStructuredData>[]> = new Map<string, LogEntry[]>();\n\n private taskReporter: TaskReporter;\n private tasks: Map<string, TaskReporterTask> = new Map();\n private logMemory: boolean;\n\n constructor(\n private options: {\n concurrency: number;\n version: string;\n /** Whether to capture and report main process memory usage on target completion */\n logMemory?: boolean;\n } = { concurrency: 0, version: \"0.0.0\" }\n ) {\n this.logMemory = !!options.logMemory;\n this.taskReporter = this.createTaskReporter();\n\n this.print(`${fancy(\"lage\")} - Version ${options.version} - ${options.concurrency} Workers`);\n }\n\n private createTaskReporter(): TaskReporter {\n return new TaskReporter({\n productName: \"lage\",\n version: this.options.version,\n\n showCompleted: true,\n showConsoleDebug: true,\n showConsoleError: true,\n showConsoleInfo: true,\n showConsoleLog: true,\n showConsoleWarn: true,\n showErrors: true,\n showPending: true,\n showStarted: true,\n showSummary: true,\n showTaskDetails: true,\n showTaskExtended: true,\n });\n }\n\n public log(entry: LogEntry<any>): void {\n // save the logs for errors\n if (entry.data?.target?.id) {\n if (!this.logEntries.has(entry.data.target.id)) {\n this.logEntries.set(entry.data.target.id, []);\n }\n this.logEntries.get(entry.data.target.id)!.push(entry);\n }\n\n // if \"hidden\", do not even attempt to record or report the entry\n if (entry?.data?.target?.hidden) {\n return;\n }\n\n if (entry.data && entry.data.status && entry.data.target) {\n const target: Target = entry.data.target;\n const status: TargetStatus = entry.data.status;\n\n const reporterTask = this.tasks.has(target.id) ? this.tasks.get(target.id) : this.taskReporter.addTask(target.label, true);\n\n if (reporterTask) {\n this.tasks.set(target.id, reporterTask);\n\n const mem = entry.data.memoryUsage;\n const memoryMessage = this.logMemory && mem ? `[rss: ${formatBytes(mem.rss)}, heap: ${formatBytes(mem.heapUsed)}]` : \"\";\n\n switch (status) {\n case \"running\":\n reporterTask.start();\n break;\n\n case \"success\":\n reporterTask.complete({ status: \"complete\", message: memoryMessage });\n break;\n\n case \"aborted\":\n reporterTask.complete({ status: \"abort\" });\n break;\n\n case \"skipped\":\n reporterTask.complete({ status: \"skip\", message: memoryMessage });\n break;\n\n case \"failed\":\n reporterTask.complete({ status: \"fail\", message: memoryMessage });\n break;\n }\n }\n }\n }\n\n private print(message: string) {\n this.logStream.write(message + \"\\n\");\n }\n\n private hr(): void {\n this.print(\"┈\".repeat(80));\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending, running, queued } = targetRunByStatus;\n\n // If we are printing summary, and there are still some running / queued tasks - report them as aborted\n for (const wrappedTarget of running.concat(queued)) {\n const reporterTask = this.tasks.get(wrappedTarget);\n if (reporterTask) {\n reporterTask.complete({ status: \"abort\" });\n }\n }\n\n const statusColorFn: {\n [status in TargetStatus]: chalk.Chalk;\n } = {\n success: chalk.greenBright,\n failed: chalk.redBright,\n skipped: chalk.gray,\n running: chalk.yellow,\n pending: chalk.gray,\n aborted: chalk.red,\n queued: chalk.magenta,\n };\n\n if (targetRuns.size > 0) {\n this.print(chalk.cyanBright(`\\nSummary`));\n\n this.hr();\n\n const slowestTargets = slowestTargetRuns([...targetRuns.values()]);\n\n for (const wrappedTarget of slowestTargets) {\n if (wrappedTarget.target.hidden) {\n continue;\n }\n\n const colorFn = statusColorFn[wrappedTarget.status] ?? chalk.white;\n const target = wrappedTarget.target;\n const hasDurations = !!wrappedTarget.duration && !!wrappedTarget.queueTime;\n const queueDuration: [number, number] = hasDurations ? hrtimeDiff(wrappedTarget.queueTime, wrappedTarget.startTime) : [0, 0];\n\n if (wrappedTarget.status === \"running\") {\n const reporterTask = this.tasks.get(wrappedTarget.target.id);\n if (reporterTask) {\n reporterTask.complete({ status: \"fail\" });\n }\n }\n\n this.print(\n `${target.label} ${colorFn(\n `${wrappedTarget.status === \"running\" ? \"running - incomplete\" : wrappedTarget.status}${\n hasDurations\n ? `, took ${formatDuration(hrToSeconds(wrappedTarget.duration))}, queued for ${formatDuration(hrToSeconds(queueDuration))}`\n : \"\"\n }`\n )}`\n );\n }\n\n this.print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n\n this.print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(\n schedulerRunSummary.maxWorkerMemoryUsage\n )}`\n );\n } else {\n this.print(\"Nothing has been run.\");\n }\n\n this.hr();\n\n if (failed && failed.length > 0) {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const failureLogs = this.logEntries.get(targetId);\n\n this.print(`[${colors.pkg(packageName ?? \"<root>\")} ${colors.task(task)}] ${colors[LogLevel.error](\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n // Log each entry separately to prevent truncation\n this.print(entry.msg);\n }\n }\n\n this.hr();\n }\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : \"\";\n\n this.print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n}\n"],"names":["ProgressReporter","colors","LogLevel","info","chalk","white","verbose","gray","warn","error","hex","silly","green","task","pkg","ok","red","yellow","fancy","str","gradient","r","g","b","createTaskReporter","TaskReporter","productName","version","options","showCompleted","showConsoleDebug","showConsoleError","showConsoleInfo","showConsoleLog","showConsoleWarn","showErrors","showPending","showStarted","showSummary","showTaskDetails","showTaskExtended","log","entry","data","target","id","logEntries","has","set","get","push","hidden","status","reporterTask","tasks","taskReporter","addTask","label","mem","memoryUsage","memoryMessage","logMemory","formatBytes","rss","heapUsed","start","complete","message","print","logStream","write","hr","repeat","summarize","schedulerRunSummary","targetRuns","targetRunByStatus","duration","failed","aborted","skipped","success","pending","running","queued","wrappedTarget","concat","statusColorFn","greenBright","redBright","magenta","size","cyanBright","slowestTargets","slowestTargetRuns","values","colorFn","hasDurations","queueTime","queueDuration","hrtimeDiff","startTime","formatDuration","hrToSeconds","length","workerRestarts","maxWorkerMemoryUsage","targetId","packageName","failureLogs","msg","allCacheHits","filter","run","allCacheHitText","concurrency","process","stdout","Map"],"mappings":"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"}
|
|
@@ -2,16 +2,19 @@ import type { Reporter, LogEntry } from "@lage-run/logger";
|
|
|
2
2
|
import { Writable } from "stream";
|
|
3
3
|
export declare class VerboseFileLogReporter implements Reporter {
|
|
4
4
|
private fileStream;
|
|
5
|
+
private logMemory;
|
|
5
6
|
/**
|
|
6
7
|
* @param logFile Log file path from CLI args
|
|
7
8
|
* @param fileStream Stream for testing
|
|
9
|
+
* @param logMemory Whether to log memory usage at task completion
|
|
8
10
|
*/
|
|
9
|
-
constructor(logFile?: string, fileStream?: Writable);
|
|
11
|
+
constructor(logFile?: string, fileStream?: Writable, logMemory?: boolean);
|
|
10
12
|
cleanup(): void;
|
|
11
13
|
log(entry: LogEntry<any>): void;
|
|
12
14
|
private printEntry;
|
|
13
15
|
private getEntryTargetId;
|
|
14
16
|
private print;
|
|
17
|
+
private formatMemory;
|
|
15
18
|
private logTargetEntry;
|
|
16
19
|
summarize(): void;
|
|
17
20
|
}
|
|
@@ -8,13 +8,14 @@ Object.defineProperty(exports, "VerboseFileLogReporter", {
|
|
|
8
8
|
return VerboseFileLogReporter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
const _isTargetStatusLogEntry = require("./isTargetStatusLogEntry.js");
|
|
13
13
|
const _logger = require("@lage-run/logger");
|
|
14
14
|
const _ansiregex = /*#__PURE__*/ _interop_require_default(require("ansi-regex"));
|
|
15
15
|
const _stream = require("stream");
|
|
16
16
|
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
17
17
|
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
18
|
+
const _formatBytes = require("./formatBytes.js");
|
|
18
19
|
function _define_property(obj, key, value) {
|
|
19
20
|
if (key in obj) {
|
|
20
21
|
Object.defineProperty(obj, key, {
|
|
@@ -77,24 +78,29 @@ class VerboseFileLogReporter {
|
|
|
77
78
|
print(message) {
|
|
78
79
|
this.fileStream.write(message + "\n");
|
|
79
80
|
}
|
|
81
|
+
formatMemory(memoryUsage) {
|
|
82
|
+
if (!this.logMemory || !memoryUsage) {
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
return ` [rss: ${(0, _formatBytes.formatBytes)(memoryUsage.rss)}, heap: ${(0, _formatBytes.formatBytes)(memoryUsage.heapUsed)}]`;
|
|
86
|
+
}
|
|
80
87
|
logTargetEntry(entry) {
|
|
81
88
|
const data = entry.data;
|
|
82
89
|
if ((0, _isTargetStatusLogEntry.isTargetStatusLogEntry)(data)) {
|
|
83
|
-
const { hash, duration, status } = data;
|
|
90
|
+
const { hash, duration, status, memoryUsage } = data;
|
|
91
|
+
const mem = this.formatMemory(memoryUsage);
|
|
84
92
|
const statusMessages = {
|
|
85
93
|
running: "➔ start",
|
|
86
|
-
success: `✓ done - ${duration && (0,
|
|
87
|
-
failed:
|
|
88
|
-
skipped: `» skip - ${hash}`,
|
|
94
|
+
success: `✓ done - ${duration && (0, _formatDuration.formatDuration)((0, _formatDuration.hrToSeconds)(duration))}${mem}`,
|
|
95
|
+
failed: `✖ fail${mem}`,
|
|
96
|
+
skipped: `» skip - ${hash}${mem}`,
|
|
89
97
|
aborted: "- aborted",
|
|
90
98
|
queued: "… queued",
|
|
91
99
|
pending: "… pending"
|
|
92
100
|
};
|
|
93
101
|
return this.printEntry(entry, statusMessages[status]);
|
|
94
|
-
} else {
|
|
95
|
-
const defaultMessage = `: ${stripAnsi(entry.msg)}`;
|
|
96
|
-
return this.printEntry(entry, defaultMessage);
|
|
97
102
|
}
|
|
103
|
+
return this.printEntry(entry, `: ${stripAnsi(entry.msg)}`);
|
|
98
104
|
}
|
|
99
105
|
summarize() {
|
|
100
106
|
// No summary needed for VerboseFileLogReporter
|
|
@@ -102,8 +108,11 @@ class VerboseFileLogReporter {
|
|
|
102
108
|
/**
|
|
103
109
|
* @param logFile Log file path from CLI args
|
|
104
110
|
* @param fileStream Stream for testing
|
|
105
|
-
|
|
111
|
+
* @param logMemory Whether to log memory usage at task completion
|
|
112
|
+
*/ constructor(logFile, fileStream, logMemory){
|
|
106
113
|
_define_property(this, "fileStream", void 0);
|
|
114
|
+
_define_property(this, "logMemory", void 0);
|
|
115
|
+
this.logMemory = logMemory ?? false;
|
|
107
116
|
// if logFile is falsy (not specified on cli args), this.fileStream just become a "nowhere" stream and this reporter effectively does nothing
|
|
108
117
|
if (logFile) {
|
|
109
118
|
const logFileDir = _path.default.dirname(_path.default.resolve(logFile));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/VerboseFileLogReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"
|
|
1
|
+
{"version":3,"sources":["../src/VerboseFileLogReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"./formatDuration.js\";\nimport { isTargetStatusLogEntry } from \"./isTargetStatusLogEntry.js\";\nimport { LogLevel } from \"@lage-run/logger\";\nimport ansiRegex from \"ansi-regex\";\nimport type { Reporter, LogEntry } from \"@lage-run/logger\";\nimport type { TargetLogData } from \"./types/TargetLogData.js\";\nimport { Writable } from \"stream\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport type { TargetStatus } from \"@lage-run/scheduler-types\";\nimport { formatBytes } from \"./formatBytes.js\";\n\nconst stripAnsiRegex = ansiRegex();\n\nfunction stripAnsi(message: string) {\n return message.replace(stripAnsiRegex, \"\");\n}\n\nexport class VerboseFileLogReporter implements Reporter {\n private fileStream: Writable;\n private logMemory: boolean;\n\n /**\n * @param logFile Log file path from CLI args\n * @param fileStream Stream for testing\n * @param logMemory Whether to log memory usage at task completion\n */\n constructor(logFile?: string, fileStream?: Writable, logMemory?: boolean) {\n this.logMemory = logMemory ?? false;\n // if logFile is falsy (not specified on cli args), this.fileStream just become a \"nowhere\" stream and this reporter effectively does nothing\n if (logFile) {\n const logFileDir = path.dirname(path.resolve(logFile));\n if (!fs.existsSync(logFileDir)) {\n fs.mkdirSync(logFileDir, { recursive: true });\n }\n }\n\n this.fileStream = fileStream ?? (logFile ? fs.createWriteStream(logFile) : new Writable({ write() {} }));\n }\n\n public cleanup(): void {\n this.fileStream.end();\n }\n\n public log(entry: LogEntry<any>): void {\n // if \"hidden\", do not even attempt to record or report the entry\n if (entry?.data?.target?.hidden) {\n return;\n }\n\n // if loglevel is not high enough, do not report the entry\n if (LogLevel.verbose < entry.level) {\n return;\n }\n\n // log normal target entries\n if (entry.data && entry.data.target) {\n return this.logTargetEntry(entry);\n }\n\n // log generic entries (not related to target)\n if (entry.msg) {\n return this.print(`${entry.msg}`);\n }\n }\n\n private printEntry(entry: LogEntry<any>, message: string) {\n let packageAndTask = \"\";\n\n if (entry?.data?.target) {\n const { packageName, task } = entry.data.target;\n const pkg = packageName ?? \"<root>\";\n\n packageAndTask = `${pkg} ${task}`.trim();\n }\n\n this.print(`${this.getEntryTargetId(entry)} ${packageAndTask} ${message}`.trim());\n }\n\n private getEntryTargetId(entry: LogEntry<any>) {\n if (entry.data?.target?.id) {\n return `[:${entry.data.target.id}:]`;\n }\n\n return \"\";\n }\n\n private print(message: string) {\n this.fileStream.write(message + \"\\n\");\n }\n\n private formatMemory(memoryUsage?: NodeJS.MemoryUsage): string {\n if (!this.logMemory || !memoryUsage) {\n return \"\";\n }\n return ` [rss: ${formatBytes(memoryUsage.rss)}, heap: ${formatBytes(memoryUsage.heapUsed)}]`;\n }\n\n private logTargetEntry(entry: LogEntry<TargetLogData>) {\n const data = entry.data!;\n\n if (isTargetStatusLogEntry(data)) {\n const { hash, duration, status, memoryUsage } = data;\n const mem = this.formatMemory(memoryUsage);\n const statusMessages: Record<TargetStatus, string> = {\n running: \"➔ start\",\n success: `✓ done - ${duration && formatDuration(hrToSeconds(duration))}${mem}`,\n failed: `✖ fail${mem}`,\n skipped: `» skip - ${hash}${mem}`,\n aborted: \"- aborted\",\n queued: \"… queued\",\n pending: \"… pending\",\n };\n\n return this.printEntry(entry, statusMessages[status]);\n }\n\n return this.printEntry(entry, `: ${stripAnsi(entry.msg)}`);\n }\n\n public summarize(): void {\n // No summary needed for VerboseFileLogReporter\n }\n}\n"],"names":["VerboseFileLogReporter","stripAnsiRegex","ansiRegex","stripAnsi","message","replace","cleanup","fileStream","end","log","entry","data","target","hidden","LogLevel","verbose","level","logTargetEntry","msg","print","printEntry","packageAndTask","packageName","task","pkg","trim","getEntryTargetId","id","write","formatMemory","memoryUsage","logMemory","formatBytes","rss","heapUsed","isTargetStatusLogEntry","hash","duration","status","mem","statusMessages","running","success","formatDuration","hrToSeconds","failed","skipped","aborted","queued","pending","summarize","logFile","logFileDir","path","dirname","resolve","fs","existsSync","mkdirSync","recursive","createWriteStream","Writable"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function formatDuration(seconds: string): string;
|
|
2
|
+
export declare function hrToSeconds(hrtime: [number, number]): string;
|
|
3
|
+
/**
|
|
4
|
+
* calculates the difference of two hrtime values
|
|
5
|
+
*/
|
|
6
|
+
export declare function hrtimeDiff(start?: [number, number], end?: [number, number]): [number, number];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get formatDuration () {
|
|
13
|
+
return formatDuration;
|
|
14
|
+
},
|
|
15
|
+
get hrToSeconds () {
|
|
16
|
+
return hrToSeconds;
|
|
17
|
+
},
|
|
18
|
+
get hrtimeDiff () {
|
|
19
|
+
return hrtimeDiff;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
function formatDuration(seconds) {
|
|
23
|
+
const raw = parseFloat(seconds);
|
|
24
|
+
if (raw > 60) {
|
|
25
|
+
const minutes = Math.floor(raw / 60);
|
|
26
|
+
const sec = (raw - minutes * 60).toFixed(2);
|
|
27
|
+
return `${minutes}m ${sec}s`;
|
|
28
|
+
}
|
|
29
|
+
const sec = raw.toFixed(2);
|
|
30
|
+
return `${sec}s`;
|
|
31
|
+
}
|
|
32
|
+
function hrToSeconds(hrtime) {
|
|
33
|
+
const raw = hrtime[0] + hrtime[1] / 1e9;
|
|
34
|
+
return raw.toFixed(2);
|
|
35
|
+
}
|
|
36
|
+
function hrtimeDiff(start = [
|
|
37
|
+
0,
|
|
38
|
+
0
|
|
39
|
+
], end = [
|
|
40
|
+
0,
|
|
41
|
+
0
|
|
42
|
+
]) {
|
|
43
|
+
const sec = end[0] - start[0];
|
|
44
|
+
const nsec = end[1] - start[1];
|
|
45
|
+
if (nsec < 0) {
|
|
46
|
+
return [
|
|
47
|
+
Math.max(0, sec - 1),
|
|
48
|
+
1e9 + nsec
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
sec,
|
|
53
|
+
nsec
|
|
54
|
+
];
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/formatDuration.ts"],"sourcesContent":["export function formatDuration(seconds: string): string {\n const raw = parseFloat(seconds);\n if (raw > 60) {\n const minutes = Math.floor(raw / 60);\n const sec = (raw - minutes * 60).toFixed(2);\n return `${minutes}m ${sec}s`;\n }\n const sec = raw.toFixed(2);\n return `${sec}s`;\n}\n\nexport function hrToSeconds(hrtime: [number, number]): string {\n const raw = hrtime[0] + hrtime[1] / 1e9;\n return raw.toFixed(2);\n}\n\n/**\n * calculates the difference of two hrtime values\n */\nexport function hrtimeDiff(start: [number, number] = [0, 0], end: [number, number] = [0, 0]): [number, number] {\n const sec = end[0] - start[0];\n const nsec = end[1] - start[1];\n\n if (nsec < 0) {\n return [Math.max(0, sec - 1), 1e9 + nsec];\n }\n\n return [sec, nsec];\n}\n"],"names":["formatDuration","hrToSeconds","hrtimeDiff","seconds","raw","parseFloat","minutes","Math","floor","sec","toFixed","hrtime","start","end","nsec","max"],"mappings":";;;;;;;;;;;QAAgBA;eAAAA;;QAWAC;eAAAA;;QAQAC;eAAAA;;;AAnBT,SAASF,eAAeG,OAAe;IAC5C,MAAMC,MAAMC,WAAWF;IACvB,IAAIC,MAAM,IAAI;QACZ,MAAME,UAAUC,KAAKC,KAAK,CAACJ,MAAM;QACjC,MAAMK,MAAM,AAACL,CAAAA,MAAME,UAAU,EAAC,EAAGI,OAAO,CAAC;QACzC,OAAO,GAAGJ,QAAQ,EAAE,EAAEG,IAAI,CAAC,CAAC;IAC9B;IACA,MAAMA,MAAML,IAAIM,OAAO,CAAC;IACxB,OAAO,GAAGD,IAAI,CAAC,CAAC;AAClB;AAEO,SAASR,YAAYU,MAAwB;IAClD,MAAMP,MAAMO,MAAM,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,GAAG;IACpC,OAAOP,IAAIM,OAAO,CAAC;AACrB;AAKO,SAASR,WAAWU,QAA0B;IAAC;IAAG;CAAE,EAAEC,MAAwB;IAAC;IAAG;CAAE;IACzF,MAAMJ,MAAMI,GAAG,CAAC,EAAE,GAAGD,KAAK,CAAC,EAAE;IAC7B,MAAME,OAAOD,GAAG,CAAC,EAAE,GAAGD,KAAK,CAAC,EAAE;IAE9B,IAAIE,OAAO,GAAG;QACZ,OAAO;YAACP,KAAKQ,GAAG,CAAC,GAAGN,MAAM;YAAI,MAAMK;SAAK;IAC3C;IAEA,OAAO;QAACL;QAAKK;KAAK;AACpB"}
|
package/lib/index.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export { ChromeTraceEventsReporter } from "./ChromeTraceEventsReporter.js";
|
|
|
7
7
|
export { ProgressReporter } from "./ProgressReporter.js";
|
|
8
8
|
export { VerboseFileLogReporter } from "./VerboseFileLogReporter.js";
|
|
9
9
|
export type { TargetStatusData, TargetMessageData, TargetLogData } from "./types/TargetLogData.js";
|
|
10
|
+
export { formatDuration, hrToSeconds, hrtimeDiff } from "./formatDuration.js";
|
package/lib/index.js
CHANGED
|
@@ -32,6 +32,15 @@ _export(exports, {
|
|
|
32
32
|
},
|
|
33
33
|
get VerboseFileLogReporter () {
|
|
34
34
|
return _VerboseFileLogReporter.VerboseFileLogReporter;
|
|
35
|
+
},
|
|
36
|
+
get formatDuration () {
|
|
37
|
+
return _formatDuration.formatDuration;
|
|
38
|
+
},
|
|
39
|
+
get hrToSeconds () {
|
|
40
|
+
return _formatDuration.hrToSeconds;
|
|
41
|
+
},
|
|
42
|
+
get hrtimeDiff () {
|
|
43
|
+
return _formatDuration.hrtimeDiff;
|
|
35
44
|
}
|
|
36
45
|
});
|
|
37
46
|
const _AdoReporter = require("./AdoReporter.js");
|
|
@@ -42,3 +51,4 @@ const _LogReporter = require("./LogReporter.js");
|
|
|
42
51
|
const _ChromeTraceEventsReporter = require("./ChromeTraceEventsReporter.js");
|
|
43
52
|
const _ProgressReporter = require("./ProgressReporter.js");
|
|
44
53
|
const _VerboseFileLogReporter = require("./VerboseFileLogReporter.js");
|
|
54
|
+
const _formatDuration = require("./formatDuration.js");
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { AdoReporter } from \"./AdoReporter.js\";\nexport { GithubActionsReporter } from \"./GithubActionsReporter.js\";\nexport { BasicReporter } from \"./BasicReporter.js\";\nexport { JsonReporter, type JsonReporterLogData, type JsonReporterSummaryData } from \"./JsonReporter.js\";\nexport { LogReporter } from \"./LogReporter.js\";\nexport { ChromeTraceEventsReporter } from \"./ChromeTraceEventsReporter.js\";\nexport { ProgressReporter } from \"./ProgressReporter.js\";\nexport { VerboseFileLogReporter } from \"./VerboseFileLogReporter.js\";\nexport type { TargetStatusData, TargetMessageData, TargetLogData } from \"./types/TargetLogData.js\";\n"],"names":["AdoReporter","BasicReporter","ChromeTraceEventsReporter","GithubActionsReporter","JsonReporter","LogReporter","ProgressReporter","VerboseFileLogReporter"],"mappings":";;;;;;;;;;;QAASA;eAAAA,wBAAW;;QAEXC;eAAAA,4BAAa;;QAGbC;eAAAA,oDAAyB;;QAJzBC;eAAAA,4CAAqB;;QAErBC;eAAAA,0BAAY;;QACZC;eAAAA,wBAAW;;QAEXC;eAAAA,kCAAgB;;QAChBC;eAAAA,8CAAsB;;;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { AdoReporter } from \"./AdoReporter.js\";\nexport { GithubActionsReporter } from \"./GithubActionsReporter.js\";\nexport { BasicReporter } from \"./BasicReporter.js\";\nexport { JsonReporter, type JsonReporterLogData, type JsonReporterSummaryData } from \"./JsonReporter.js\";\nexport { LogReporter } from \"./LogReporter.js\";\nexport { ChromeTraceEventsReporter } from \"./ChromeTraceEventsReporter.js\";\nexport { ProgressReporter } from \"./ProgressReporter.js\";\nexport { VerboseFileLogReporter } from \"./VerboseFileLogReporter.js\";\nexport type { TargetStatusData, TargetMessageData, TargetLogData } from \"./types/TargetLogData.js\";\nexport { formatDuration, hrToSeconds, hrtimeDiff } from \"./formatDuration.js\";\n"],"names":["AdoReporter","BasicReporter","ChromeTraceEventsReporter","GithubActionsReporter","JsonReporter","LogReporter","ProgressReporter","VerboseFileLogReporter","formatDuration","hrToSeconds","hrtimeDiff"],"mappings":";;;;;;;;;;;QAASA;eAAAA,wBAAW;;QAEXC;eAAAA,4BAAa;;QAGbC;eAAAA,oDAAyB;;QAJzBC;eAAAA,4CAAqB;;QAErBC;eAAAA,0BAAY;;QACZC;eAAAA,wBAAW;;QAEXC;eAAAA,kCAAgB;;QAChBC;eAAAA,8CAAsB;;QAEtBC;eAAAA,8BAAc;;QAAEC;eAAAA,2BAAW;;QAAEC;eAAAA,0BAAU;;;6BATpB;uCACU;+BACR;8BACuD;6BACzD;2CACc;kCACT;wCACM;gCAEiB"}
|
package/lib/slowestTargetRuns.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "slowestTargetRuns", {
|
|
|
8
8
|
return slowestTargetRuns;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
11
|
+
const _formatDuration = require("./formatDuration.js");
|
|
12
12
|
function slowestTargetRuns(targetRuns) {
|
|
13
|
-
return targetRuns.sort((a, b)=>parseFloat((0,
|
|
13
|
+
return targetRuns.sort((a, b)=>parseFloat((0, _formatDuration.hrToSeconds)((0, _formatDuration.hrtimeDiff)(a.duration, b.duration)))).filter((run)=>run.status !== "skipped" && !run.target.hidden);
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/slowestTargetRuns.ts"],"sourcesContent":["import { hrtimeDiff, hrToSeconds } from \"
|
|
1
|
+
{"version":3,"sources":["../src/slowestTargetRuns.ts"],"sourcesContent":["import { hrtimeDiff, hrToSeconds } from \"./formatDuration.js\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\n\nexport function slowestTargetRuns(targetRuns: TargetRun[]): TargetRun<unknown>[] {\n return targetRuns\n .sort((a, b) => parseFloat(hrToSeconds(hrtimeDiff(a.duration, b.duration))))\n .filter((run) => run.status !== \"skipped\" && !run.target.hidden);\n}\n"],"names":["slowestTargetRuns","targetRuns","sort","a","b","parseFloat","hrToSeconds","hrtimeDiff","duration","filter","run","status","target","hidden"],"mappings":";;;;+BAGgBA;;;eAAAA;;;gCAHwB;AAGjC,SAASA,kBAAkBC,UAAuB;IACvD,OAAOA,WACJC,IAAI,CAAC,CAACC,GAAGC,IAAMC,WAAWC,IAAAA,2BAAW,EAACC,IAAAA,0BAAU,EAACJ,EAAEK,QAAQ,EAAEJ,EAAEI,QAAQ,KACvEC,MAAM,CAAC,CAACC,MAAQA,IAAIC,MAAM,KAAK,aAAa,CAACD,IAAIE,MAAM,CAACC,MAAM;AACnE"}
|
|
@@ -6,6 +6,11 @@ export interface TargetStatusData {
|
|
|
6
6
|
status: TargetStatus;
|
|
7
7
|
duration?: [number, number];
|
|
8
8
|
hash?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Memory usage, only included for non-abort completion statuses and only if logging memory
|
|
11
|
+
* usage is enabled in the reporter options.
|
|
12
|
+
*/
|
|
13
|
+
memoryUsage?: NodeJS.MemoryUsage;
|
|
9
14
|
}
|
|
10
15
|
/** `LogEntry.data` for a target message log */
|
|
11
16
|
export interface TargetMessageData {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lage-run/reporters",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Log reporters for Lage",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"main": "lib/index.js",
|
|
12
12
|
"types": "lib/index.d.ts",
|
|
13
13
|
"scripts": {
|
|
14
|
+
"api": "monorepo-scripts api",
|
|
14
15
|
"build": "yarn types && yarn transpile",
|
|
15
16
|
"transpile": "monorepo-scripts transpile",
|
|
16
17
|
"types": "yarn run -T tsc",
|
|
@@ -18,10 +19,9 @@
|
|
|
18
19
|
"lint": "monorepo-scripts lint"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@lage-run/format-hrtime": "^0.1.9",
|
|
22
22
|
"@lage-run/logger": "^1.3.3",
|
|
23
|
-
"@lage-run/scheduler-types": "^0.
|
|
24
|
-
"@lage-run/target-graph": "^0.14.
|
|
23
|
+
"@lage-run/scheduler-types": "^0.4.0",
|
|
24
|
+
"@lage-run/target-graph": "^0.14.2",
|
|
25
25
|
"@ms-cloudpack/task-reporter": "^0.19.0",
|
|
26
26
|
"ansi-regex": "^5.0.1",
|
|
27
27
|
"chalk": "^4.1.2",
|