trace.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import type {Location} from 'history';
  2. import {getContextKeys} from 'sentry/components/events/contexts/utils';
  3. import {generateTraceTarget} from 'sentry/components/quickTrace/utils';
  4. import {t} from 'sentry/locale';
  5. import type {Event} from 'sentry/types/event';
  6. import type {KeyValueListData} from 'sentry/types/group';
  7. import type {Organization} from 'sentry/types/organization';
  8. import {defined} from 'sentry/utils';
  9. import {transactionSummaryRouteWithQuery} from 'sentry/views/performance/transactionSummary/utils';
  10. enum TraceContextKeys {
  11. TRACE_ID = 'trace_id',
  12. SPAN_ID = 'span_id',
  13. PARENT_SPAN_ID = 'parent_span_id',
  14. OP_NAME = 'op',
  15. STATUS = 'status',
  16. EXCLUSIVE_TIME = 'exclusive_time',
  17. CLIENT_SAMPLE_RATE = 'client_sample_rate',
  18. DYNAMIC_SAMPLING_CONTEXT = 'dynamic_sampling_context',
  19. ORIGIN = 'origin',
  20. DATA = 'data',
  21. }
  22. export interface TraceContext {
  23. // Any custom keys users may set
  24. [key: string]: any;
  25. [TraceContextKeys.TRACE_ID]?: string;
  26. [TraceContextKeys.SPAN_ID]?: string;
  27. [TraceContextKeys.PARENT_SPAN_ID]?: string;
  28. [TraceContextKeys.OP_NAME]?: string;
  29. [TraceContextKeys.STATUS]?: string;
  30. [TraceContextKeys.EXCLUSIVE_TIME]?: number;
  31. [TraceContextKeys.CLIENT_SAMPLE_RATE]?: number;
  32. [TraceContextKeys.DYNAMIC_SAMPLING_CONTEXT]?: Record<string, string>;
  33. [TraceContextKeys.ORIGIN]?: string;
  34. [TraceContextKeys.DATA]?: Record<string, any>;
  35. }
  36. export function getTraceContextData({
  37. data,
  38. event,
  39. location,
  40. organization,
  41. meta,
  42. }: {
  43. data: TraceContext;
  44. event: Event;
  45. location: Location;
  46. organization: Organization;
  47. meta?: Record<keyof TraceContext, any>;
  48. }): KeyValueListData {
  49. return getContextKeys({data})
  50. .map(ctxKey => {
  51. switch (ctxKey) {
  52. case TraceContextKeys.TRACE_ID: {
  53. const traceId = data.trace_id || '';
  54. if (!traceId) {
  55. return undefined;
  56. }
  57. const link = generateTraceTarget(event, organization, location);
  58. return {
  59. key: ctxKey,
  60. subject: t('Trace ID'),
  61. value: traceId,
  62. action: {link},
  63. };
  64. }
  65. case TraceContextKeys.SPAN_ID: {
  66. return {
  67. key: ctxKey,
  68. subject: t('Span ID'),
  69. value: data.span_id || '',
  70. };
  71. }
  72. case TraceContextKeys.PARENT_SPAN_ID: {
  73. return {
  74. key: ctxKey,
  75. subject: t('Parent Span ID'),
  76. value: data.parent_span_id || '',
  77. };
  78. }
  79. case TraceContextKeys.OP_NAME: {
  80. return {
  81. key: ctxKey,
  82. subject: t('Operation Name'),
  83. value: data.op || '',
  84. };
  85. }
  86. case TraceContextKeys.STATUS: {
  87. return {
  88. key: ctxKey,
  89. subject: t('Status'),
  90. value: data.status || '',
  91. };
  92. }
  93. case TraceContextKeys.EXCLUSIVE_TIME: {
  94. return {
  95. key: ctxKey,
  96. subject: t('Exclusive Time (ms)'),
  97. value: data.exclusive_time,
  98. };
  99. }
  100. case TraceContextKeys.CLIENT_SAMPLE_RATE: {
  101. return {
  102. key: ctxKey,
  103. subject: t('Client Sample Rate'),
  104. value: data.client_sample_rate,
  105. };
  106. }
  107. case TraceContextKeys.DYNAMIC_SAMPLING_CONTEXT: {
  108. return {
  109. key: ctxKey,
  110. subject: t('Dynamic Sampling Context'),
  111. value: data.dynamic_sampling_context,
  112. };
  113. }
  114. case TraceContextKeys.ORIGIN: {
  115. return {
  116. key: ctxKey,
  117. subject: t('Origin'),
  118. value: data.origin,
  119. };
  120. }
  121. case TraceContextKeys.DATA: {
  122. return {
  123. key: ctxKey,
  124. subject: t('Data'),
  125. value: data.data,
  126. };
  127. }
  128. case 'transaction_name': {
  129. const eventTag = event?.tags.find(tag => {
  130. return tag.key === 'transaction';
  131. });
  132. if (!eventTag || typeof eventTag.value !== 'string') {
  133. return undefined;
  134. }
  135. const transactionName = eventTag.value;
  136. if (!organization.features.includes('performance-view')) {
  137. return {
  138. key: ctxKey,
  139. subject: t('Transaction'),
  140. value: transactionName,
  141. };
  142. }
  143. const link = transactionSummaryRouteWithQuery({
  144. orgSlug: organization.slug,
  145. transaction: transactionName,
  146. projectID: event.projectID,
  147. query: {},
  148. });
  149. return {
  150. key: ctxKey,
  151. subject: t('Transaction'),
  152. value: transactionName,
  153. action: {link},
  154. };
  155. }
  156. default:
  157. return {
  158. key: ctxKey,
  159. subject: ctxKey,
  160. value: data[ctxKey],
  161. meta: meta?.[ctxKey]?.[''],
  162. };
  163. }
  164. })
  165. .filter(defined);
  166. }