useSpanList.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {Location} from 'history';
  2. import omit from 'lodash/omit';
  3. import {defined} from 'sentry/utils';
  4. import EventView from 'sentry/utils/discover/eventView';
  5. import type {Sort} from 'sentry/utils/discover/fields';
  6. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  7. import {useLocation} from 'sentry/utils/useLocation';
  8. import {ModuleName, SpanMetricsFields} from 'sentry/views/starfish/types';
  9. import {useWrappedDiscoverQuery} from 'sentry/views/starfish/utils/useSpansQuery';
  10. import {NULL_SPAN_CATEGORY} from 'sentry/views/starfish/views/webServiceView/spanGroupBreakdownContainer';
  11. const {SPAN_SELF_TIME} = SpanMetricsFields;
  12. const SPAN_FILTER_KEYS = ['span.op', 'span.domain', 'span.action', '!span.module'];
  13. export type SpanMetrics = {
  14. 'http_error_count()': number;
  15. 'http_error_count_percent_change()': number;
  16. 'p95(span.self_time)': number;
  17. 'percentile_percent_change(span.self_time, 0.95)': number;
  18. 'span.description': string;
  19. 'span.domain': string;
  20. 'span.group': string;
  21. 'span.op': string;
  22. 'sps()': number;
  23. 'sps_percent_change()': number;
  24. 'sum(span.self_time)': number;
  25. 'time_spent_percentage()': number;
  26. };
  27. export const useSpanList = (
  28. moduleName: ModuleName,
  29. transaction?: string,
  30. method?: string,
  31. spanCategory?: string,
  32. sorts?: Sort[],
  33. limit?: number,
  34. referrer = 'use-span-list',
  35. cursor?: string
  36. ) => {
  37. const location = useLocation();
  38. const eventView = getEventView(
  39. moduleName,
  40. location,
  41. transaction,
  42. method,
  43. spanCategory,
  44. sorts
  45. );
  46. const {isLoading, data, meta, pageLinks} = useWrappedDiscoverQuery<SpanMetrics[]>({
  47. eventView,
  48. initialData: [],
  49. limit,
  50. referrer,
  51. cursor,
  52. });
  53. return {isLoading, data, meta, pageLinks};
  54. };
  55. function getEventView(
  56. moduleName: ModuleName,
  57. location: Location,
  58. transaction?: string,
  59. method?: string,
  60. spanCategory?: string,
  61. sorts?: Sort[]
  62. ) {
  63. const query = buildEventViewQuery(
  64. moduleName,
  65. location,
  66. transaction,
  67. method,
  68. spanCategory
  69. )
  70. .filter(Boolean)
  71. .join(' ');
  72. const eventView = EventView.fromNewQueryWithLocation(
  73. {
  74. name: '',
  75. query,
  76. fields: [
  77. 'span.op',
  78. 'span.group',
  79. 'span.description',
  80. 'span.domain',
  81. 'sps()',
  82. 'sps_percent_change()',
  83. `sum(${SPAN_SELF_TIME})`,
  84. `p95(${SPAN_SELF_TIME})`,
  85. 'time_spent_percentage()',
  86. `percentile_percent_change(${SPAN_SELF_TIME}, 0.95)`,
  87. 'http_error_count()',
  88. 'http_error_count_percent_change()',
  89. ],
  90. dataset: DiscoverDatasets.SPANS_METRICS,
  91. projects: [1],
  92. version: 2,
  93. },
  94. omit(location, 'span.category', 'http.method')
  95. );
  96. if (sorts) {
  97. eventView.sorts = sorts;
  98. }
  99. return eventView;
  100. }
  101. function buildEventViewQuery(
  102. moduleName: ModuleName,
  103. location: Location,
  104. transaction?: string,
  105. method?: string,
  106. spanCategory?: string
  107. ) {
  108. const {query} = location;
  109. const result = Object.keys(query)
  110. .filter(key => SPAN_FILTER_KEYS.includes(key))
  111. .filter(key => Boolean(query[key]))
  112. .map(key => {
  113. return `${key}:${query[key]}`;
  114. });
  115. if (moduleName !== ModuleName.ALL) {
  116. result.push(`span.module:${moduleName}`);
  117. }
  118. if (defined(spanCategory)) {
  119. if (spanCategory === NULL_SPAN_CATEGORY) {
  120. result.push(`!has:span.category`);
  121. } else if (spanCategory !== 'Other') {
  122. result.push(`span.category:${spanCategory}`);
  123. }
  124. }
  125. if (transaction) {
  126. result.push(`transaction:${transaction}`);
  127. }
  128. if (method) {
  129. result.push(`transaction.method:${method}`);
  130. }
  131. return result;
  132. }