mysql.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { _optionalChain } from '@sentry/utils';
  2. import { loadModule, logger, fill } from '@sentry/utils';
  3. import { DEBUG_BUILD } from '../../common/debug-build.js';
  4. import { shouldDisableAutoInstrumentation } from './utils/node-utils.js';
  5. /** Tracing integration for node-mysql package */
  6. class Mysql {
  7. /**
  8. * @inheritDoc
  9. */
  10. static __initStatic() {this.id = 'Mysql';}
  11. /**
  12. * @inheritDoc
  13. */
  14. constructor() {
  15. this.name = Mysql.id;
  16. }
  17. /** @inheritdoc */
  18. loadDependency() {
  19. return (this._module = this._module || loadModule('mysql/lib/Connection.js'));
  20. }
  21. /**
  22. * @inheritDoc
  23. */
  24. setupOnce(_, getCurrentHub) {
  25. if (shouldDisableAutoInstrumentation(getCurrentHub)) {
  26. DEBUG_BUILD && logger.log('Mysql Integration is skipped because of instrumenter configuration.');
  27. return;
  28. }
  29. const pkg = this.loadDependency();
  30. if (!pkg) {
  31. DEBUG_BUILD && logger.error('Mysql Integration was unable to require `mysql` package.');
  32. return;
  33. }
  34. let mySqlConfig = undefined;
  35. try {
  36. pkg.prototype.connect = new Proxy(pkg.prototype.connect, {
  37. apply(wrappingTarget, thisArg, args) {
  38. if (!mySqlConfig) {
  39. mySqlConfig = thisArg.config;
  40. }
  41. return wrappingTarget.apply(thisArg, args);
  42. },
  43. });
  44. } catch (e) {
  45. DEBUG_BUILD && logger.error('Mysql Integration was unable to instrument `mysql` config.');
  46. }
  47. function spanDataFromConfig() {
  48. if (!mySqlConfig) {
  49. return {};
  50. }
  51. return {
  52. 'server.address': mySqlConfig.host,
  53. 'server.port': mySqlConfig.port,
  54. 'db.user': mySqlConfig.user,
  55. };
  56. }
  57. function finishSpan(span) {
  58. if (!span) {
  59. return;
  60. }
  61. const data = spanDataFromConfig();
  62. Object.keys(data).forEach(key => {
  63. span.setAttribute(key, data[key]);
  64. });
  65. span.end();
  66. }
  67. // The original function will have one of these signatures:
  68. // function (callback) => void
  69. // function (options, callback) => void
  70. // function (options, values, callback) => void
  71. fill(pkg, 'createQuery', function (orig) {
  72. return function ( options, values, callback) {
  73. // eslint-disable-next-line deprecation/deprecation
  74. const scope = getCurrentHub().getScope();
  75. // eslint-disable-next-line deprecation/deprecation
  76. const parentSpan = scope.getSpan();
  77. // eslint-disable-next-line deprecation/deprecation
  78. const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({
  79. description: typeof options === 'string' ? options : (options ).sql,
  80. op: 'db',
  81. origin: 'auto.db.mysql',
  82. data: {
  83. 'db.system': 'mysql',
  84. },
  85. })]);
  86. if (typeof callback === 'function') {
  87. return orig.call(this, options, values, function (err, result, fields) {
  88. finishSpan(span);
  89. callback(err, result, fields);
  90. });
  91. }
  92. if (typeof values === 'function') {
  93. return orig.call(this, options, function (err, result, fields) {
  94. finishSpan(span);
  95. values(err, result, fields);
  96. });
  97. }
  98. // streaming, no callback!
  99. const query = orig.call(this, options, values) ;
  100. query.on('end', () => {
  101. finishSpan(span);
  102. });
  103. return query;
  104. };
  105. });
  106. }
  107. }Mysql.__initStatic();
  108. export { Mysql };
  109. //# sourceMappingURL=mysql.js.map