Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

profiler.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.profiler = void 0;
  4. const fs = require("fs");
  5. const ora = require("ora");
  6. const readline = require("readline");
  7. const tmp = require("tmp");
  8. const abort_controller_1 = require("abort-controller");
  9. const apiv2_1 = require("./apiv2");
  10. const api_1 = require("./database/api");
  11. const logger_1 = require("./logger");
  12. const profileReport_1 = require("./profileReport");
  13. const responseToError_1 = require("./responseToError");
  14. const utils = require("./utils");
  15. tmp.setGracefulCleanup();
  16. async function profiler(options) {
  17. const origin = (0, api_1.realtimeOriginOrEmulatorOrCustomUrl)(options.instanceDetails.databaseUrl);
  18. const url = new URL(utils.getDatabaseUrl(origin, options.instance, "/.settings/profile.json?"));
  19. const rl = readline.createInterface({ input: process.stdin });
  20. const fileOut = !!options.output;
  21. const tmpFile = tmp.tmpNameSync();
  22. const tmpStream = fs.createWriteStream(tmpFile);
  23. const outStream = fileOut ? fs.createWriteStream(options.output) : process.stdout;
  24. const spinner = ora({
  25. text: "0 operations recorded. Press [enter] to stop",
  26. color: "yellow",
  27. });
  28. const outputFormat = options.raw ? "RAW" : options.parent.json ? "JSON" : "TXT";
  29. const controller = new abort_controller_1.default();
  30. const generateReport = () => {
  31. rl.close();
  32. spinner.stop();
  33. controller.abort();
  34. const dataFile = options.input || tmpFile;
  35. const reportOptions = {
  36. format: outputFormat,
  37. isFile: fileOut,
  38. isInput: !!options.input,
  39. collapse: options.collapse,
  40. };
  41. const report = new profileReport_1.ProfileReport(dataFile, outStream, reportOptions);
  42. return report.generate();
  43. };
  44. if (options.input) {
  45. return generateReport();
  46. }
  47. const c = new apiv2_1.Client({ urlPrefix: url.origin, auth: true });
  48. const res = await c.request({
  49. method: "GET",
  50. path: url.pathname,
  51. responseType: "stream",
  52. resolveOnHTTPError: true,
  53. headers: {
  54. Accept: "text/event-stream",
  55. },
  56. signal: controller.signal,
  57. });
  58. if (res.response.status >= 400) {
  59. throw (0, responseToError_1.responseToError)(res.response, await res.response.text());
  60. }
  61. if (!options.duration) {
  62. spinner.start();
  63. }
  64. let counter = 0;
  65. res.body.on("data", (chunk) => {
  66. if (chunk.toString().includes("event: log")) {
  67. counter++;
  68. spinner.text = `${counter} operations recorded. Press [enter] to stop`;
  69. }
  70. });
  71. res.body.on("end", () => {
  72. spinner.text = counter + " operations recorded.\n";
  73. });
  74. let resError;
  75. res.body.on("error", (e) => {
  76. if (e.type !== "aborted") {
  77. resError = e;
  78. logger_1.logger.error("Unexpected error from response stream:", e);
  79. }
  80. });
  81. const p = new Promise((resolve, reject) => {
  82. const fn = () => {
  83. controller.abort();
  84. if (resError) {
  85. return reject(resError);
  86. }
  87. resolve(generateReport());
  88. };
  89. if (options.duration) {
  90. setTimeout(fn, options.duration * 1000);
  91. }
  92. else {
  93. rl.question("", fn);
  94. }
  95. });
  96. res.body.pipe(tmpStream);
  97. return p;
  98. }
  99. exports.profiler = profiler;