tracing.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict';
  2. const process = require('process');
  3. // Safe load: use getBuiltinModule if available, fallback to require, catch if unavailable
  4. const dc = (() => {
  5. try {
  6. return 'getBuiltinModule' in process
  7. ? process.getBuiltinModule('node:diagnostics_channel')
  8. : require('node:diagnostics_channel');
  9. } catch {
  10. return undefined;
  11. }
  12. })();
  13. const hasTracingChannel = typeof dc?.tracingChannel === 'function';
  14. const queryChannel = hasTracingChannel
  15. ? dc.tracingChannel('mysql2:query')
  16. : undefined;
  17. const executeChannel = hasTracingChannel
  18. ? dc.tracingChannel('mysql2:execute')
  19. : undefined;
  20. const connectChannel = hasTracingChannel
  21. ? dc.tracingChannel('mysql2:connect')
  22. : undefined;
  23. const poolConnectChannel = hasTracingChannel
  24. ? dc.tracingChannel('mysql2:pool:connect')
  25. : undefined;
  26. function getServerContext(config) {
  27. if (config.socketPath) {
  28. return { serverAddress: config.socketPath, serverPort: undefined };
  29. }
  30. return {
  31. serverAddress: config.host || 'localhost',
  32. serverPort: config.port || 3306,
  33. };
  34. }
  35. // Node 20+: TracingChannel has an aggregated hasSubscribers getter.
  36. // Node 18.x: that getter is missing (undefined), fall back to start sub-channel.
  37. function shouldTrace(channel) {
  38. if (channel === undefined || channel === null) {
  39. return false;
  40. }
  41. return channel.hasSubscribers ?? channel.start?.hasSubscribers ?? false;
  42. }
  43. // Generic traceCallback wrapper — calls fn synchronously, wraps the callback
  44. // at args[position] to emit asyncStart/asyncEnd/error. No promises involved.
  45. function traceCallback(channel, fn, position, context, thisArg, ...args) {
  46. if (shouldTrace(channel)) {
  47. return channel.traceCallback(fn, position, context(), thisArg, ...args);
  48. }
  49. return fn.apply(thisArg, args);
  50. }
  51. // tracePromise for operations that are inherently async (connection handshake)
  52. function tracePromise(channel, fn, contextFactory) {
  53. if (shouldTrace(channel)) {
  54. return channel.tracePromise(fn, contextFactory());
  55. }
  56. return fn();
  57. }
  58. module.exports = {
  59. dc,
  60. hasTracingChannel,
  61. shouldTrace,
  62. queryChannel,
  63. executeChannel,
  64. connectChannel,
  65. poolConnectChannel,
  66. getServerContext,
  67. traceCallback,
  68. tracePromise,
  69. };