event.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. import type {TraceContextType} from 'sentry/components/events/interfaces/spans/types';
  2. import type {SymbolicatorStatus} from 'sentry/components/events/interfaces/types';
  3. import type {PlatformKey} from 'sentry/data/platformCategories';
  4. import type {RawCrumb} from './breadcrumbs';
  5. import type {Image} from './debugImage';
  6. import type {IssueAttachment, IssueCategory} from './group';
  7. import type {Release} from './release';
  8. import type {RawStacktrace, StackTraceMechanism, StacktraceType} from './stacktrace';
  9. // TODO(epurkhiser): objc and cocoa should almost definitely be moved into PlatformKey
  10. export type PlatformType = PlatformKey | 'objc' | 'cocoa';
  11. export type Level = 'error' | 'fatal' | 'info' | 'warning' | 'sample' | 'unknown';
  12. /**
  13. * Grouping Configuration.
  14. */
  15. export type EventGroupComponent = {
  16. contributes: boolean;
  17. hint: string | null;
  18. id: string;
  19. name: string | null;
  20. values: EventGroupComponent[] | string[];
  21. };
  22. export type EventGroupingConfig = {
  23. base: string | null;
  24. changelog: string;
  25. delegates: string[];
  26. hidden: boolean;
  27. id: string;
  28. latest: boolean;
  29. risk: number;
  30. strategies: string[];
  31. };
  32. export type VariantEvidence = {
  33. desc: string;
  34. fingerprint: string;
  35. cause_span_hashes?: string[];
  36. offender_span_hashes?: string[];
  37. op?: string;
  38. parent_span_hashes?: string[];
  39. };
  40. type EventGroupVariantKey = 'custom-fingerprint' | 'app' | 'default' | 'system';
  41. export enum EventGroupVariantType {
  42. CHECKSUM = 'checksum',
  43. FALLBACK = 'fallback',
  44. CUSTOM_FINGERPRINT = 'custom-fingerprint',
  45. COMPONENT = 'component',
  46. SALTED_COMPONENT = 'salted-component',
  47. PERFORMANCE_PROBLEM = 'performance-problem',
  48. }
  49. interface BaseVariant {
  50. description: string | null;
  51. hash: string | null;
  52. hashMismatch: boolean;
  53. key: string;
  54. type: string;
  55. }
  56. interface FallbackVariant extends BaseVariant {
  57. type: EventGroupVariantType.FALLBACK;
  58. }
  59. interface ChecksumVariant extends BaseVariant {
  60. type: EventGroupVariantType.CHECKSUM;
  61. }
  62. interface HasComponentGrouping {
  63. client_values?: Array<string>;
  64. component?: EventGroupComponent;
  65. config?: EventGroupingConfig;
  66. matched_rule?: string;
  67. values?: Array<string>;
  68. }
  69. interface ComponentVariant extends BaseVariant, HasComponentGrouping {
  70. type: EventGroupVariantType.COMPONENT;
  71. }
  72. interface CustomFingerprintVariant extends BaseVariant, HasComponentGrouping {
  73. type: EventGroupVariantType.CUSTOM_FINGERPRINT;
  74. }
  75. interface SaltedComponentVariant extends BaseVariant, HasComponentGrouping {
  76. type: EventGroupVariantType.SALTED_COMPONENT;
  77. }
  78. interface PerformanceProblemVariant extends BaseVariant {
  79. evidence: VariantEvidence;
  80. type: EventGroupVariantType.PERFORMANCE_PROBLEM;
  81. }
  82. export type EventGroupVariant =
  83. | FallbackVariant
  84. | ChecksumVariant
  85. | ComponentVariant
  86. | SaltedComponentVariant
  87. | CustomFingerprintVariant
  88. | PerformanceProblemVariant;
  89. export type EventGroupInfo = Record<EventGroupVariantKey, EventGroupVariant>;
  90. /**
  91. * SDK Update metadata
  92. */
  93. type EnableIntegrationSuggestion = {
  94. enables: Array<SDKUpdatesSuggestion>;
  95. integrationName: string;
  96. type: 'enableIntegration';
  97. integrationUrl?: string | null;
  98. };
  99. export type UpdateSdkSuggestion = {
  100. enables: Array<SDKUpdatesSuggestion>;
  101. newSdkVersion: string;
  102. sdkName: string;
  103. type: 'updateSdk';
  104. sdkUrl?: string | null;
  105. };
  106. type ChangeSdkSuggestion = {
  107. enables: Array<SDKUpdatesSuggestion>;
  108. newSdkName: string;
  109. type: 'changeSdk';
  110. sdkUrl?: string | null;
  111. };
  112. export type SDKUpdatesSuggestion =
  113. | EnableIntegrationSuggestion
  114. | UpdateSdkSuggestion
  115. | ChangeSdkSuggestion;
  116. /**
  117. * Frames, Threads and Event interfaces.
  118. */
  119. export interface Thread {
  120. crashed: boolean;
  121. current: boolean;
  122. id: number;
  123. rawStacktrace: RawStacktrace;
  124. stacktrace: StacktraceType | null;
  125. name?: string | null;
  126. }
  127. export type Frame = {
  128. absPath: string | null;
  129. colNo: number | null;
  130. context: Array<[number, string]>;
  131. errors: Array<any> | null;
  132. filename: string | null;
  133. function: string | null;
  134. inApp: boolean;
  135. instructionAddr: string | null;
  136. lineNo: number | null;
  137. module: string | null;
  138. package: string | null;
  139. platform: PlatformType | null;
  140. rawFunction: string | null;
  141. symbol: string | null;
  142. symbolAddr: string | null;
  143. trust: any | null;
  144. vars: Record<string, any> | null;
  145. addrMode?: string;
  146. isPrefix?: boolean;
  147. isSentinel?: boolean;
  148. map?: string | null;
  149. mapUrl?: string | null;
  150. minGroupingLevel?: number;
  151. origAbsPath?: string | null;
  152. symbolicatorStatus?: SymbolicatorStatus;
  153. };
  154. export enum FrameBadge {
  155. SENTINEL = 'sentinel',
  156. PREFIX = 'prefix',
  157. GROUPING = 'grouping',
  158. }
  159. export type ExceptionValue = {
  160. mechanism: StackTraceMechanism | null;
  161. module: string | null;
  162. rawStacktrace: RawStacktrace;
  163. stacktrace: StacktraceType | null;
  164. threadId: number | null;
  165. type: string;
  166. value: string;
  167. frames?: Frame[] | null;
  168. };
  169. export type ExceptionType = {
  170. excOmitted: any | null;
  171. hasSystemFrames: boolean;
  172. values?: Array<ExceptionValue>;
  173. };
  174. export type TreeLabelPart =
  175. | string
  176. | {
  177. classbase?: string;
  178. datapath?: (string | number)[];
  179. filebase?: string;
  180. function?: string;
  181. is_prefix?: boolean;
  182. // is_sentinel is no longer being used,
  183. // but we will still assess whether we will use this property in the near future.
  184. is_sentinel?: boolean;
  185. package?: string;
  186. type?: string;
  187. };
  188. // This type is incomplete
  189. export type EventMetadata = {
  190. current_level?: number;
  191. current_tree_label?: TreeLabelPart[];
  192. directive?: string;
  193. display_title_with_tree_label?: boolean;
  194. filename?: string;
  195. finest_tree_label?: TreeLabelPart[];
  196. function?: string;
  197. message?: string;
  198. origin?: string;
  199. stripped_crash?: boolean;
  200. title?: string;
  201. type?: string;
  202. uri?: string;
  203. value?: string;
  204. };
  205. export enum EventOrGroupType {
  206. ERROR = 'error',
  207. CSP = 'csp',
  208. HPKP = 'hpkp',
  209. EXPECTCT = 'expectct',
  210. EXPECTSTAPLE = 'expectstaple',
  211. DEFAULT = 'default',
  212. TRANSACTION = 'transaction',
  213. }
  214. /**
  215. * Event interface types.
  216. */
  217. export enum EntryType {
  218. EXCEPTION = 'exception',
  219. MESSAGE = 'message',
  220. REQUEST = 'request',
  221. STACKTRACE = 'stacktrace',
  222. TEMPLATE = 'template',
  223. CSP = 'csp',
  224. EXPECTCT = 'expectct',
  225. EXPECTSTAPLE = 'expectstaple',
  226. HPKP = 'hpkp',
  227. BREADCRUMBS = 'breadcrumbs',
  228. THREADS = 'threads',
  229. DEBUGMETA = 'debugmeta',
  230. SPANS = 'spans',
  231. RESOURCES = 'resources',
  232. }
  233. type EntryDebugMeta = {
  234. data: {
  235. images: Array<Image | null>;
  236. };
  237. type: EntryType.DEBUGMETA;
  238. };
  239. type EntryBreadcrumbs = {
  240. data: {
  241. values: Array<RawCrumb>;
  242. };
  243. type: EntryType.BREADCRUMBS;
  244. };
  245. export type EntryThreads = {
  246. data: {
  247. values?: Array<Thread>;
  248. };
  249. type: EntryType.THREADS;
  250. };
  251. export type EntryException = {
  252. data: ExceptionType;
  253. type: EntryType.EXCEPTION;
  254. };
  255. type EntryStacktrace = {
  256. data: StacktraceType;
  257. type: EntryType.STACKTRACE;
  258. };
  259. type EntrySpans = {
  260. data: any;
  261. type: EntryType.SPANS;
  262. };
  263. type EntryMessage = {
  264. data: {
  265. formatted: string;
  266. params?: Record<string, any> | any[];
  267. };
  268. type: EntryType.MESSAGE;
  269. };
  270. export type EntryRequest = {
  271. data: {
  272. method: string;
  273. url: string;
  274. cookies?: [key: string, value: string][];
  275. data?: string | null | Record<string, any> | [key: string, value: any][];
  276. env?: Record<string, string>;
  277. fragment?: string | null;
  278. headers?: [key: string, value: string][];
  279. inferredContentType?:
  280. | null
  281. | 'application/json'
  282. | 'application/x-www-form-urlencoded'
  283. | 'multipart/form-data';
  284. query?: [key: string, value: string][] | string;
  285. };
  286. type: EntryType.REQUEST;
  287. };
  288. type EntryTemplate = {
  289. data: Frame;
  290. type: EntryType.TEMPLATE;
  291. };
  292. type EntryCsp = {
  293. data: Record<string, any>;
  294. type: EntryType.CSP;
  295. };
  296. type EntryGeneric = {
  297. data: Record<string, any>;
  298. type: EntryType.EXPECTCT | EntryType.EXPECTSTAPLE | EntryType.HPKP;
  299. };
  300. type EntryResources = {
  301. data: any; // Data is unused here
  302. type: EntryType.RESOURCES;
  303. };
  304. export type Entry =
  305. | EntryDebugMeta
  306. | EntryBreadcrumbs
  307. | EntryThreads
  308. | EntryException
  309. | EntryStacktrace
  310. | EntrySpans
  311. | EntryMessage
  312. | EntryRequest
  313. | EntryTemplate
  314. | EntryCsp
  315. | EntryGeneric
  316. | EntryResources;
  317. // Contexts: https://develop.sentry.dev/sdk/event-payloads/contexts/
  318. export interface BaseContext {
  319. type: string;
  320. }
  321. export enum DeviceContextKey {
  322. ARCH = 'arch',
  323. BATTERY_LEVEL = 'battery_level',
  324. BATTERY_STATUS = 'battery_status',
  325. BOOT_TIME = 'boot_time',
  326. BRAND = 'brand',
  327. CHARGING = 'charging',
  328. CPU_DESCRIPTION = 'cpu_description',
  329. DEVICE_TYPE = 'device_type',
  330. DEVICE_UNIQUE_IDENTIFIER = 'device_unique_identifier',
  331. EXTERNAL_FREE_STORAGE = 'external_free_storage',
  332. EXTERNAL_STORAGE_SIZE = 'external_storage_size',
  333. EXTERNAL_TOTAL_STORAGE = 'external_total_storage',
  334. FAMILY = 'family',
  335. FREE_MEMORY = 'free_memory',
  336. FREE_STORAGE = 'free_storage',
  337. LOW_MEMORY = 'low_memory',
  338. MANUFACTURER = 'manufacturer',
  339. MEMORY_SIZE = 'memory_size',
  340. MODEL = 'model',
  341. MODEL_ID = 'model_id',
  342. NAME = 'name',
  343. ONLINE = 'online',
  344. ORIENTATION = 'orientation',
  345. PROCESSOR_COUNT = 'processor_count',
  346. PROCESSOR_FREQUENCY = 'processor_frequency',
  347. SCREEN_DENSITY = 'screen_density',
  348. SCREEN_DPI = 'screen_dpi',
  349. SCREEN_HEIGHT_PIXELS = 'screen_height_pixels',
  350. SCREEN_RESOLUTION = 'screen_resolution',
  351. SCREEN_WIDTH_PIXELS = 'screen_width_pixels',
  352. SIMULATOR = 'simulator',
  353. STORAGE_SIZE = 'storage_size',
  354. SUPPORTS_ACCELEROMETER = 'supports_accelerometer',
  355. SUPPORTS_AUDIO = 'supports_audio',
  356. SUPPORTS_GYROSCOPE = 'supports_gyroscope',
  357. SUPPORTS_LOCATION_SERVICE = 'supports_location_service',
  358. SUPPORTS_VIBRATION = 'supports_vibration',
  359. USABLE_MEMORY = 'usable_memory',
  360. }
  361. // https://develop.sentry.dev/sdk/event-payloads/contexts/#device-context
  362. export interface DeviceContext
  363. extends Partial<Record<DeviceContextKey, unknown>>,
  364. BaseContext {
  365. type: 'device';
  366. [DeviceContextKey.NAME]: string;
  367. [DeviceContextKey.ARCH]?: string;
  368. [DeviceContextKey.BATTERY_LEVEL]?: number;
  369. [DeviceContextKey.BATTERY_STATUS]?: string;
  370. [DeviceContextKey.BOOT_TIME]?: string;
  371. [DeviceContextKey.BRAND]?: string;
  372. [DeviceContextKey.CHARGING]?: boolean;
  373. [DeviceContextKey.CPU_DESCRIPTION]?: string;
  374. [DeviceContextKey.DEVICE_TYPE]?: string;
  375. [DeviceContextKey.DEVICE_UNIQUE_IDENTIFIER]?: string;
  376. [DeviceContextKey.EXTERNAL_FREE_STORAGE]?: number;
  377. [DeviceContextKey.EXTERNAL_STORAGE_SIZE]?: number;
  378. [DeviceContextKey.EXTERNAL_TOTAL_STORAGE]?: number;
  379. [DeviceContextKey.FAMILY]?: string;
  380. [DeviceContextKey.FREE_MEMORY]?: number;
  381. [DeviceContextKey.FREE_STORAGE]?: number;
  382. [DeviceContextKey.LOW_MEMORY]?: boolean;
  383. [DeviceContextKey.MANUFACTURER]?: string;
  384. [DeviceContextKey.MEMORY_SIZE]?: number;
  385. [DeviceContextKey.MODEL]?: string;
  386. [DeviceContextKey.MODEL_ID]?: string;
  387. [DeviceContextKey.ONLINE]?: boolean;
  388. [DeviceContextKey.ORIENTATION]?: 'portrait' | 'landscape';
  389. [DeviceContextKey.PROCESSOR_COUNT]?: number;
  390. [DeviceContextKey.PROCESSOR_FREQUENCY]?: number;
  391. [DeviceContextKey.SCREEN_DENSITY]?: number;
  392. [DeviceContextKey.SCREEN_DPI]?: number;
  393. [DeviceContextKey.SCREEN_HEIGHT_PIXELS]?: number;
  394. [DeviceContextKey.SCREEN_RESOLUTION]?: string;
  395. [DeviceContextKey.SCREEN_WIDTH_PIXELS]?: number;
  396. [DeviceContextKey.SIMULATOR]?: boolean;
  397. [DeviceContextKey.STORAGE_SIZE]?: number;
  398. [DeviceContextKey.SUPPORTS_ACCELEROMETER]?: boolean;
  399. [DeviceContextKey.SUPPORTS_AUDIO]?: boolean;
  400. [DeviceContextKey.SUPPORTS_GYROSCOPE]?: boolean;
  401. [DeviceContextKey.SUPPORTS_LOCATION_SERVICE]?: boolean;
  402. [DeviceContextKey.SUPPORTS_VIBRATION]?: boolean;
  403. [DeviceContextKey.USABLE_MEMORY]?: number;
  404. // This field is deprecated in favour of locale field in culture context
  405. language?: string;
  406. // This field is deprecated in favour of timezone field in culture context
  407. timezone?: string;
  408. }
  409. enum RuntimeContextKey {
  410. BUILD = 'build',
  411. NAME = 'name',
  412. RAW_DESCRIPTION = 'raw_description',
  413. VERSION = 'version',
  414. }
  415. // https://develop.sentry.dev/sdk/event-payloads/contexts/#runtime-context
  416. interface RuntimeContext
  417. extends Partial<Record<RuntimeContextKey, unknown>>,
  418. BaseContext {
  419. type: 'runtime';
  420. [RuntimeContextKey.BUILD]?: string;
  421. [RuntimeContextKey.NAME]?: string;
  422. [RuntimeContextKey.RAW_DESCRIPTION]?: string;
  423. [RuntimeContextKey.VERSION]?: number;
  424. }
  425. type OSContext = {
  426. build: string;
  427. kernel_version: string;
  428. name: string;
  429. type: string;
  430. version: string;
  431. };
  432. export enum OtelContextKey {
  433. ATTRIBUTES = 'attributes',
  434. RESOURCE = 'resource',
  435. }
  436. // OpenTelemetry Context
  437. // https://develop.sentry.dev/sdk/performance/opentelemetry/#opentelemetry-context
  438. interface OtelContext extends Partial<Record<OtelContextKey, unknown>>, BaseContext {
  439. type: 'otel';
  440. [OtelContextKey.ATTRIBUTES]?: Record<string, unknown>;
  441. [OtelContextKey.RESOURCE]?: Record<string, unknown>;
  442. }
  443. type EventContexts = {
  444. client_os?: OSContext;
  445. device?: DeviceContext;
  446. feedback?: Record<string, any>;
  447. os?: OSContext;
  448. otel?: OtelContext;
  449. // TODO (udameli): add better types here
  450. // once perf issue data shape is more clear
  451. performance_issue?: any;
  452. runtime?: RuntimeContext;
  453. trace?: TraceContextType;
  454. };
  455. export type Measurement = {value: number; unit?: string};
  456. export type EventTag = {key: string; value: string};
  457. export type EventUser = {
  458. data?: string | null;
  459. email?: string;
  460. id?: string;
  461. ip_address?: string;
  462. name?: string | null;
  463. username?: string | null;
  464. };
  465. export type PerformanceDetectorData = {
  466. causeSpanIds: string[];
  467. offenderSpanIds: string[];
  468. parentSpanIds: string[];
  469. };
  470. interface EventBase {
  471. contexts: EventContexts;
  472. crashFile: IssueAttachment | null;
  473. culprit: string;
  474. dateReceived: string;
  475. dist: string | null;
  476. entries: Entry[];
  477. errors: any[];
  478. eventID: string;
  479. fingerprints: string[];
  480. id: string;
  481. location: string | null;
  482. message: string;
  483. metadata: EventMetadata;
  484. projectID: string;
  485. size: number;
  486. tags: EventTag[];
  487. title: string;
  488. type:
  489. | EventOrGroupType.CSP
  490. | EventOrGroupType.DEFAULT
  491. | EventOrGroupType.EXPECTCT
  492. | EventOrGroupType.EXPECTSTAPLE
  493. | EventOrGroupType.HPKP;
  494. user: EventUser | null;
  495. _meta?: Record<string, any>;
  496. context?: Record<string, any>;
  497. dateCreated?: string;
  498. device?: Record<string, any>;
  499. endTimestamp?: number;
  500. groupID?: string;
  501. groupingConfig?: {
  502. enhancements: string;
  503. id: string;
  504. };
  505. issueCategory?: IssueCategory;
  506. latestEventID?: string | null;
  507. measurements?: Record<string, Measurement>;
  508. nextEventID?: string | null;
  509. oldestEventID?: string | null;
  510. packages?: Record<string, string>;
  511. platform?: PlatformType;
  512. previousEventID?: string | null;
  513. projectSlug?: string;
  514. release?: Release | null;
  515. sdk?: {
  516. name: string;
  517. version: string;
  518. } | null;
  519. sdkUpdates?: Array<SDKUpdatesSuggestion>;
  520. userReport?: any;
  521. }
  522. interface TraceEventContexts extends EventContexts {
  523. trace?: TraceContextType;
  524. }
  525. export interface EventTransaction
  526. extends Omit<EventBase, 'entries' | 'type' | 'contexts'> {
  527. contexts: TraceEventContexts;
  528. endTimestamp: number;
  529. entries: (EntrySpans | EntryRequest)[];
  530. startTimestamp: number;
  531. type: EventOrGroupType.TRANSACTION;
  532. perfProblem?: PerformanceDetectorData;
  533. }
  534. export interface EventError extends Omit<EventBase, 'entries' | 'type'> {
  535. entries: (
  536. | EntryException
  537. | EntryStacktrace
  538. | EntryRequest
  539. | EntryThreads
  540. | EntryDebugMeta
  541. )[];
  542. type: EventOrGroupType.ERROR;
  543. }
  544. export type Event = EventError | EventTransaction | EventBase;
  545. // Response from EventIdLookupEndpoint
  546. // /organizations/${orgSlug}/eventids/${eventId}/
  547. export type EventIdResponse = {
  548. event: Event;
  549. eventId: string;
  550. groupId: string;
  551. organizationSlug: string;
  552. projectSlug: string;
  553. };