events.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import {LocationDescriptor} from 'history';
  2. import pick from 'lodash/pick';
  3. import {Client} from 'app/api';
  4. import {canIncludePreviousPeriod} from 'app/components/charts/utils';
  5. import {
  6. DateString,
  7. EventsStats,
  8. MultiSeriesEventsStats,
  9. OrganizationSummary,
  10. } from 'app/types';
  11. import {LocationQuery} from 'app/utils/discover/eventView';
  12. import {getPeriod} from 'app/utils/getPeriod';
  13. import {PERFORMANCE_URL_PARAM} from 'app/utils/performance/constants';
  14. type Options = {
  15. organization: OrganizationSummary;
  16. project?: Readonly<number[]>;
  17. environment?: Readonly<string[]>;
  18. team?: Readonly<string | string[]>;
  19. period?: string;
  20. start?: DateString;
  21. end?: DateString;
  22. interval?: string;
  23. includePrevious?: boolean;
  24. limit?: number;
  25. query?: string;
  26. yAxis?: string | string[];
  27. field?: string[];
  28. topEvents?: number;
  29. orderby?: string;
  30. partial: boolean;
  31. };
  32. /**
  33. * Make requests to `events-stats` endpoint
  34. *
  35. * @param {Object} api API client instance
  36. * @param {Object} options Request parameters
  37. * @param {Object} options.organization Organization object
  38. * @param {Number[]} options.project List of project ids
  39. * @param {String[]} options.environment List of environments to query for
  40. * @param {String[]} options.team List of teams to query for
  41. * @param {String} options.period Time period to query for, in the format: <integer><units> where units are "d" or "h"
  42. * @param {String} options.interval Time interval to group results in, in the format: <integer><units> where units are "d", "h", "m", "s"
  43. * @param {Boolean} options.includePrevious Should request also return reqsults for previous period?
  44. * @param {Number} options.limit The number of rows to return
  45. * @param {String} options.query Search query
  46. */
  47. export const doEventsRequest = (
  48. api: Client,
  49. {
  50. organization,
  51. project,
  52. environment,
  53. team,
  54. period,
  55. start,
  56. end,
  57. interval,
  58. includePrevious,
  59. query,
  60. yAxis,
  61. field,
  62. topEvents,
  63. orderby,
  64. partial,
  65. }: Options
  66. ): Promise<EventsStats | MultiSeriesEventsStats> => {
  67. const shouldDoublePeriod = canIncludePreviousPeriod(includePrevious, period);
  68. const urlQuery = Object.fromEntries(
  69. Object.entries({
  70. interval,
  71. project,
  72. environment,
  73. team,
  74. query,
  75. yAxis,
  76. field,
  77. topEvents,
  78. orderby,
  79. partial: partial ? '1' : undefined,
  80. }).filter(([, value]) => typeof value !== 'undefined')
  81. );
  82. // Doubling period for absolute dates is not accurate unless starting and
  83. // ending times are the same (at least for daily intervals). This is
  84. // the tradeoff for now.
  85. const periodObj = getPeriod({period, start, end}, {shouldDoublePeriod});
  86. return api.requestPromise(`/organizations/${organization.slug}/events-stats/`, {
  87. query: {
  88. ...urlQuery,
  89. ...periodObj,
  90. },
  91. });
  92. };
  93. export type EventQuery = {
  94. field: string[];
  95. team?: string | string[];
  96. project?: string | string[];
  97. sort?: string | string[];
  98. query: string;
  99. per_page?: number;
  100. referrer?: string;
  101. environment?: string[];
  102. noPagination?: boolean;
  103. };
  104. export type TagSegment = {
  105. count: number;
  106. name: string;
  107. value: string;
  108. url: LocationDescriptor;
  109. isOther?: boolean;
  110. key?: string;
  111. };
  112. export type Tag = {
  113. key: string;
  114. topValues: Array<TagSegment>;
  115. };
  116. /**
  117. * Fetches tag facets for a query
  118. */
  119. export async function fetchTagFacets(
  120. api: Client,
  121. orgSlug: string,
  122. query: EventQuery
  123. ): Promise<Tag[]> {
  124. const urlParams = pick(query, Object.values(PERFORMANCE_URL_PARAM));
  125. const queryOption = {...urlParams, query: query.query};
  126. return api.requestPromise(`/organizations/${orgSlug}/events-facets/`, {
  127. query: queryOption,
  128. });
  129. }
  130. /**
  131. * Fetches total count of events for a given query
  132. */
  133. export async function fetchTotalCount(
  134. api: Client,
  135. orgSlug: String,
  136. query: EventQuery & LocationQuery
  137. ): Promise<number> {
  138. const urlParams = pick(query, Object.values(PERFORMANCE_URL_PARAM));
  139. const queryOption = {...urlParams, query: query.query};
  140. type Response = {
  141. count: number;
  142. };
  143. return api
  144. .requestPromise(`/organizations/${orgSlug}/events-meta/`, {
  145. query: queryOption,
  146. })
  147. .then((res: Response) => res.count);
  148. }