You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.4 KiB
99 lines
3.4 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.profiler = void 0;
|
|
const fs = require("fs");
|
|
const ora = require("ora");
|
|
const readline = require("readline");
|
|
const tmp = require("tmp");
|
|
const abort_controller_1 = require("abort-controller");
|
|
const apiv2_1 = require("./apiv2");
|
|
const api_1 = require("./database/api");
|
|
const logger_1 = require("./logger");
|
|
const profileReport_1 = require("./profileReport");
|
|
const responseToError_1 = require("./responseToError");
|
|
const utils = require("./utils");
|
|
tmp.setGracefulCleanup();
|
|
async function profiler(options) {
|
|
const origin = (0, api_1.realtimeOriginOrEmulatorOrCustomUrl)(options.instanceDetails.databaseUrl);
|
|
const url = new URL(utils.getDatabaseUrl(origin, options.instance, "/.settings/profile.json?"));
|
|
const rl = readline.createInterface({ input: process.stdin });
|
|
const fileOut = !!options.output;
|
|
const tmpFile = tmp.tmpNameSync();
|
|
const tmpStream = fs.createWriteStream(tmpFile);
|
|
const outStream = fileOut ? fs.createWriteStream(options.output) : process.stdout;
|
|
const spinner = ora({
|
|
text: "0 operations recorded. Press [enter] to stop",
|
|
color: "yellow",
|
|
});
|
|
const outputFormat = options.raw ? "RAW" : options.parent.json ? "JSON" : "TXT";
|
|
const controller = new abort_controller_1.default();
|
|
const generateReport = () => {
|
|
rl.close();
|
|
spinner.stop();
|
|
controller.abort();
|
|
const dataFile = options.input || tmpFile;
|
|
const reportOptions = {
|
|
format: outputFormat,
|
|
isFile: fileOut,
|
|
isInput: !!options.input,
|
|
collapse: options.collapse,
|
|
};
|
|
const report = new profileReport_1.ProfileReport(dataFile, outStream, reportOptions);
|
|
return report.generate();
|
|
};
|
|
if (options.input) {
|
|
return generateReport();
|
|
}
|
|
const c = new apiv2_1.Client({ urlPrefix: url.origin, auth: true });
|
|
const res = await c.request({
|
|
method: "GET",
|
|
path: url.pathname,
|
|
responseType: "stream",
|
|
resolveOnHTTPError: true,
|
|
headers: {
|
|
Accept: "text/event-stream",
|
|
},
|
|
signal: controller.signal,
|
|
});
|
|
if (res.response.status >= 400) {
|
|
throw (0, responseToError_1.responseToError)(res.response, await res.response.text());
|
|
}
|
|
if (!options.duration) {
|
|
spinner.start();
|
|
}
|
|
let counter = 0;
|
|
res.body.on("data", (chunk) => {
|
|
if (chunk.toString().includes("event: log")) {
|
|
counter++;
|
|
spinner.text = `${counter} operations recorded. Press [enter] to stop`;
|
|
}
|
|
});
|
|
res.body.on("end", () => {
|
|
spinner.text = counter + " operations recorded.\n";
|
|
});
|
|
let resError;
|
|
res.body.on("error", (e) => {
|
|
if (e.type !== "aborted") {
|
|
resError = e;
|
|
logger_1.logger.error("Unexpected error from response stream:", e);
|
|
}
|
|
});
|
|
const p = new Promise((resolve, reject) => {
|
|
const fn = () => {
|
|
controller.abort();
|
|
if (resError) {
|
|
return reject(resError);
|
|
}
|
|
resolve(generateReport());
|
|
};
|
|
if (options.duration) {
|
|
setTimeout(fn, options.duration * 1000);
|
|
}
|
|
else {
|
|
rl.question("", fn);
|
|
}
|
|
});
|
|
res.body.pipe(tmpStream);
|
|
return p;
|
|
}
|
|
exports.profiler = profiler;
|