useSpanList.tsx 3.1 KB

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