UNPKG

@procube/pino-transmit-http

Version:

A pino browser transmit that send log statements over HTTP

130 lines 4.59 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_throttle_1 = __importDefault(require("lodash.throttle")); const lodash_debounce_1 = __importDefault(require("lodash.debounce")); const msgpack_1 = require("@msgpack/msgpack"); const pako_1 = require("pako"); const defaultOptions = { throttle: 500, asJson: false, url: "/log", }; function exception2string(e) { if (typeof e === "string") { return e; } if (e instanceof Error) { if (e.stack) { return e.stack; } return e.message; } if (typeof e.toString === "function") { return e.toString(); } return "Unknown error"; } function concatenateUint8Arrays(arrayOfArrays) { const totalLength = arrayOfArrays.reduce((total, arr) => total + arr.length, 0); const result = new Uint8Array(totalLength); let offset = 0; for (const arr of arrayOfArrays) { result.set(arr, offset); offset += arr.length; } return result; } function transmitHttp(inOpts, _logger) { const opts = { ...defaultOptions, ...inOpts }; if (typeof window === "undefined" || !window.navigator || !window.navigator.sendBeacon) { console.error("pino-transmit-http: sendBeacon is not available."); return undefined; } let collection = []; async function rawSend() { if (collection.length === 0) { return; } try { console.log(`sending logs: ${JSON.stringify(collection)}`); // const collectionData = concatenateUint8Arrays( // collection.map((item) => encode(item)), // ) // const gzippedBody = gzip(encode(collectionData)) const body = opts.asJson ? JSON.stringify(collection) : (0, msgpack_1.encode)(collection); const gzippedBody = (0, pako_1.gzip)(body); collection = []; await fetch(opts.url, { method: "POST", mode: "same-origin", headers: { "Content-Encoding": "gzip", "Content-Type": opts.asJson ? "application/json" : "application/msgpack", }, body: gzippedBody, }); } catch (e) { console.error(`pino-transmit-http: failed to send logs: ${exception2string(e)}`); } } function flush() { if (collection.length === 0) { return; } console.log(`sending logs as flush: ${JSON.stringify(collection)}`); const collectionData = concatenateUint8Arrays(collection.map((item) => (0, msgpack_1.encode)(item))); collection = []; const gzippedBody = (0, pako_1.gzip)(collectionData); window.navigator.sendBeacon(opts.url, gzippedBody); } let send; if (opts.debounce !== null && opts.debounce !== undefined) { send = (0, lodash_debounce_1.default)(rawSend, opts.debounce); } else if (opts.throttle !== null && opts.throttle !== undefined) { send = (0, lodash_throttle_1.default)(rawSend, opts.throttle, { trailing: true, leading: false, }); } else { console.warn("pino-transmit-http: Either throttle or debounce option must be passed to pino-transmit-http. Falling back to throttle by %dms", defaultOptions.throttle); send = (0, lodash_throttle_1.default)(rawSend, defaultOptions.throttle, { trailing: true, leading: false, }); } if (typeof window !== "undefined") { window.addEventListener("unload", function onUnload() { send = flush; flush(); // flush logs, no await as we are in an unload event }); window.addEventListener("resize", function onResize() { flush(); }); } return { level: opts.level, send: function (_level, logEvent) { try { collection.push({ time: logEvent.ts / 1000, level: logEvent.level.label, ...logEvent.messages[0], }); send(); } catch (e) { console.error(`pino-transmit-http: Failed to transmit logs: ${exception2string(e)}`); } }, }; } exports.default = transmitHttp; //# sourceMappingURL=index.js.map