similarQueryView.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {Fragment} from 'react';
  2. import {useTheme} from '@emotion/react';
  3. import GridEditable from 'sentry/components/gridEditable';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. import {
  6. DataRow,
  7. Keys,
  8. similarity,
  9. TableColumnHeader,
  10. } from 'sentry/views/starfish/modules/databaseModule/databaseTableView';
  11. import {useQueryMainTable} from 'sentry/views/starfish/modules/databaseModule/queries';
  12. type Props = {
  13. mainTableRow: DataRow;
  14. };
  15. const COLUMN_ORDER: TableColumnHeader[] = [
  16. {
  17. key: 'description',
  18. name: 'Query',
  19. width: 300,
  20. },
  21. {
  22. key: 'epm',
  23. name: 'Tpm',
  24. },
  25. {
  26. key: 'p50',
  27. name: 'p50',
  28. },
  29. {
  30. key: 'p95',
  31. name: 'p95',
  32. },
  33. {
  34. key: 'total_time',
  35. name: 'Total Time',
  36. },
  37. ];
  38. function SimilarQueryView(props: Props) {
  39. const {mainTableRow} = props;
  40. const {isLoading, data} = useQueryMainTable({
  41. limit: 410,
  42. });
  43. const location = useLocation();
  44. const theme = useTheme();
  45. const similarQueries = data.filter(
  46. row => similarity(row.description, mainTableRow.description) > 0.8
  47. );
  48. const renderHeadCell = (col): React.ReactNode => {
  49. return <span>{col.name}</span>;
  50. };
  51. const renderBodyCell = (column: TableColumnHeader, row: DataRow): React.ReactNode => {
  52. const {key} = column;
  53. let renderedValue: React.ReactNode = row[key];
  54. if (key === 'description') {
  55. const mainTableQueryWords = new Set(mainTableRow.description.split(' '));
  56. const diffQuery = (
  57. <div>
  58. {row.description.split(' ').map(word => {
  59. if (mainTableQueryWords.has(word)) {
  60. return `${word} `;
  61. }
  62. return (
  63. <span style={{color: theme.green400}} key={word}>
  64. {`${word} `}
  65. </span>
  66. );
  67. })}
  68. </div>
  69. );
  70. renderedValue = diffQuery;
  71. }
  72. const timeBasedKeys: Keys[] = ['p50', 'p95', 'total_time'];
  73. if ((['epm', ...timeBasedKeys] as Keys[]).includes(key)) {
  74. const val = row[key] as number;
  75. const mainTableVal = mainTableRow[key] as number;
  76. const sign = val > mainTableVal ? '+' : '';
  77. const percentage = (val / mainTableVal - 1) * 100;
  78. let unit = '';
  79. if (timeBasedKeys.includes(key)) {
  80. unit = 'ms';
  81. }
  82. renderedValue = (
  83. <Fragment>
  84. {val.toFixed(3)}
  85. {unit} ({sign}
  86. <span style={{color: sign ? theme.red400 : theme.green400}}>
  87. {percentage.toFixed(2)}%
  88. </span>
  89. )
  90. </Fragment>
  91. );
  92. }
  93. return <span>{renderedValue}</span>;
  94. };
  95. if (!isLoading && similarQueries.length > 0) {
  96. return (
  97. <GridEditable
  98. isLoading={isLoading}
  99. data={similarQueries as any}
  100. columnOrder={COLUMN_ORDER}
  101. columnSortBy={[]}
  102. grid={{
  103. renderHeadCell,
  104. renderBodyCell,
  105. }}
  106. location={location}
  107. />
  108. );
  109. }
  110. return <Fragment />;
  111. }
  112. export default SimilarQueryView;