useSpanMetrics.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {Location} from 'history';
  2. import moment, {Moment} from 'moment';
  3. import EventView from 'sentry/utils/discover/eventView';
  4. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  5. import {useLocation} from 'sentry/utils/useLocation';
  6. import usePageFilters from 'sentry/utils/usePageFilters';
  7. import type {IndexedSpan} from 'sentry/views/starfish/queries/types';
  8. import {getDateFilters} from 'sentry/views/starfish/utils/dates';
  9. useSpansQuery;
  10. import {getDateQueryFilter} from 'sentry/views/starfish/utils/getDateQueryFilter';
  11. import {useSpansQuery} from 'sentry/views/starfish/utils/useSpansQuery';
  12. export type SpanMetrics = {
  13. 'first_seen()': string;
  14. 'last_seen()': string;
  15. 'p95(span.duration)': number;
  16. 'spm()': number;
  17. 'sum(span.duration)': number;
  18. 'time_spent_percentage()': number;
  19. };
  20. export const useSpanMetrics = (
  21. span?: Pick<IndexedSpan, 'group'>,
  22. queryFilters: {transactionName?: string} = {},
  23. _referrer = 'span-metrics'
  24. ) => {
  25. const location = useLocation();
  26. const pageFilters = usePageFilters();
  27. const {startTime, endTime} = getDateFilters(pageFilters);
  28. const dateFilters = getDateQueryFilter(startTime, endTime);
  29. const filters: string[] = [];
  30. if (queryFilters.transactionName) {
  31. filters.push(`transaction = ${queryFilters.transactionName}`);
  32. }
  33. const query = span
  34. ? getQuery(span, startTime, endTime, dateFilters, queryFilters.transactionName)
  35. : '';
  36. const eventView = span
  37. ? getEventView(span, location, queryFilters.transactionName)
  38. : undefined;
  39. // TODO: Add referrer
  40. const {isLoading, data} = useSpansQuery<SpanMetrics[]>({
  41. eventView,
  42. queryString: query,
  43. initialData: [],
  44. enabled: Boolean(query),
  45. });
  46. return {isLoading, data: data[0] ?? {}};
  47. };
  48. function getQuery(
  49. span: {group: string},
  50. startTime: Moment,
  51. endTime: Moment,
  52. dateFilters: string,
  53. transaction?: string
  54. ) {
  55. return `
  56. SELECT
  57. count() as count,
  58. min(timestamp) as "first_seen()",
  59. max(timestamp) as "last_seen()",
  60. quantile(0.95)(exclusive_time) as "p95(span.duration)",
  61. sum(exclusive_time) as "sum(span.duration)",
  62. divide(count(), ${
  63. moment(endTime ?? undefined).unix() - moment(startTime).unix()
  64. }) as "spm()"
  65. FROM spans_experimental_starfish
  66. WHERE group_id = '${span.group}'
  67. ${dateFilters}
  68. ${transaction ? `AND transaction = '${transaction}'` : ''}
  69. `;
  70. }
  71. function getEventView(span: {group: string}, location: Location, transaction?: string) {
  72. const cleanGroupId = span.group.replaceAll('-', '').slice(-16);
  73. return EventView.fromNewQueryWithLocation(
  74. {
  75. name: '',
  76. query: `span.group:${cleanGroupId}${
  77. transaction ? ` transaction:${transaction}` : ''
  78. }`,
  79. fields: [
  80. 'spm()',
  81. 'sum(span.duration)',
  82. 'p95(span.duration)',
  83. 'time_spent_percentage()',
  84. ],
  85. dataset: DiscoverDatasets.SPANS_METRICS,
  86. projects: [1],
  87. version: 2,
  88. },
  89. location
  90. );
  91. }