fboxrec 0.1.0 → 0.3.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/dist/index.cjs CHANGED
@@ -691,7 +691,7 @@ var FORMAT_VERSION = 1;
691
691
  var MAX_DECOMPRESSED_BYTES = 1024 * 1024 * 1024;
692
692
 
693
693
  // src/dump/serializer.ts
694
- var FLIGHTBOX_VERSION = "0.1.0";
694
+ var FLIGHTBOX_VERSION = "0.3.0";
695
695
  var DUMP_GZIP_LEVEL = 1;
696
696
  var dumpCounter = 0;
697
697
  function buildIncident(opts) {
@@ -1482,8 +1482,9 @@ function startWatchdog(agent) {
1482
1482
  // src/instrumentations/http-server.ts
1483
1483
  var http = __toESM(require("http"));
1484
1484
  var import_node_crypto2 = require("crypto");
1485
- var patched = false;
1486
1485
  var agentRef;
1486
+ var active2 = false;
1487
+ var saved = null;
1487
1488
  function tokenMatches(supplied, expected) {
1488
1489
  const a = (0, import_node_crypto2.createHash)("sha256").update(supplied).digest();
1489
1490
  const b = (0, import_node_crypto2.createHash)("sha256").update(expected).digest();
@@ -1525,12 +1526,12 @@ function handleFlightboxEndpoint(agent, req, res) {
1525
1526
  }
1526
1527
  function instrumentHttpServer(agent) {
1527
1528
  agentRef = agent;
1528
- if (patched) return;
1529
- patched = true;
1529
+ active2 = true;
1530
+ if (saved) return;
1530
1531
  const orig = http.Server.prototype.emit;
1531
1532
  const flightboxEmit = function(event) {
1532
1533
  const args = arguments;
1533
- if (event !== "request") {
1534
+ if (!active2 || event !== "request") {
1534
1535
  return orig.apply(this, args);
1535
1536
  }
1536
1537
  const agent2 = agentRef;
@@ -1583,13 +1584,22 @@ function instrumentHttpServer(agent) {
1583
1584
  }
1584
1585
  return requestStorage.run(ctx, () => orig.apply(this, args));
1585
1586
  };
1586
- http.Server.prototype.emit = flightboxEmit;
1587
+ saved = { orig, wrapper: flightboxEmit };
1588
+ http.Server.prototype.emit = saved.wrapper;
1589
+ }
1590
+ function restoreHttpServer() {
1591
+ active2 = false;
1592
+ if (saved && http.Server.prototype.emit === saved.wrapper) {
1593
+ http.Server.prototype.emit = saved.orig;
1594
+ saved = null;
1595
+ }
1587
1596
  }
1588
1597
 
1589
1598
  // src/instrumentations/http-client.ts
1590
1599
  var import_node_module = require("module");
1591
- var patched2 = false;
1592
1600
  var agentRef2;
1601
+ var active3 = false;
1602
+ var liveWraps = /* @__PURE__ */ new Map();
1593
1603
  function extractTarget(args) {
1594
1604
  let method = "GET";
1595
1605
  let host = "";
@@ -1621,10 +1631,12 @@ function extractTarget(args) {
1621
1631
  return { method: String(method).toUpperCase(), host: String(host), path: String(path8) };
1622
1632
  }
1623
1633
  var nodeRequire = (0, import_node_module.createRequire)(process.cwd() + "/noop.js");
1624
- function wrapModule(mod) {
1625
- const origRequest = mod.request.bind(mod);
1634
+ function wrapModule(key, mod) {
1635
+ const rawRequest = mod.request;
1636
+ const rawGet = mod.get;
1637
+ const origRequest = rawRequest.bind(mod);
1626
1638
  const tracedRequest = function(...args) {
1627
- if (isShedding()) return origRequest(...args);
1639
+ if (!active3 || isShedding()) return origRequest(...args);
1628
1640
  const agent = agentRef2;
1629
1641
  let spanId = 0n;
1630
1642
  let requestId = 0n;
@@ -1671,18 +1683,27 @@ function wrapModule(mod) {
1671
1683
  }
1672
1684
  return req;
1673
1685
  };
1674
- mod.request = tracedRequest;
1675
- mod.get = function(...args) {
1686
+ const tracedGet = function(...args) {
1676
1687
  const req = tracedRequest(...args);
1677
1688
  req.end();
1678
1689
  return req;
1679
1690
  };
1691
+ mod.request = tracedRequest;
1692
+ mod.get = tracedGet;
1693
+ liveWraps.set(key, () => {
1694
+ let clear = true;
1695
+ if (mod.request === tracedRequest) mod.request = rawRequest;
1696
+ else clear = false;
1697
+ if (mod.get === tracedGet) mod.get = rawGet;
1698
+ else clear = false;
1699
+ return clear;
1700
+ });
1680
1701
  }
1681
1702
  function wrapFetch() {
1682
1703
  const origFetch = globalThis.fetch;
1683
1704
  if (typeof origFetch !== "function") return;
1684
- globalThis.fetch = async function flightboxFetch(input, init) {
1685
- if (isShedding()) return origFetch(input, init);
1705
+ const wrapper = async function flightboxFetch(input, init) {
1706
+ if (!active3 || isShedding()) return origFetch(input, init);
1686
1707
  const agent = agentRef2;
1687
1708
  let spanId = 0n;
1688
1709
  let requestId = 0n;
@@ -1735,22 +1756,41 @@ function wrapFetch() {
1735
1756
  throw err;
1736
1757
  }
1737
1758
  };
1759
+ globalThis.fetch = wrapper;
1760
+ liveWraps.set("fetch", () => {
1761
+ if (globalThis.fetch === wrapper) {
1762
+ globalThis.fetch = origFetch;
1763
+ return true;
1764
+ }
1765
+ return false;
1766
+ });
1738
1767
  }
1739
1768
  function instrumentHttpClient(agent) {
1740
1769
  agentRef2 = agent;
1741
- if (patched2) return;
1742
- patched2 = true;
1743
- try {
1744
- wrapModule(nodeRequire("node:http"));
1745
- } catch {
1770
+ active3 = true;
1771
+ if (!liveWraps.has("http")) {
1772
+ try {
1773
+ wrapModule("http", nodeRequire("node:http"));
1774
+ } catch {
1775
+ }
1746
1776
  }
1747
- try {
1748
- wrapModule(nodeRequire("node:https"));
1749
- } catch {
1777
+ if (!liveWraps.has("https")) {
1778
+ try {
1779
+ wrapModule("https", nodeRequire("node:https"));
1780
+ } catch {
1781
+ }
1750
1782
  }
1751
- try {
1752
- wrapFetch();
1753
- } catch {
1783
+ if (!liveWraps.has("fetch")) {
1784
+ try {
1785
+ wrapFetch();
1786
+ } catch {
1787
+ }
1788
+ }
1789
+ }
1790
+ function restoreHttpClient() {
1791
+ active3 = false;
1792
+ for (const [key, undo] of liveWraps) {
1793
+ if (undo()) liveWraps.delete(key);
1754
1794
  }
1755
1795
  }
1756
1796
 
@@ -1770,17 +1810,21 @@ function paramShapes(values) {
1770
1810
  return values.slice(0, 32).map((v) => v === null ? "null" : Array.isArray(v) ? "array" : typeof v);
1771
1811
  }
1772
1812
  var agentRef3;
1813
+ var active4 = false;
1814
+ var queryPatch = null;
1815
+ var connectPatch = null;
1773
1816
  function instrumentPg(agent) {
1774
1817
  agentRef3 = agent;
1775
1818
  const recorder = {
1776
1819
  record: ((...args) => agentRef3.recorder.record(...args))
1777
1820
  };
1821
+ active4 = true;
1778
1822
  const pg = loadPg();
1779
1823
  if (!pg?.Client?.prototype?.query) return false;
1780
- if (!pg.Client.prototype.query.__flightbox) {
1824
+ if (!queryPatch && !pg.Client.prototype.query.__flightbox) {
1781
1825
  const origQuery = pg.Client.prototype.query;
1782
1826
  const wrappedQuery = function(...args) {
1783
- if (isShedding()) return origQuery.apply(this, args);
1827
+ if (!active4 || isShedding()) return origQuery.apply(this, args);
1784
1828
  let spanId = 0n;
1785
1829
  let requestId = 0n;
1786
1830
  let tStart = 0n;
@@ -1853,13 +1897,14 @@ function instrumentPg(agent) {
1853
1897
  return out;
1854
1898
  };
1855
1899
  wrappedQuery.__flightbox = true;
1900
+ queryPatch = { proto: pg.Client.prototype, orig: origQuery, wrapper: wrappedQuery };
1856
1901
  pg.Client.prototype.query = wrappedQuery;
1857
1902
  }
1858
1903
  const Pool = pg.Pool;
1859
- if (Pool?.prototype?.connect && !Pool.prototype.connect.__flightbox) {
1904
+ if (Pool?.prototype?.connect && !connectPatch && !Pool.prototype.connect.__flightbox) {
1860
1905
  const origConnect = Pool.prototype.connect;
1861
1906
  const wrappedConnect = function(cb) {
1862
- if (isShedding()) return origConnect.call(this, cb);
1907
+ if (!active4 || isShedding()) return origConnect.call(this, cb);
1863
1908
  const tStart = nowMono();
1864
1909
  const requestId = currentRequestId();
1865
1910
  const record = () => {
@@ -1886,33 +1931,58 @@ function instrumentPg(agent) {
1886
1931
  return out;
1887
1932
  };
1888
1933
  wrappedConnect.__flightbox = true;
1934
+ connectPatch = { proto: Pool.prototype, orig: origConnect, wrapper: wrappedConnect };
1889
1935
  Pool.prototype.connect = wrappedConnect;
1890
1936
  }
1891
1937
  return true;
1892
1938
  }
1939
+ function restorePg() {
1940
+ active4 = false;
1941
+ if (queryPatch && queryPatch.proto.query === queryPatch.wrapper) {
1942
+ queryPatch.proto.query = queryPatch.orig;
1943
+ queryPatch = null;
1944
+ }
1945
+ if (connectPatch && connectPatch.proto.connect === connectPatch.wrapper) {
1946
+ connectPatch.proto.connect = connectPatch.orig;
1947
+ connectPatch = null;
1948
+ }
1949
+ }
1893
1950
 
1894
1951
  // src/instrumentations/console.ts
1895
1952
  var import_node_util = require("util");
1896
1953
  var LEVELS = ["log", "info", "warn", "error", "debug"];
1897
1954
  var FORMAT_OPTS = { depth: 2, maxArrayLength: 20, maxStringLength: LIMITS.log };
1898
- var patched3 = false;
1899
1955
  var agentRef4;
1956
+ var active5 = false;
1957
+ var patches = /* @__PURE__ */ new Map();
1900
1958
  function instrumentConsole(agent) {
1901
1959
  agentRef4 = agent;
1902
- if (patched3) return;
1903
- patched3 = true;
1960
+ active5 = true;
1904
1961
  for (const level of LEVELS) {
1905
- const orig = console[level].bind(console);
1906
- console[level] = function flightboxConsole(...args) {
1962
+ if (patches.has(level)) continue;
1963
+ const orig = console[level];
1964
+ const bound = orig.bind(console);
1965
+ const wrapper = function flightboxConsole(...args) {
1907
1966
  try {
1908
- if (!isShedding()) {
1967
+ if (active5 && !isShedding()) {
1909
1968
  const msg = capScrub((0, import_node_util.formatWithOptions)(FORMAT_OPTS, ...args), LIMITS.log);
1910
1969
  agentRef4.recorder.record(8 /* Log */, { level, msg });
1911
1970
  }
1912
1971
  } catch {
1913
1972
  }
1914
- orig(...args);
1973
+ bound(...args);
1915
1974
  };
1975
+ patches.set(level, { orig, wrapper });
1976
+ console[level] = wrapper;
1977
+ }
1978
+ }
1979
+ function restoreConsole() {
1980
+ active5 = false;
1981
+ for (const [level, p] of patches) {
1982
+ if (console[level] === p.wrapper) {
1983
+ console[level] = p.orig;
1984
+ patches.delete(level);
1985
+ }
1916
1986
  }
1917
1987
  }
1918
1988
 
@@ -1934,6 +2004,21 @@ function applyInstrumentations(agent) {
1934
2004
  }
1935
2005
  }
1936
2006
  }
2007
+ var RESTORATIONS = [
2008
+ ["http-server", restoreHttpServer],
2009
+ ["http-client", restoreHttpClient],
2010
+ ["pg", restorePg],
2011
+ ["console", restoreConsole]
2012
+ ];
2013
+ function removeInstrumentations(log) {
2014
+ for (const [name, restore] of RESTORATIONS) {
2015
+ try {
2016
+ restore();
2017
+ } catch (err) {
2018
+ log(`instrumentation ${name} failed to restore: ${err.message}`);
2019
+ }
2020
+ }
2021
+ }
1937
2022
 
1938
2023
  // src/instrumentations/vitals.ts
1939
2024
  var import_node_perf_hooks = require("perf_hooks");
@@ -2215,6 +2300,7 @@ function stop() {
2215
2300
  } catch {
2216
2301
  }
2217
2302
  }
2303
+ removeInstrumentations(instance.config.log);
2218
2304
  instance.panicWriter.disarm();
2219
2305
  setShedding(false);
2220
2306
  instance = null;