No Description
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.

loggingEmulator.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.LoggingEmulator = void 0;
  4. const types_1 = require("./types");
  5. const constants_1 = require("./constants");
  6. const triple_beam_1 = require("triple-beam");
  7. const WebSocket = require("ws");
  8. const TransportStream = require("winston-transport");
  9. const logger_1 = require("../logger");
  10. const stripAnsi = require("strip-ansi");
  11. class LoggingEmulator {
  12. constructor(args) {
  13. this.args = args;
  14. }
  15. start() {
  16. this.transport = new WebSocketTransport();
  17. this.transport.start(this.getInfo());
  18. logger_1.logger.add(this.transport);
  19. return Promise.resolve();
  20. }
  21. connect() {
  22. return Promise.resolve();
  23. }
  24. async stop() {
  25. if (this.transport) {
  26. logger_1.logger.remove(this.transport);
  27. return this.transport.stop();
  28. }
  29. }
  30. getInfo() {
  31. const host = this.args.host || constants_1.Constants.getDefaultHost();
  32. const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.LOGGING);
  33. return {
  34. name: this.getName(),
  35. host,
  36. port,
  37. };
  38. }
  39. getName() {
  40. return types_1.Emulators.LOGGING;
  41. }
  42. }
  43. exports.LoggingEmulator = LoggingEmulator;
  44. LoggingEmulator.LOGGING_EMULATOR_ENV = "FIREBASE_LOGGING_EMULATOR_HOST";
  45. class WebSocketTransport extends TransportStream {
  46. constructor(options = {}) {
  47. super(options);
  48. this.connections = new Set();
  49. this.history = [];
  50. this.setMaxListeners(30);
  51. }
  52. start(options) {
  53. this.wss = new WebSocket.Server(options);
  54. this.wss.on("connection", (ws) => {
  55. this.connections.add(ws);
  56. ws.once("close", () => this.connections.delete(ws));
  57. this.history.forEach((bundle) => {
  58. ws.send(JSON.stringify(bundle));
  59. });
  60. });
  61. }
  62. stop() {
  63. return new Promise((resolve, reject) => {
  64. if (!this.wss) {
  65. return resolve();
  66. }
  67. this.wss.close((err) => {
  68. if (err)
  69. return reject(err);
  70. resolve();
  71. });
  72. this.connections.forEach((socket) => socket.terminate());
  73. });
  74. }
  75. log(info, next) {
  76. setImmediate(() => this.emit("logged", info));
  77. const bundle = {
  78. level: info.level,
  79. data: {},
  80. timestamp: new Date().getTime(),
  81. message: "",
  82. };
  83. const splat = [info.message, ...(info[triple_beam_1.SPLAT] || [])]
  84. .map((value) => {
  85. if (typeof value === "string") {
  86. try {
  87. bundle.data = Object.assign(Object.assign({}, bundle.data), JSON.parse(value));
  88. return null;
  89. }
  90. catch (err) {
  91. return value;
  92. }
  93. }
  94. else {
  95. bundle.data = Object.assign(Object.assign({}, bundle.data), value);
  96. }
  97. })
  98. .filter((v) => v);
  99. bundle.message = splat.join(" ");
  100. if (bundle.data && bundle.data.metadata && bundle.data.metadata.level) {
  101. bundle.level = bundle.data.metadata.level.toLowerCase();
  102. }
  103. else {
  104. bundle.level = bundle.level.toLowerCase();
  105. }
  106. if (bundle.data && bundle.data.metadata && bundle.data.metadata.message) {
  107. bundle.message = bundle.data.metadata.message;
  108. }
  109. bundle.message = stripAnsi(bundle.message);
  110. this.history.push(bundle);
  111. this.connections.forEach((ws) => {
  112. ws.send(JSON.stringify(bundle));
  113. });
  114. if (next) {
  115. next();
  116. }
  117. }
  118. }