index.ts 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131
  1. import {t} from 'sentry/locale';
  2. import type {TagCollection} from 'sentry/types/group';
  3. import {SpanIndexedField} from 'sentry/views/insights/types';
  4. import {CONDITIONS_ARGUMENTS, WEB_VITALS_QUALITY} from '../discover/types';
  5. // Don't forget to update https://docs.sentry.io/product/sentry-basics/search/searchable-properties/ for any changes made here
  6. export enum FieldKind {
  7. TAG = 'tag',
  8. MEASUREMENT = 'measurement',
  9. BREAKDOWN = 'breakdown',
  10. FIELD = 'field',
  11. ISSUE_FIELD = 'issue_field',
  12. EVENT_FIELD = 'event_field',
  13. FUNCTION = 'function',
  14. EQUATION = 'equation',
  15. METRICS = 'metric',
  16. NUMERIC_METRICS = 'numeric_metric',
  17. }
  18. export enum FieldKey {
  19. AGE = 'age',
  20. ASSIGNED = 'assigned',
  21. ASSIGNED_OR_SUGGESTED = 'assigned_or_suggested',
  22. BOOKMARKS = 'bookmarks',
  23. BROWSER_NAME = 'browser.name',
  24. CULPRIT = 'culprit',
  25. DEVICE_ARCH = 'device.arch',
  26. DEVICE_BATTERY_LEVEL = 'device.battery_level',
  27. DEVICE_BRAND = 'device.brand',
  28. DEVICE_CHARGING = 'device.charging',
  29. // device.class is a synthesized field calculated based off device info found in context such
  30. // as model (for iOS devices), and device specs like processor_frequency (for Android devices).
  31. // https://github.com/getsentry/relay/blob/master/relay-general/src/protocol/device_class.rs
  32. DEVICE_CLASS = 'device.class',
  33. DEVICE_FAMILY = 'device.family',
  34. DEVICE_LOCALE = 'device.locale',
  35. DEVICE_MODEL_ID = 'device.model_id',
  36. DEVICE_NAME = 'device.name',
  37. DEVICE_ONLINE = 'device.online',
  38. DEVICE_ORIENTATION = 'device.orientation',
  39. DEVICE_SCREEN_DENSITY = 'device.screen_density',
  40. DEVICE_SCREEN_DPI = 'device.screen_dpi',
  41. DEVICE_SCREEN_HEIGHT_PIXELS = 'device.screen_height_pixels',
  42. DEVICE_SCREEN_WIDTH_PIXELS = 'device.screen_width_pixels',
  43. DEVICE_SIMULATOR = 'device.simulator',
  44. DEVICE_UUID = 'device.uuid',
  45. DIST = 'dist',
  46. ENVIRONMENT = 'environment',
  47. ERROR_HANDLED = 'error.handled',
  48. ERROR_MECHANISM = 'error.mechanism',
  49. ERROR_TYPE = 'error.type',
  50. ERROR_UNHANDLED = 'error.unhandled',
  51. ERROR_VALUE = 'error.value',
  52. ERROR_RECEIVED = 'error.received',
  53. ERROR_MAIN_THREAD = 'error.main_thread',
  54. EVENT_TIMESTAMP = 'event.timestamp',
  55. EVENT_TYPE = 'event.type',
  56. FIRST_RELEASE = 'firstRelease',
  57. FIRST_SEEN = 'firstSeen',
  58. GEO_CITY = 'geo.city',
  59. GEO_COUNTRY_CODE = 'geo.country_code',
  60. GEO_REGION = 'geo.region',
  61. GEO_SUBDIVISION = 'geo.subdivision',
  62. HAS = 'has',
  63. HTTP_METHOD = 'http.method',
  64. HTTP_REFERER = 'http.referer',
  65. HTTP_STATUS_CODE = 'http.status_code',
  66. HTTP_URL = 'http.url',
  67. ID = 'id',
  68. IS = 'is',
  69. ISSUE = 'issue',
  70. ISSUE_CATEGORY = 'issue.category',
  71. ISSUE_PRIORITY = 'issue.priority',
  72. ISSUE_TYPE = 'issue.type',
  73. LAST_SEEN = 'lastSeen',
  74. LEVEL = 'level',
  75. LOCATION = 'location',
  76. MESSAGE = 'message',
  77. OS = 'os',
  78. OS_BUILD = 'os.build',
  79. OS_KERNEL_VERSION = 'os.kernel_version',
  80. OS_NAME = 'os.name',
  81. PLATFORM = 'platform',
  82. PLATFORM_NAME = 'platform.name',
  83. PROFILE_ID = 'profile.id',
  84. PROJECT = 'project',
  85. RELEASE = 'release',
  86. RELEASE_BUILD = 'release.build',
  87. RELEASE_PACKAGE = 'release.package',
  88. RELEASE_STAGE = 'release.stage',
  89. RELEASE_VERSION = 'release.version',
  90. REPLAY_ID = 'replayId',
  91. SDK_NAME = 'sdk.name',
  92. SDK_VERSION = 'sdk.version',
  93. STACK_ABS_PATH = 'stack.abs_path',
  94. STACK_COLNO = 'stack.colno',
  95. STACK_FILENAME = 'stack.filename',
  96. STACK_FUNCTION = 'stack.function',
  97. STACK_IN_APP = 'stack.in_app',
  98. STACK_LINENO = 'stack.lineno',
  99. STACK_MODULE = 'stack.module',
  100. STACK_PACKAGE = 'stack.package',
  101. STACK_RESOURCE = 'stack.resource',
  102. STACK_STACK_LEVEL = 'stack.stack_level',
  103. TIMESTAMP = 'timestamp',
  104. TIMESTAMP_TO_DAY = 'timestamp.to_day',
  105. TIMESTAMP_TO_HOUR = 'timestamp.to_hour',
  106. TIMES_SEEN = 'timesSeen',
  107. TITLE = 'title',
  108. TOTAL_COUNT = 'total.count',
  109. TRACE = 'trace',
  110. TRACE_PARENT_SPAN = 'trace.parent_span',
  111. TRACE_SPAN = 'trace.span',
  112. TRACE_CLIENT_SAMPLE_RATE = 'trace.client_sample_rate',
  113. TRANSACTION = 'transaction',
  114. TRANSACTION_DURATION = 'transaction.duration',
  115. TRANSACTION_OP = 'transaction.op',
  116. TRANSACTION_STATUS = 'transaction.status',
  117. UNREAL_CRASH_TYPE = 'unreal.crash_type',
  118. USER = 'user',
  119. USER_DISPLAY = 'user.display',
  120. USER_EMAIL = 'user.email',
  121. USER_ID = 'user.id',
  122. USER_IP = 'user.ip',
  123. USER_USERNAME = 'user.username',
  124. USER_SEGMENT = 'user.segment',
  125. APP_IN_FOREGROUND = 'app.in_foreground',
  126. FUNCTION_DURATION = 'function.duration',
  127. }
  128. export enum FieldValueType {
  129. BOOLEAN = 'boolean',
  130. DATE = 'date',
  131. DURATION = 'duration',
  132. INTEGER = 'integer',
  133. NUMBER = 'number',
  134. PERCENTAGE = 'percentage',
  135. STRING = 'string',
  136. NEVER = 'never',
  137. SIZE = 'size',
  138. RATE = 'rate',
  139. PERCENT_CHANGE = 'percent_change',
  140. }
  141. export enum WebVital {
  142. FP = 'measurements.fp',
  143. FCP = 'measurements.fcp',
  144. LCP = 'measurements.lcp',
  145. FID = 'measurements.fid',
  146. CLS = 'measurements.cls',
  147. TTFB = 'measurements.ttfb',
  148. INP = 'measurements.inp',
  149. REQUEST_TIME = 'measurements.ttfb.requesttime',
  150. }
  151. export enum MobileVital {
  152. APP_START_COLD = 'measurements.app_start_cold',
  153. APP_START_WARM = 'measurements.app_start_warm',
  154. FRAMES_TOTAL = 'measurements.frames_total',
  155. FRAMES_SLOW = 'measurements.frames_slow',
  156. FRAMES_FROZEN = 'measurements.frames_frozen',
  157. FRAMES_SLOW_RATE = 'measurements.frames_slow_rate',
  158. FRAMES_FROZEN_RATE = 'measurements.frames_frozen_rate',
  159. STALL_COUNT = 'measurements.stall_count',
  160. STALL_TOTAL_TIME = 'measurements.stall_total_time',
  161. STALL_LONGEST_TIME = 'measurements.stall_longest_time',
  162. STALL_PERCENTAGE = 'measurements.stall_percentage',
  163. TIME_TO_FULL_DISPLAY = 'measurements.time_to_full_display',
  164. TIME_TO_INITIAL_DISPLAY = 'measurements.time_to_initial_display',
  165. }
  166. export enum StackTags {
  167. STACK_ABS_PATH = 'stack.abs_path',
  168. STACK_COLNO = 'stack.colno',
  169. STACK_FILENAME = 'stack.filename',
  170. STACK_FUNCTION = 'stack.function',
  171. STACK_IN_APP = 'stack.in_app',
  172. STACK_LINENO = 'stack.lineno',
  173. STACK_MODULE = 'stack.module',
  174. STACK_PACKAGE = 'stack.package',
  175. STACK_RESOURCE = 'stack.resource',
  176. STACK_STACK_LEVEL = 'stack.stack_level',
  177. }
  178. export enum ErrorTags {
  179. ERROR_HANDLED = 'error.handled',
  180. ERROR_MECHANISM = 'error.mechanism',
  181. ERROR_TYPE = 'error.type',
  182. ERROR_UNHANDLED = 'error.unhandled',
  183. ERROR_VALUE = 'error.value',
  184. ERROR_RECEIVED = 'error.received',
  185. ERROR_MAIN_THREAD = 'error.main_thread',
  186. }
  187. export enum SpanOpBreakdown {
  188. SPANS_BROWSER = 'spans.browser',
  189. SPANS_DB = 'spans.db',
  190. SPANS_HTTP = 'spans.http',
  191. SPANS_RESOURCE = 'spans.resource',
  192. SPANS_UI = 'spans.ui',
  193. }
  194. export enum AggregationKey {
  195. COUNT = 'count',
  196. COUNT_UNIQUE = 'count_unique',
  197. COUNT_MISERABLE = 'count_miserable',
  198. COUNT_IF = 'count_if',
  199. COUNT_WEB_VITALS = 'count_web_vitals',
  200. EPS = 'eps',
  201. EPM = 'epm',
  202. FAILURE_COUNT = 'failure_count',
  203. MIN = 'min',
  204. MAX = 'max',
  205. SUM = 'sum',
  206. ANY = 'any',
  207. P50 = 'p50',
  208. P75 = 'p75',
  209. P90 = 'p90',
  210. P95 = 'p95',
  211. P99 = 'p99',
  212. P100 = 'p100',
  213. PERCENTILE = 'percentile',
  214. AVG = 'avg',
  215. APDEX = 'apdex',
  216. USER_MISERY = 'user_misery',
  217. FAILURE_RATE = 'failure_rate',
  218. LAST_SEEN = 'last_seen',
  219. }
  220. export enum IsFieldValues {
  221. RESOLVED = 'resolved',
  222. UNRESOLVED = 'unresolved',
  223. ARCHIVED = 'archived',
  224. ESCALATING = 'escalating',
  225. NEW = 'new',
  226. ONGOING = 'ongoing',
  227. REGRESSED = 'regressed',
  228. ASSIGNED = 'assigned',
  229. UNASSIGNED = 'unassigned',
  230. FOR_REVIEW = 'for_review',
  231. LINKED = 'linked',
  232. UNLINKED = 'unlinked',
  233. }
  234. export type AggregateColumnParameter = {
  235. /**
  236. * The types of columns that are valid for this parameter.
  237. * Can pass a list of FieldValueTypes or a predicate function.
  238. */
  239. columnTypes:
  240. | FieldValueType[]
  241. | ((field: {key: string; valueType: FieldValueType}) => boolean);
  242. kind: 'column';
  243. name: string;
  244. required: boolean;
  245. defaultValue?: string;
  246. };
  247. export type AggregateValueParameter = {
  248. dataType: FieldValueType;
  249. kind: 'value';
  250. name: string;
  251. required: boolean;
  252. defaultValue?: string;
  253. options?: Array<{value: string; label?: string}>;
  254. placeholder?: string;
  255. };
  256. export type AggregateParameter = AggregateColumnParameter | AggregateValueParameter;
  257. export type ParameterDependentValueType = (
  258. parameters: Array<string | null>
  259. ) => FieldValueType;
  260. export interface FieldDefinition {
  261. kind: FieldKind;
  262. valueType: FieldValueType | null;
  263. /**
  264. * Allow all comparison operators to be used with this field.
  265. * Useful for fields like `release.version` which accepts text, but
  266. * can also be used with operators like `>=` or `<`.
  267. */
  268. allowComparisonOperators?: boolean;
  269. /**
  270. * Default value for the field
  271. */
  272. defaultValue?: string;
  273. /**
  274. * Is this field being deprecated
  275. */
  276. deprecated?: boolean;
  277. /**
  278. * Description of the field
  279. */
  280. desc?: string;
  281. /**
  282. * Feature flag that indicates gating of the field from use
  283. */
  284. featureFlag?: string;
  285. /**
  286. * Additional keywords used when filtering via autocomplete
  287. */
  288. keywords?: string[];
  289. /**
  290. * Only valid for aggregate fields.
  291. * Modifies the value type based on the parameters passed to the function.
  292. */
  293. parameterDependentValueType?: ParameterDependentValueType;
  294. /**
  295. * Only valid for aggregate fields.
  296. * Defines the number and type of parameters that the function accepts.
  297. */
  298. parameters?: AggregateParameter[];
  299. /**
  300. * Potential values for the field
  301. */
  302. values?: string[];
  303. }
  304. type ColumnValidator = (field: {key: string; valueType: FieldValueType}) => boolean;
  305. function validateForNumericAggregate(
  306. validColumnTypes: FieldValueType[]
  307. ): ColumnValidator {
  308. return function ({key, valueType}) {
  309. // these built-in columns cannot be applied to numeric aggregates such as percentile(...)
  310. if (
  311. [
  312. FieldKey.DEVICE_BATTERY_LEVEL,
  313. FieldKey.STACK_COLNO,
  314. FieldKey.STACK_LINENO,
  315. FieldKey.STACK_STACK_LEVEL,
  316. ].includes(key as FieldKey)
  317. ) {
  318. return false;
  319. }
  320. return validColumnTypes.includes(valueType);
  321. };
  322. }
  323. function getDynamicFieldValueType(parameters: Array<string | null>): FieldValueType {
  324. const column = parameters[0];
  325. const fieldDef = column ? getFieldDefinition(column) : null;
  326. return fieldDef?.valueType ?? FieldValueType.NUMBER;
  327. }
  328. function validateAndDenyListColumns(
  329. validColumnTypes: FieldValueType[],
  330. deniedColumns: string[]
  331. ): ColumnValidator {
  332. return function ({key, valueType}) {
  333. return validColumnTypes.includes(valueType) && !deniedColumns.includes(key);
  334. };
  335. }
  336. function validateAllowedColumns(validColumns: string[]): ColumnValidator {
  337. return function ({key}): boolean {
  338. return validColumns.includes(key);
  339. };
  340. }
  341. export const AGGREGATION_FIELDS: Record<AggregationKey, FieldDefinition> = {
  342. [AggregationKey.COUNT]: {
  343. desc: t('count of events'),
  344. kind: FieldKind.FUNCTION,
  345. valueType: FieldValueType.NUMBER,
  346. parameters: [],
  347. },
  348. [AggregationKey.COUNT_UNIQUE]: {
  349. desc: t('Unique count of the field values'),
  350. kind: FieldKind.FUNCTION,
  351. valueType: FieldValueType.INTEGER,
  352. parameters: [
  353. {
  354. name: 'column',
  355. kind: 'column',
  356. columnTypes: [
  357. FieldValueType.STRING,
  358. FieldValueType.DURATION,
  359. FieldValueType.NUMBER,
  360. FieldValueType.INTEGER,
  361. FieldValueType.DURATION,
  362. FieldValueType.BOOLEAN,
  363. ],
  364. defaultValue: 'user',
  365. required: true,
  366. },
  367. ],
  368. },
  369. [AggregationKey.COUNT_MISERABLE]: {
  370. desc: t('Count of unique miserable users'),
  371. kind: FieldKind.FUNCTION,
  372. parameters: [
  373. {
  374. name: 'column',
  375. kind: 'column',
  376. columnTypes: validateAllowedColumns(['user']),
  377. defaultValue: 'user',
  378. required: true,
  379. },
  380. {
  381. name: 'value',
  382. kind: 'value',
  383. dataType: FieldValueType.NUMBER,
  384. defaultValue: '300',
  385. required: true,
  386. },
  387. ],
  388. valueType: FieldValueType.NUMBER,
  389. },
  390. [AggregationKey.COUNT_IF]: {
  391. desc: t('Count of events matching the parameter conditions'),
  392. kind: FieldKind.FUNCTION,
  393. valueType: FieldValueType.NUMBER,
  394. parameters: [
  395. {
  396. name: 'column',
  397. kind: 'column',
  398. columnTypes: validateAndDenyListColumns(
  399. [FieldValueType.STRING, FieldValueType.NUMBER, FieldValueType.DURATION],
  400. ['id', 'issue', 'user.display']
  401. ),
  402. defaultValue: 'transaction.duration',
  403. required: true,
  404. },
  405. {
  406. name: 'value',
  407. kind: 'value',
  408. dataType: FieldValueType.STRING,
  409. defaultValue: CONDITIONS_ARGUMENTS[0].value,
  410. options: CONDITIONS_ARGUMENTS,
  411. required: true,
  412. },
  413. {
  414. name: 'value',
  415. kind: 'value',
  416. dataType: FieldValueType.STRING,
  417. defaultValue: '300',
  418. required: true,
  419. },
  420. ],
  421. },
  422. [AggregationKey.COUNT_WEB_VITALS]: {
  423. desc: t('Count of web vitals with a specific status'),
  424. kind: FieldKind.FUNCTION,
  425. valueType: FieldValueType.NUMBER,
  426. parameters: [
  427. {
  428. name: 'column',
  429. kind: 'column',
  430. columnTypes: function ({key}): boolean {
  431. return [
  432. WebVital.LCP,
  433. WebVital.FP,
  434. WebVital.FCP,
  435. WebVital.FID,
  436. WebVital.CLS,
  437. ].includes(key as WebVital);
  438. },
  439. defaultValue: WebVital.LCP,
  440. required: true,
  441. },
  442. {
  443. name: 'value',
  444. kind: 'value',
  445. options: WEB_VITALS_QUALITY,
  446. dataType: FieldValueType.STRING,
  447. defaultValue: WEB_VITALS_QUALITY[0].value,
  448. required: true,
  449. },
  450. ],
  451. },
  452. [AggregationKey.EPS]: {
  453. desc: t('Events per second'),
  454. kind: FieldKind.FUNCTION,
  455. valueType: FieldValueType.NUMBER,
  456. parameters: [],
  457. },
  458. [AggregationKey.EPM]: {
  459. desc: t('Events per minute'),
  460. kind: FieldKind.FUNCTION,
  461. valueType: FieldValueType.NUMBER,
  462. parameters: [],
  463. },
  464. [AggregationKey.FAILURE_RATE]: {
  465. desc: t('Failed event percentage based on transaction.status'),
  466. kind: FieldKind.FUNCTION,
  467. valueType: FieldValueType.PERCENTAGE,
  468. parameters: [],
  469. },
  470. [AggregationKey.FAILURE_COUNT]: {
  471. desc: t('Failed event count based on transaction.status'),
  472. kind: FieldKind.FUNCTION,
  473. valueType: FieldValueType.NUMBER,
  474. parameters: [],
  475. },
  476. [AggregationKey.MIN]: {
  477. desc: t('Returns the minimum value of the selected field'),
  478. kind: FieldKind.FUNCTION,
  479. defaultValue: '300ms',
  480. valueType: null,
  481. parameterDependentValueType: getDynamicFieldValueType,
  482. parameters: [
  483. {
  484. name: 'column',
  485. kind: 'column',
  486. columnTypes: validateForNumericAggregate([
  487. FieldValueType.INTEGER,
  488. FieldValueType.NUMBER,
  489. FieldValueType.DURATION,
  490. FieldValueType.DATE,
  491. FieldValueType.PERCENTAGE,
  492. ]),
  493. defaultValue: 'transaction.duration',
  494. required: true,
  495. },
  496. ],
  497. },
  498. [AggregationKey.MAX]: {
  499. desc: t('Returns maximum value of the selected field'),
  500. kind: FieldKind.FUNCTION,
  501. defaultValue: '300ms',
  502. valueType: null,
  503. parameterDependentValueType: getDynamicFieldValueType,
  504. parameters: [
  505. {
  506. name: 'column',
  507. kind: 'column',
  508. columnTypes: validateForNumericAggregate([
  509. FieldValueType.INTEGER,
  510. FieldValueType.NUMBER,
  511. FieldValueType.DURATION,
  512. FieldValueType.DATE,
  513. FieldValueType.PERCENTAGE,
  514. ]),
  515. defaultValue: 'transaction.duration',
  516. required: true,
  517. },
  518. ],
  519. },
  520. [AggregationKey.SUM]: {
  521. desc: t('Returns the total value for the selected field'),
  522. kind: FieldKind.FUNCTION,
  523. defaultValue: '300ms',
  524. valueType: null,
  525. parameterDependentValueType: getDynamicFieldValueType,
  526. parameters: [
  527. {
  528. name: 'column',
  529. kind: 'column',
  530. columnTypes: validateForNumericAggregate([
  531. FieldValueType.DURATION,
  532. FieldValueType.NUMBER,
  533. FieldValueType.PERCENTAGE,
  534. ]),
  535. required: true,
  536. defaultValue: 'transaction.duration',
  537. },
  538. ],
  539. },
  540. [AggregationKey.ANY]: {
  541. desc: t('Not Recommended, a random field value'),
  542. kind: FieldKind.FUNCTION,
  543. defaultValue: '300ms',
  544. valueType: null,
  545. parameterDependentValueType: getDynamicFieldValueType,
  546. parameters: [
  547. {
  548. name: 'column',
  549. kind: 'column',
  550. columnTypes: [
  551. FieldValueType.STRING,
  552. FieldValueType.INTEGER,
  553. FieldValueType.NUMBER,
  554. FieldValueType.DURATION,
  555. FieldValueType.DATE,
  556. FieldValueType.BOOLEAN,
  557. ],
  558. required: true,
  559. defaultValue: 'transaction.duration',
  560. },
  561. ],
  562. },
  563. [AggregationKey.P50]: {
  564. desc: t('Returns the 50th percentile of the selected field'),
  565. kind: FieldKind.FUNCTION,
  566. defaultValue: '300ms',
  567. valueType: null,
  568. parameterDependentValueType: getDynamicFieldValueType,
  569. parameters: [
  570. {
  571. name: 'column',
  572. kind: 'column',
  573. columnTypes: validateForNumericAggregate([
  574. FieldValueType.DURATION,
  575. FieldValueType.NUMBER,
  576. FieldValueType.PERCENTAGE,
  577. ]),
  578. defaultValue: 'transaction.duration',
  579. required: false,
  580. },
  581. ],
  582. },
  583. [AggregationKey.P75]: {
  584. desc: t('Returns the 75th percentile of the selected field'),
  585. kind: FieldKind.FUNCTION,
  586. defaultValue: '300ms',
  587. valueType: null,
  588. parameterDependentValueType: getDynamicFieldValueType,
  589. parameters: [
  590. {
  591. name: 'column',
  592. kind: 'column',
  593. columnTypes: validateForNumericAggregate([
  594. FieldValueType.DURATION,
  595. FieldValueType.NUMBER,
  596. FieldValueType.PERCENTAGE,
  597. ]),
  598. defaultValue: 'transaction.duration',
  599. required: false,
  600. },
  601. ],
  602. },
  603. [AggregationKey.P90]: {
  604. desc: t('Returns the 90th percentile of the selected field'),
  605. kind: FieldKind.FUNCTION,
  606. defaultValue: '300ms',
  607. valueType: null,
  608. parameterDependentValueType: getDynamicFieldValueType,
  609. parameters: [
  610. {
  611. name: 'column',
  612. kind: 'column',
  613. columnTypes: validateForNumericAggregate([
  614. FieldValueType.DURATION,
  615. FieldValueType.NUMBER,
  616. FieldValueType.PERCENTAGE,
  617. ]),
  618. defaultValue: 'transaction.duration',
  619. required: false,
  620. },
  621. ],
  622. },
  623. [AggregationKey.P95]: {
  624. desc: t('Returns the 95th percentile of the selected field'),
  625. kind: FieldKind.FUNCTION,
  626. defaultValue: '300ms',
  627. valueType: null,
  628. parameterDependentValueType: getDynamicFieldValueType,
  629. parameters: [
  630. {
  631. name: 'column',
  632. kind: 'column',
  633. columnTypes: validateForNumericAggregate([
  634. FieldValueType.DURATION,
  635. FieldValueType.NUMBER,
  636. FieldValueType.PERCENTAGE,
  637. ]),
  638. defaultValue: 'transaction.duration',
  639. required: false,
  640. },
  641. ],
  642. },
  643. [AggregationKey.P99]: {
  644. desc: t('Returns the 99th percentile of the selected field'),
  645. kind: FieldKind.FUNCTION,
  646. defaultValue: '300ms',
  647. valueType: null,
  648. parameterDependentValueType: getDynamicFieldValueType,
  649. parameters: [
  650. {
  651. name: 'column',
  652. kind: 'column',
  653. columnTypes: validateForNumericAggregate([
  654. FieldValueType.DURATION,
  655. FieldValueType.NUMBER,
  656. FieldValueType.PERCENTAGE,
  657. ]),
  658. defaultValue: 'transaction.duration',
  659. required: false,
  660. },
  661. ],
  662. },
  663. [AggregationKey.P100]: {
  664. desc: t('Returns the 100th percentile of the selected field'),
  665. kind: FieldKind.FUNCTION,
  666. defaultValue: '300ms',
  667. valueType: null,
  668. parameterDependentValueType: getDynamicFieldValueType,
  669. parameters: [
  670. {
  671. name: 'column',
  672. kind: 'column',
  673. columnTypes: validateForNumericAggregate([
  674. FieldValueType.DURATION,
  675. FieldValueType.NUMBER,
  676. FieldValueType.PERCENTAGE,
  677. ]),
  678. defaultValue: 'transaction.duration',
  679. required: false,
  680. },
  681. ],
  682. },
  683. [AggregationKey.PERCENTILE]: {
  684. desc: t('Returns the percentile of the selected field'),
  685. kind: FieldKind.FUNCTION,
  686. defaultValue: '300ms',
  687. valueType: null,
  688. parameterDependentValueType: getDynamicFieldValueType,
  689. parameters: [
  690. {
  691. name: 'column',
  692. kind: 'column',
  693. columnTypes: validateForNumericAggregate([
  694. FieldValueType.DURATION,
  695. FieldValueType.NUMBER,
  696. FieldValueType.PERCENTAGE,
  697. ]),
  698. defaultValue: 'transaction.duration',
  699. required: true,
  700. },
  701. {
  702. name: 'value',
  703. kind: 'value',
  704. dataType: FieldValueType.NUMBER,
  705. defaultValue: '0.5',
  706. required: true,
  707. },
  708. ],
  709. },
  710. [AggregationKey.AVG]: {
  711. desc: t('Returns averages for a selected field'),
  712. kind: FieldKind.FUNCTION,
  713. defaultValue: '300ms',
  714. valueType: null,
  715. parameterDependentValueType: getDynamicFieldValueType,
  716. parameters: [
  717. {
  718. name: 'column',
  719. kind: 'column',
  720. columnTypes: validateForNumericAggregate([
  721. FieldValueType.DURATION,
  722. FieldValueType.NUMBER,
  723. FieldValueType.PERCENTAGE,
  724. ]),
  725. defaultValue: 'transaction.duration',
  726. required: false,
  727. },
  728. ],
  729. },
  730. [AggregationKey.APDEX]: {
  731. desc: t('Performance score based on a duration threshold'),
  732. kind: FieldKind.FUNCTION,
  733. valueType: FieldValueType.NUMBER,
  734. parameters: [
  735. {
  736. name: 'value',
  737. kind: 'value',
  738. dataType: FieldValueType.NUMBER,
  739. defaultValue: '300',
  740. required: true,
  741. },
  742. ],
  743. },
  744. [AggregationKey.USER_MISERY]: {
  745. desc: t(
  746. 'User-weighted performance metric that counts the number of unique users who were frustrated'
  747. ),
  748. kind: FieldKind.FUNCTION,
  749. valueType: FieldValueType.NUMBER,
  750. parameters: [
  751. {
  752. name: 'value',
  753. kind: 'value',
  754. dataType: FieldValueType.NUMBER,
  755. defaultValue: '300',
  756. required: true,
  757. },
  758. ],
  759. },
  760. [AggregationKey.LAST_SEEN]: {
  761. desc: t('Issues last seen at a date and time'),
  762. kind: FieldKind.FUNCTION,
  763. valueType: FieldValueType.DATE,
  764. parameters: [],
  765. },
  766. };
  767. export const MEASUREMENT_FIELDS: Record<WebVital | MobileVital, FieldDefinition> = {
  768. [WebVital.FP]: {
  769. desc: t('Web Vital First Paint'),
  770. kind: FieldKind.METRICS,
  771. valueType: FieldValueType.DURATION,
  772. },
  773. [WebVital.FCP]: {
  774. desc: t('Web Vital First Contentful Paint'),
  775. kind: FieldKind.METRICS,
  776. valueType: FieldValueType.DURATION,
  777. },
  778. [WebVital.LCP]: {
  779. desc: t('Web Vital Largest Contentful Paint'),
  780. kind: FieldKind.METRICS,
  781. valueType: FieldValueType.DURATION,
  782. },
  783. [WebVital.FID]: {
  784. desc: t('Web Vital First Input Delay'),
  785. kind: FieldKind.METRICS,
  786. valueType: FieldValueType.DURATION,
  787. },
  788. [WebVital.CLS]: {
  789. desc: t('Web Vital Cumulative Layout Shift'),
  790. kind: FieldKind.METRICS,
  791. valueType: FieldValueType.NUMBER,
  792. },
  793. [WebVital.TTFB]: {
  794. desc: t('Web Vital Time To First Byte'),
  795. kind: FieldKind.METRICS,
  796. valueType: FieldValueType.DURATION,
  797. },
  798. [WebVital.REQUEST_TIME]: {
  799. desc: t('Time between start of request to start of response'),
  800. kind: FieldKind.METRICS,
  801. valueType: FieldValueType.DURATION,
  802. },
  803. [MobileVital.APP_START_COLD]: {
  804. desc: t('First launch (not in memory and no process exists)'),
  805. kind: FieldKind.METRICS,
  806. valueType: FieldValueType.DURATION,
  807. },
  808. [MobileVital.APP_START_WARM]: {
  809. desc: t('Already launched (partial memory and process may exist)'),
  810. kind: FieldKind.METRICS,
  811. valueType: FieldValueType.DURATION,
  812. },
  813. [MobileVital.FRAMES_TOTAL]: {
  814. desc: t('Total number of frames'),
  815. kind: FieldKind.METRICS,
  816. valueType: FieldValueType.INTEGER,
  817. },
  818. [MobileVital.FRAMES_SLOW]: {
  819. desc: t('Number of slow frames'),
  820. kind: FieldKind.METRICS,
  821. valueType: FieldValueType.INTEGER,
  822. },
  823. [MobileVital.FRAMES_FROZEN]: {
  824. desc: t('Number of frozen frames'),
  825. kind: FieldKind.METRICS,
  826. valueType: FieldValueType.INTEGER,
  827. },
  828. [MobileVital.FRAMES_SLOW_RATE]: {
  829. desc: t('Number of slow frames out of the total'),
  830. kind: FieldKind.METRICS,
  831. valueType: FieldValueType.PERCENTAGE,
  832. },
  833. [MobileVital.FRAMES_FROZEN_RATE]: {
  834. desc: t('Number of frozen frames out of the total'),
  835. kind: FieldKind.METRICS,
  836. valueType: FieldValueType.PERCENTAGE,
  837. },
  838. [MobileVital.STALL_COUNT]: {
  839. desc: t('Count of slow Javascript event loops (React Native)'),
  840. kind: FieldKind.METRICS,
  841. valueType: FieldValueType.INTEGER,
  842. },
  843. [MobileVital.STALL_TOTAL_TIME]: {
  844. desc: t('Total stall duration (React Native)'),
  845. kind: FieldKind.METRICS,
  846. valueType: FieldValueType.PERCENTAGE,
  847. },
  848. [MobileVital.STALL_LONGEST_TIME]: {
  849. desc: t('Duration of slowest Javascript event loop (React Native)'),
  850. kind: FieldKind.METRICS,
  851. valueType: FieldValueType.INTEGER,
  852. },
  853. [MobileVital.STALL_PERCENTAGE]: {
  854. desc: t('Total stall duration out of the total transaction duration (React Native)'),
  855. kind: FieldKind.METRICS,
  856. valueType: FieldValueType.PERCENTAGE,
  857. },
  858. [MobileVital.TIME_TO_FULL_DISPLAY]: {
  859. desc: t(
  860. 'The time between application launch and complete display of all resources and views'
  861. ),
  862. kind: FieldKind.METRICS,
  863. valueType: FieldValueType.DURATION,
  864. },
  865. [MobileVital.TIME_TO_INITIAL_DISPLAY]: {
  866. desc: t('The time it takes for an application to produce its first frame'),
  867. kind: FieldKind.METRICS,
  868. valueType: FieldValueType.DURATION,
  869. },
  870. [WebVital.INP]: {
  871. desc: t('Web Vital Interaction to Next Paint'),
  872. kind: FieldKind.METRICS,
  873. valueType: FieldValueType.DURATION,
  874. },
  875. };
  876. export const SPAN_OP_FIELDS: Record<SpanOpBreakdown, FieldDefinition> = {
  877. [SpanOpBreakdown.SPANS_BROWSER]: {
  878. desc: t('Cumulative time based on the browser operation'),
  879. kind: FieldKind.METRICS,
  880. valueType: FieldValueType.DURATION,
  881. },
  882. [SpanOpBreakdown.SPANS_DB]: {
  883. desc: t('Cumulative time based on the database operation'),
  884. kind: FieldKind.METRICS,
  885. valueType: FieldValueType.DURATION,
  886. },
  887. [SpanOpBreakdown.SPANS_HTTP]: {
  888. desc: t('Cumulative time based on the http operation'),
  889. kind: FieldKind.METRICS,
  890. valueType: FieldValueType.DURATION,
  891. },
  892. [SpanOpBreakdown.SPANS_RESOURCE]: {
  893. desc: t('Cumulative time based on the resource operation'),
  894. kind: FieldKind.METRICS,
  895. valueType: FieldValueType.DURATION,
  896. },
  897. [SpanOpBreakdown.SPANS_UI]: {
  898. desc: t('Cumulative time based on the ui operation'),
  899. kind: FieldKind.METRICS,
  900. valueType: FieldValueType.DURATION,
  901. },
  902. };
  903. type TraceFields =
  904. | SpanIndexedField.SPAN_ACTION
  905. | SpanIndexedField.SPAN_DESCRIPTION
  906. | SpanIndexedField.SPAN_DOMAIN
  907. | SpanIndexedField.SPAN_DURATION
  908. | SpanIndexedField.SPAN_GROUP
  909. | SpanIndexedField.SPAN_MODULE
  910. | SpanIndexedField.SPAN_OP
  911. // TODO: Remove self time field when it is deprecated
  912. | SpanIndexedField.SPAN_SELF_TIME
  913. | SpanIndexedField.SPAN_STATUS
  914. | SpanIndexedField.RESPONSE_CODE;
  915. const TRACE_FIELD_DEFINITIONS: Record<TraceFields, FieldDefinition> = {
  916. /** Indexed Fields */
  917. [SpanIndexedField.SPAN_ACTION]: {
  918. desc: t(
  919. 'The type of span action, e.g `SELECT` for a SQL span or `POST` for an HTTP span'
  920. ),
  921. kind: FieldKind.FIELD,
  922. valueType: FieldValueType.STRING,
  923. },
  924. [SpanIndexedField.SPAN_DESCRIPTION]: {
  925. desc: t('Parameterized and scrubbed description of the span'),
  926. kind: FieldKind.FIELD,
  927. valueType: FieldValueType.STRING,
  928. },
  929. [SpanIndexedField.SPAN_DOMAIN]: {
  930. desc: t(
  931. 'General scope of the span’s action, i.e. the tables involved in a `db` span or the host name in an `http` span'
  932. ),
  933. kind: FieldKind.FIELD,
  934. valueType: FieldValueType.STRING,
  935. },
  936. [SpanIndexedField.SPAN_DURATION]: {
  937. desc: t('The total time taken by the span'),
  938. kind: FieldKind.METRICS,
  939. valueType: FieldValueType.DURATION,
  940. },
  941. [SpanIndexedField.SPAN_GROUP]: {
  942. desc: t('Unique hash of the span’s description'),
  943. kind: FieldKind.FIELD,
  944. valueType: FieldValueType.STRING,
  945. },
  946. [SpanIndexedField.SPAN_MODULE]: {
  947. desc: t(
  948. 'The Insights module that the span is associated with, e.g `cache`, `db`, `http`, etc.'
  949. ),
  950. kind: FieldKind.FIELD,
  951. valueType: FieldValueType.STRING,
  952. },
  953. [SpanIndexedField.SPAN_OP]: {
  954. desc: t('The operation of the span, e.g `http.client`, `middleware`'),
  955. kind: FieldKind.FIELD,
  956. valueType: FieldValueType.STRING,
  957. },
  958. [SpanIndexedField.SPAN_SELF_TIME]: {
  959. desc: t('The duration of the span excluding the duration of its child spans'),
  960. kind: FieldKind.METRICS,
  961. valueType: FieldValueType.DURATION,
  962. },
  963. [SpanIndexedField.SPAN_STATUS]: {
  964. desc: t('Status of the operation the span represents'),
  965. kind: FieldKind.FIELD,
  966. valueType: FieldValueType.STRING,
  967. },
  968. [SpanIndexedField.RESPONSE_CODE]: {
  969. desc: t('The HTTP response status code'),
  970. kind: FieldKind.FIELD,
  971. valueType: FieldValueType.STRING,
  972. },
  973. };
  974. type AllEventFieldKeys =
  975. | keyof typeof AGGREGATION_FIELDS
  976. | keyof typeof MEASUREMENT_FIELDS
  977. | keyof typeof SPAN_OP_FIELDS
  978. | keyof typeof TRACE_FIELD_DEFINITIONS
  979. | FieldKey;
  980. const EVENT_FIELD_DEFINITIONS: Record<AllEventFieldKeys, FieldDefinition> = {
  981. ...AGGREGATION_FIELDS,
  982. ...MEASUREMENT_FIELDS,
  983. ...SPAN_OP_FIELDS,
  984. ...TRACE_FIELD_DEFINITIONS,
  985. [FieldKey.AGE]: {
  986. desc: t('The age of the issue in relative time'),
  987. kind: FieldKind.FIELD,
  988. valueType: FieldValueType.DATE,
  989. },
  990. [FieldKey.ASSIGNED]: {
  991. desc: t('Assignee of the issue as a user ID'),
  992. kind: FieldKind.FIELD,
  993. valueType: FieldValueType.STRING,
  994. },
  995. [FieldKey.ASSIGNED_OR_SUGGESTED]: {
  996. desc: t('Assignee or suggestee of the issue as a user ID'),
  997. kind: FieldKind.FIELD,
  998. valueType: FieldValueType.STRING,
  999. },
  1000. [FieldKey.CULPRIT]: {
  1001. deprecated: true,
  1002. kind: FieldKind.FIELD,
  1003. valueType: FieldValueType.STRING,
  1004. },
  1005. [FieldKey.BOOKMARKS]: {
  1006. desc: t('The issues bookmarked by a user ID'),
  1007. kind: FieldKind.FIELD,
  1008. valueType: FieldValueType.STRING,
  1009. },
  1010. [FieldKey.BROWSER_NAME]: {
  1011. desc: t('Name of the browser'),
  1012. kind: FieldKind.FIELD,
  1013. valueType: FieldValueType.STRING,
  1014. },
  1015. [FieldKey.DEVICE_ARCH]: {
  1016. desc: t('CPU architecture'),
  1017. kind: FieldKind.FIELD,
  1018. valueType: FieldValueType.STRING,
  1019. },
  1020. [FieldKey.DEVICE_BATTERY_LEVEL]: {
  1021. desc: t('Indicates remaining battery life'),
  1022. kind: FieldKind.FIELD,
  1023. valueType: FieldValueType.STRING,
  1024. },
  1025. [FieldKey.DEVICE_BRAND]: {
  1026. desc: t('Brand of device'),
  1027. kind: FieldKind.FIELD,
  1028. valueType: FieldValueType.STRING,
  1029. },
  1030. [FieldKey.DEVICE_CHARGING]: {
  1031. desc: t('Charging at the time of the event'),
  1032. kind: FieldKind.FIELD,
  1033. valueType: FieldValueType.BOOLEAN,
  1034. },
  1035. [FieldKey.DEVICE_CLASS]: {
  1036. desc: t('The estimated performance level of the device, graded low, medium, or high'),
  1037. kind: FieldKind.FIELD,
  1038. valueType: FieldValueType.STRING,
  1039. },
  1040. [FieldKey.DEVICE_FAMILY]: {
  1041. desc: t('Model name across generations'),
  1042. kind: FieldKind.FIELD,
  1043. valueType: FieldValueType.STRING,
  1044. },
  1045. [FieldKey.DEVICE_LOCALE]: {
  1046. desc: t("The locale of the user's device"),
  1047. kind: FieldKind.FIELD,
  1048. valueType: FieldValueType.STRING,
  1049. },
  1050. [FieldKey.DEVICE_MODEL_ID]: {
  1051. desc: t('Internal hardware revision'),
  1052. kind: FieldKind.FIELD,
  1053. valueType: FieldValueType.STRING,
  1054. },
  1055. [FieldKey.DEVICE_NAME]: {
  1056. desc: t('Descriptor details'),
  1057. kind: FieldKind.FIELD,
  1058. valueType: FieldValueType.STRING,
  1059. },
  1060. [FieldKey.DEVICE_ONLINE]: {
  1061. desc: t('Online at the time of the event'),
  1062. kind: FieldKind.FIELD,
  1063. valueType: FieldValueType.BOOLEAN,
  1064. },
  1065. [FieldKey.DEVICE_ORIENTATION]: {
  1066. desc: t('Portrait or landscape view '),
  1067. kind: FieldKind.FIELD,
  1068. valueType: FieldValueType.STRING,
  1069. },
  1070. [FieldKey.DEVICE_SCREEN_DENSITY]: {
  1071. desc: t('Pixel density of the device screen'),
  1072. kind: FieldKind.FIELD,
  1073. valueType: FieldValueType.STRING,
  1074. },
  1075. [FieldKey.DEVICE_SCREEN_DPI]: {
  1076. desc: t('Dots per inch of the device screen'),
  1077. kind: FieldKind.FIELD,
  1078. valueType: FieldValueType.STRING,
  1079. },
  1080. [FieldKey.DEVICE_SCREEN_HEIGHT_PIXELS]: {
  1081. desc: t('Height of the device screen in pixels'),
  1082. kind: FieldKind.FIELD,
  1083. valueType: FieldValueType.STRING,
  1084. },
  1085. [FieldKey.DEVICE_SCREEN_WIDTH_PIXELS]: {
  1086. desc: t('Width of the device screen in pixels'),
  1087. kind: FieldKind.FIELD,
  1088. valueType: FieldValueType.STRING,
  1089. },
  1090. [FieldKey.DEVICE_SIMULATOR]: {
  1091. desc: t('Indicates if it occured on a simulator'),
  1092. kind: FieldKind.FIELD,
  1093. valueType: FieldValueType.BOOLEAN,
  1094. },
  1095. [FieldKey.DEVICE_UUID]: {
  1096. desc: t('Unique device identifier'),
  1097. kind: FieldKind.FIELD,
  1098. valueType: FieldValueType.STRING,
  1099. },
  1100. [FieldKey.DIST]: {
  1101. desc: t(
  1102. 'Distinguishes between build or deployment variants of the same release of an application.'
  1103. ),
  1104. kind: FieldKind.FIELD,
  1105. valueType: FieldValueType.STRING,
  1106. },
  1107. [FieldKey.ENVIRONMENT]: {
  1108. desc: t('The environment the event was seen in'),
  1109. kind: FieldKind.FIELD,
  1110. valueType: FieldValueType.STRING,
  1111. },
  1112. [FieldKey.ERROR_HANDLED]: {
  1113. desc: t('Determines handling status of the error'),
  1114. kind: FieldKind.FIELD,
  1115. valueType: FieldValueType.BOOLEAN,
  1116. },
  1117. [FieldKey.ERROR_MECHANISM]: {
  1118. desc: t('The mechanism that created the error'),
  1119. kind: FieldKind.FIELD,
  1120. valueType: FieldValueType.STRING,
  1121. },
  1122. [FieldKey.ERROR_TYPE]: {
  1123. desc: t('The type of exception'),
  1124. kind: FieldKind.FIELD,
  1125. valueType: FieldValueType.STRING,
  1126. },
  1127. [FieldKey.ERROR_UNHANDLED]: {
  1128. desc: t('Determines unhandling status of the error'),
  1129. kind: FieldKind.FIELD,
  1130. valueType: FieldValueType.BOOLEAN,
  1131. },
  1132. [FieldKey.ERROR_VALUE]: {
  1133. desc: t('Original value that exhibits error'),
  1134. kind: FieldKind.FIELD,
  1135. valueType: FieldValueType.STRING,
  1136. },
  1137. [FieldKey.ERROR_RECEIVED]: {
  1138. desc: t('The datetime that the error was received'),
  1139. kind: FieldKind.FIELD,
  1140. valueType: FieldValueType.DATE,
  1141. },
  1142. [FieldKey.ERROR_MAIN_THREAD]: {
  1143. desc: t('Indicates if the error occurred on the main thread'),
  1144. kind: FieldKind.FIELD,
  1145. valueType: FieldValueType.BOOLEAN,
  1146. },
  1147. [FieldKey.EVENT_TIMESTAMP]: {
  1148. desc: t('Date and time of the event'),
  1149. kind: FieldKind.FIELD,
  1150. valueType: FieldValueType.DATE,
  1151. },
  1152. [FieldKey.EVENT_TYPE]: {
  1153. desc: t('Type of event (Errors, transactions, csp and default)'),
  1154. kind: FieldKind.FIELD,
  1155. valueType: FieldValueType.STRING,
  1156. },
  1157. [FieldKey.GEO_CITY]: {
  1158. desc: t('Full name of the city'),
  1159. kind: FieldKind.FIELD,
  1160. valueType: FieldValueType.STRING,
  1161. },
  1162. [FieldKey.GEO_COUNTRY_CODE]: {
  1163. desc: t('Country code based on ISO 3166-1'),
  1164. kind: FieldKind.FIELD,
  1165. valueType: FieldValueType.STRING,
  1166. },
  1167. [FieldKey.GEO_REGION]: {
  1168. desc: t('Full name of the country'),
  1169. kind: FieldKind.FIELD,
  1170. valueType: FieldValueType.STRING,
  1171. },
  1172. [FieldKey.GEO_SUBDIVISION]: {
  1173. desc: t('Full name of the subdivision'),
  1174. kind: FieldKind.FIELD,
  1175. valueType: FieldValueType.STRING,
  1176. },
  1177. [FieldKey.HTTP_METHOD]: {
  1178. desc: t('Method of the request that created the event'),
  1179. kind: FieldKind.FIELD,
  1180. valueType: FieldValueType.STRING,
  1181. },
  1182. [FieldKey.HTTP_REFERER]: {
  1183. desc: t('The web page the resource was requested from'),
  1184. kind: FieldKind.FIELD,
  1185. valueType: FieldValueType.STRING,
  1186. },
  1187. [FieldKey.HTTP_STATUS_CODE]: {
  1188. desc: t('Type of response (i.e., 200, 404)'),
  1189. kind: FieldKind.FIELD,
  1190. valueType: FieldValueType.STRING,
  1191. },
  1192. [FieldKey.HTTP_URL]: {
  1193. desc: t('Full URL of the request without parameters'),
  1194. kind: FieldKind.FIELD,
  1195. valueType: FieldValueType.STRING,
  1196. },
  1197. [FieldKey.ID]: {
  1198. desc: t('The event identification number'),
  1199. kind: FieldKind.FIELD,
  1200. valueType: FieldValueType.STRING,
  1201. },
  1202. [FieldKey.IS]: {
  1203. desc: t('The properties of an issue (i.e. Resolved, unresolved)'),
  1204. kind: FieldKind.FIELD,
  1205. valueType: FieldValueType.STRING,
  1206. keywords: ['ignored', 'assigned', 'for_review', 'unassigned', 'linked', 'unlinked'],
  1207. defaultValue: 'unresolved',
  1208. },
  1209. [FieldKey.ISSUE]: {
  1210. desc: t('The issue identification short code'),
  1211. kind: FieldKind.FIELD,
  1212. valueType: FieldValueType.STRING,
  1213. },
  1214. [FieldKey.ISSUE_CATEGORY]: {
  1215. desc: t('Category of issue (error or performance)'),
  1216. kind: FieldKind.FIELD,
  1217. valueType: FieldValueType.STRING,
  1218. keywords: ['error', 'performance'],
  1219. },
  1220. [FieldKey.ISSUE_PRIORITY]: {
  1221. desc: t('The priority of the issue'),
  1222. kind: FieldKind.FIELD,
  1223. valueType: FieldValueType.STRING,
  1224. keywords: ['high', 'medium', 'low'],
  1225. },
  1226. [FieldKey.ISSUE_TYPE]: {
  1227. desc: t('Type of problem the issue represents (i.e. N+1 Query)'),
  1228. kind: FieldKind.FIELD,
  1229. valueType: FieldValueType.STRING,
  1230. },
  1231. [FieldKey.LAST_SEEN]: {
  1232. desc: t('Issues last seen at a given time'),
  1233. kind: FieldKind.FIELD,
  1234. valueType: FieldValueType.DATE,
  1235. },
  1236. [FieldKey.LEVEL]: {
  1237. kind: FieldKind.FIELD,
  1238. desc: t('Severity of the event (i.e., fatal, error, warning)'),
  1239. valueType: FieldValueType.STRING,
  1240. },
  1241. [FieldKey.LOCATION]: {
  1242. desc: t('Location of error'),
  1243. kind: FieldKind.FIELD,
  1244. valueType: FieldValueType.STRING,
  1245. },
  1246. [FieldKey.MESSAGE]: {
  1247. desc: t('Error message or transaction name'),
  1248. kind: FieldKind.FIELD,
  1249. valueType: FieldValueType.STRING,
  1250. },
  1251. [FieldKey.OS]: {
  1252. desc: t('Build and kernel version'),
  1253. kind: FieldKind.FIELD,
  1254. valueType: FieldValueType.STRING,
  1255. },
  1256. [FieldKey.OS_BUILD]: {
  1257. desc: t('Name of the build'),
  1258. kind: FieldKind.FIELD,
  1259. valueType: FieldValueType.STRING,
  1260. },
  1261. [FieldKey.OS_KERNEL_VERSION]: {
  1262. desc: t('Version number'),
  1263. kind: FieldKind.FIELD,
  1264. valueType: FieldValueType.STRING,
  1265. },
  1266. [FieldKey.PLATFORM]: {
  1267. desc: t('Name of the platform'),
  1268. kind: FieldKind.FIELD,
  1269. valueType: FieldValueType.STRING,
  1270. },
  1271. [FieldKey.PLATFORM_NAME]: {
  1272. desc: t('Name of the platform'),
  1273. kind: FieldKind.FIELD,
  1274. valueType: FieldValueType.STRING,
  1275. },
  1276. [FieldKey.PROFILE_ID]: {
  1277. desc: t('The ID of an associated profile'),
  1278. kind: FieldKind.FIELD,
  1279. valueType: FieldValueType.STRING,
  1280. },
  1281. [FieldKey.PROJECT]: {
  1282. kind: FieldKind.FIELD,
  1283. valueType: FieldValueType.STRING,
  1284. },
  1285. [FieldKey.FIRST_RELEASE]: {
  1286. desc: t('Issues first seen in a given release'),
  1287. kind: FieldKind.FIELD,
  1288. valueType: FieldValueType.STRING,
  1289. },
  1290. [FieldKey.FIRST_SEEN]: {
  1291. desc: t('Issues first seen at a given time'),
  1292. kind: FieldKind.FIELD,
  1293. valueType: FieldValueType.DATE,
  1294. },
  1295. [FieldKey.HAS]: {
  1296. desc: t('Determines if a tag or field exists in an event'),
  1297. kind: FieldKind.FIELD,
  1298. valueType: FieldValueType.STRING,
  1299. },
  1300. [FieldKey.OS_NAME]: {
  1301. desc: t('Name of the Operating System'),
  1302. kind: FieldKind.FIELD,
  1303. valueType: FieldValueType.STRING,
  1304. },
  1305. [FieldKey.RELEASE]: {
  1306. desc: t('The version of your code deployed to an environment'),
  1307. kind: FieldKind.FIELD,
  1308. valueType: FieldValueType.STRING,
  1309. },
  1310. [FieldKey.RELEASE_BUILD]: {
  1311. desc: t('The full version number that identifies the iteration'),
  1312. kind: FieldKind.FIELD,
  1313. valueType: FieldValueType.STRING,
  1314. allowComparisonOperators: true,
  1315. },
  1316. [FieldKey.RELEASE_PACKAGE]: {
  1317. desc: t('The identifier unique to the project or application'),
  1318. kind: FieldKind.FIELD,
  1319. valueType: FieldValueType.STRING,
  1320. allowComparisonOperators: true,
  1321. },
  1322. [FieldKey.RELEASE_STAGE]: {
  1323. desc: t('Stage of usage (i.e., adopted, replaced, low)'),
  1324. kind: FieldKind.FIELD,
  1325. valueType: FieldValueType.STRING,
  1326. allowComparisonOperators: true,
  1327. },
  1328. [FieldKey.RELEASE_VERSION]: {
  1329. desc: t('An abbreviated version number of the build'),
  1330. kind: FieldKind.FIELD,
  1331. valueType: FieldValueType.STRING,
  1332. allowComparisonOperators: true,
  1333. },
  1334. [FieldKey.REPLAY_ID]: {
  1335. desc: t('The ID of an associated Session Replay'),
  1336. kind: FieldKind.TAG,
  1337. valueType: FieldValueType.STRING,
  1338. },
  1339. [FieldKey.SDK_NAME]: {
  1340. desc: t('Name of the platform that sent the event'),
  1341. kind: FieldKind.FIELD,
  1342. valueType: FieldValueType.STRING,
  1343. },
  1344. [FieldKey.SDK_VERSION]: {
  1345. desc: t('Version of the platform that sent the event'),
  1346. kind: FieldKind.FIELD,
  1347. valueType: FieldValueType.STRING,
  1348. },
  1349. [FieldKey.STACK_ABS_PATH]: {
  1350. desc: t('Absolute path to the source file'),
  1351. kind: FieldKind.FIELD,
  1352. valueType: FieldValueType.STRING,
  1353. },
  1354. [FieldKey.STACK_COLNO]: {
  1355. desc: t('Column number of the call starting at 1'),
  1356. kind: FieldKind.FIELD,
  1357. valueType: FieldValueType.NUMBER,
  1358. },
  1359. [FieldKey.STACK_FILENAME]: {
  1360. desc: t('Relative path to the source file from the root directory'),
  1361. kind: FieldKind.FIELD,
  1362. valueType: FieldValueType.STRING,
  1363. },
  1364. [FieldKey.STACK_FUNCTION]: {
  1365. desc: t('Name of function being called'),
  1366. kind: FieldKind.FIELD,
  1367. valueType: FieldValueType.STRING,
  1368. },
  1369. [FieldKey.STACK_IN_APP]: {
  1370. desc: t('Indicates if frame is related to relevant code in stack trace'),
  1371. kind: FieldKind.FIELD,
  1372. valueType: FieldValueType.BOOLEAN,
  1373. },
  1374. [FieldKey.STACK_LINENO]: {
  1375. desc: t('Line number of the call starting at 1'),
  1376. kind: FieldKind.FIELD,
  1377. valueType: FieldValueType.NUMBER,
  1378. },
  1379. [FieldKey.STACK_MODULE]: {
  1380. desc: t('Platform specific module path'),
  1381. kind: FieldKind.FIELD,
  1382. valueType: FieldValueType.STRING,
  1383. },
  1384. [FieldKey.STACK_PACKAGE]: {
  1385. desc: t('The package the frame is from'),
  1386. kind: FieldKind.FIELD,
  1387. valueType: FieldValueType.STRING,
  1388. },
  1389. [FieldKey.STACK_RESOURCE]: {
  1390. desc: t('The package the frame is from'),
  1391. kind: FieldKind.FIELD,
  1392. valueType: FieldValueType.STRING,
  1393. },
  1394. [FieldKey.STACK_STACK_LEVEL]: {
  1395. desc: t('Number of frames per stacktrace'),
  1396. kind: FieldKind.FIELD,
  1397. valueType: FieldValueType.NUMBER,
  1398. },
  1399. [FieldKey.TIMES_SEEN]: {
  1400. desc: t('Total number of events'),
  1401. kind: FieldKind.FIELD,
  1402. valueType: FieldValueType.NUMBER,
  1403. keywords: ['count'],
  1404. },
  1405. [FieldKey.TIMESTAMP]: {
  1406. desc: t('The time an event finishes'),
  1407. kind: FieldKind.FIELD,
  1408. valueType: FieldValueType.DATE,
  1409. },
  1410. [FieldKey.TIMESTAMP_TO_HOUR]: {
  1411. desc: t('Rounded down to the nearest hour'),
  1412. kind: FieldKind.FIELD,
  1413. valueType: FieldValueType.DATE,
  1414. },
  1415. [FieldKey.TIMESTAMP_TO_DAY]: {
  1416. desc: t('Rounded down to the nearest day'),
  1417. kind: FieldKind.FIELD,
  1418. valueType: FieldValueType.DATE,
  1419. },
  1420. [FieldKey.TITLE]: {
  1421. desc: t('Error or transaction name identifier'),
  1422. kind: FieldKind.FIELD,
  1423. valueType: FieldValueType.STRING,
  1424. },
  1425. [FieldKey.TRACE]: {
  1426. desc: t('The trace identification number'),
  1427. kind: FieldKind.FIELD,
  1428. valueType: FieldValueType.STRING,
  1429. },
  1430. [FieldKey.TOTAL_COUNT]: {
  1431. desc: t('The total number of events for the current query'),
  1432. kind: FieldKind.FIELD,
  1433. valueType: FieldValueType.NUMBER,
  1434. },
  1435. [FieldKey.TRACE_PARENT_SPAN]: {
  1436. desc: t('Span identification number of the parent to the event'),
  1437. kind: FieldKind.FIELD,
  1438. valueType: FieldValueType.STRING,
  1439. },
  1440. [FieldKey.TRACE_SPAN]: {
  1441. desc: t('Span identification number of the root span'),
  1442. kind: FieldKind.FIELD,
  1443. valueType: FieldValueType.STRING,
  1444. },
  1445. [FieldKey.TRACE_CLIENT_SAMPLE_RATE]: {
  1446. desc: t('Sample rate of the trace in the SDK between 0 and 1'),
  1447. kind: FieldKind.FIELD,
  1448. valueType: FieldValueType.STRING,
  1449. },
  1450. [FieldKey.TRANSACTION]: {
  1451. desc: t('Error or transaction name identifier'),
  1452. kind: FieldKind.FIELD,
  1453. valueType: FieldValueType.STRING,
  1454. },
  1455. [FieldKey.TRANSACTION_OP]: {
  1456. desc: t('Short code identifying the type of operation the span is measuring'),
  1457. kind: FieldKind.FIELD,
  1458. valueType: FieldValueType.STRING,
  1459. },
  1460. [FieldKey.TRANSACTION_DURATION]: {
  1461. desc: t('Duration of the transaction'),
  1462. kind: FieldKind.FIELD,
  1463. valueType: FieldValueType.DURATION,
  1464. },
  1465. [FieldKey.TRANSACTION_STATUS]: {
  1466. desc: t('Describes the status of the span/transaction'),
  1467. kind: FieldKind.FIELD,
  1468. valueType: FieldValueType.STRING,
  1469. },
  1470. [FieldKey.UNREAL_CRASH_TYPE]: {
  1471. desc: t('Crash type of an Unreal event'),
  1472. kind: FieldKind.FIELD,
  1473. valueType: FieldValueType.STRING,
  1474. },
  1475. [FieldKey.USER]: {
  1476. desc: t('User identification value'),
  1477. kind: FieldKind.FIELD,
  1478. valueType: FieldValueType.STRING,
  1479. },
  1480. [FieldKey.USER_DISPLAY]: {
  1481. desc: t('The first user field available of email, username, ID, and IP'),
  1482. kind: FieldKind.FIELD,
  1483. valueType: FieldValueType.STRING,
  1484. },
  1485. [FieldKey.USER_EMAIL]: {
  1486. desc: t('Email address of the user'),
  1487. kind: FieldKind.FIELD,
  1488. valueType: FieldValueType.STRING,
  1489. },
  1490. [FieldKey.USER_ID]: {
  1491. desc: t('Application specific internal identifier of the user'),
  1492. kind: FieldKind.FIELD,
  1493. valueType: FieldValueType.STRING,
  1494. },
  1495. [FieldKey.USER_IP]: {
  1496. desc: t('IP Address of the user'),
  1497. kind: FieldKind.FIELD,
  1498. valueType: FieldValueType.STRING,
  1499. },
  1500. [FieldKey.USER_USERNAME]: {
  1501. desc: t('Username of the user'),
  1502. kind: FieldKind.FIELD,
  1503. valueType: FieldValueType.STRING,
  1504. },
  1505. [FieldKey.USER_SEGMENT]: {
  1506. desc: t('Segment of the user'),
  1507. kind: FieldKind.FIELD,
  1508. valueType: FieldValueType.STRING,
  1509. },
  1510. [FieldKey.APP_IN_FOREGROUND]: {
  1511. desc: t('Indicates if the app is in the foreground or background'),
  1512. kind: FieldKind.FIELD,
  1513. valueType: FieldValueType.BOOLEAN,
  1514. },
  1515. [FieldKey.FUNCTION_DURATION]: {
  1516. desc: t('Duration of the function'),
  1517. kind: FieldKind.FIELD,
  1518. valueType: FieldValueType.DURATION,
  1519. },
  1520. };
  1521. export const ISSUE_PROPERTY_FIELDS: FieldKey[] = [
  1522. FieldKey.AGE,
  1523. FieldKey.ASSIGNED_OR_SUGGESTED,
  1524. FieldKey.ASSIGNED,
  1525. FieldKey.BOOKMARKS,
  1526. FieldKey.FIRST_RELEASE,
  1527. FieldKey.FIRST_SEEN,
  1528. FieldKey.HAS,
  1529. FieldKey.IS,
  1530. FieldKey.ISSUE_CATEGORY,
  1531. FieldKey.ISSUE_PRIORITY,
  1532. FieldKey.ISSUE_TYPE,
  1533. FieldKey.ISSUE,
  1534. FieldKey.LAST_SEEN,
  1535. FieldKey.RELEASE_STAGE,
  1536. FieldKey.TIMES_SEEN,
  1537. ];
  1538. // Should match Snuba columns defined in sentry/snuba/events.py
  1539. export const ISSUE_EVENT_PROPERTY_FIELDS: FieldKey[] = [
  1540. FieldKey.APP_IN_FOREGROUND,
  1541. FieldKey.DEVICE_ARCH,
  1542. FieldKey.DEVICE_BRAND,
  1543. FieldKey.DEVICE_CLASS,
  1544. FieldKey.DEVICE_FAMILY,
  1545. FieldKey.DEVICE_LOCALE,
  1546. FieldKey.DEVICE_LOCALE,
  1547. FieldKey.DEVICE_MODEL_ID,
  1548. FieldKey.DEVICE_ORIENTATION,
  1549. FieldKey.DEVICE_UUID,
  1550. FieldKey.DIST,
  1551. FieldKey.ERROR_HANDLED,
  1552. FieldKey.ERROR_MAIN_THREAD,
  1553. FieldKey.ERROR_MECHANISM,
  1554. FieldKey.ERROR_TYPE,
  1555. FieldKey.ERROR_UNHANDLED,
  1556. FieldKey.ERROR_VALUE,
  1557. FieldKey.EVENT_TIMESTAMP,
  1558. FieldKey.EVENT_TYPE,
  1559. FieldKey.GEO_CITY,
  1560. FieldKey.GEO_COUNTRY_CODE,
  1561. FieldKey.GEO_REGION,
  1562. FieldKey.GEO_SUBDIVISION,
  1563. FieldKey.HTTP_METHOD,
  1564. FieldKey.HTTP_REFERER,
  1565. FieldKey.HTTP_STATUS_CODE,
  1566. FieldKey.HTTP_URL,
  1567. FieldKey.ID,
  1568. FieldKey.LOCATION,
  1569. FieldKey.MESSAGE,
  1570. FieldKey.OS_BUILD,
  1571. FieldKey.OS_KERNEL_VERSION,
  1572. FieldKey.PLATFORM,
  1573. FieldKey.RELEASE_BUILD,
  1574. FieldKey.RELEASE_PACKAGE,
  1575. FieldKey.RELEASE_VERSION,
  1576. FieldKey.RELEASE,
  1577. FieldKey.SDK_NAME,
  1578. FieldKey.SDK_VERSION,
  1579. FieldKey.STACK_ABS_PATH,
  1580. FieldKey.STACK_FILENAME,
  1581. FieldKey.STACK_FUNCTION,
  1582. FieldKey.STACK_MODULE,
  1583. FieldKey.STACK_PACKAGE,
  1584. FieldKey.STACK_STACK_LEVEL,
  1585. FieldKey.TIMESTAMP,
  1586. FieldKey.TITLE,
  1587. FieldKey.TRACE,
  1588. FieldKey.TRANSACTION,
  1589. FieldKey.UNREAL_CRASH_TYPE,
  1590. FieldKey.USER_EMAIL,
  1591. FieldKey.USER_ID,
  1592. FieldKey.USER_IP,
  1593. FieldKey.USER_USERNAME,
  1594. ];
  1595. export const ISSUE_FIELDS: FieldKey[] = [
  1596. ...ISSUE_PROPERTY_FIELDS,
  1597. ...ISSUE_EVENT_PROPERTY_FIELDS,
  1598. ];
  1599. /**
  1600. * Refer to src/sentry/snuba/events.py, search for Columns
  1601. */
  1602. export const DISCOVER_FIELDS = [
  1603. FieldKey.ID,
  1604. // issue.id and project.id are omitted on purpose.
  1605. // Customers should use `issue` and `project` instead.
  1606. FieldKey.TIMESTAMP,
  1607. // time is omitted on purpose.
  1608. // Customers should use `timestamp` or `timestamp.to_hour`.
  1609. FieldKey.TIMESTAMP_TO_HOUR,
  1610. FieldKey.TIMESTAMP_TO_DAY,
  1611. FieldKey.CULPRIT,
  1612. FieldKey.LOCATION,
  1613. FieldKey.MESSAGE,
  1614. FieldKey.PLATFORM_NAME,
  1615. FieldKey.ENVIRONMENT,
  1616. FieldKey.RELEASE,
  1617. FieldKey.DIST,
  1618. FieldKey.TITLE,
  1619. FieldKey.EVENT_TYPE,
  1620. // tags.key and tags.value are omitted on purpose as well.
  1621. FieldKey.TRANSACTION,
  1622. FieldKey.UNREAL_CRASH_TYPE,
  1623. FieldKey.USER,
  1624. FieldKey.USER_ID,
  1625. FieldKey.USER_EMAIL,
  1626. FieldKey.USER_USERNAME,
  1627. FieldKey.USER_IP,
  1628. FieldKey.SDK_NAME,
  1629. FieldKey.SDK_VERSION,
  1630. FieldKey.HTTP_METHOD,
  1631. FieldKey.HTTP_REFERER,
  1632. FieldKey.HTTP_STATUS_CODE,
  1633. FieldKey.HTTP_URL,
  1634. FieldKey.OS_BUILD,
  1635. FieldKey.OS_KERNEL_VERSION,
  1636. FieldKey.DEVICE_NAME,
  1637. FieldKey.DEVICE_BRAND,
  1638. FieldKey.DEVICE_LOCALE,
  1639. FieldKey.DEVICE_UUID,
  1640. FieldKey.DEVICE_ARCH,
  1641. FieldKey.DEVICE_FAMILY,
  1642. FieldKey.DEVICE_BATTERY_LEVEL,
  1643. FieldKey.DEVICE_ORIENTATION,
  1644. FieldKey.DEVICE_SCREEN_DENSITY,
  1645. FieldKey.DEVICE_SCREEN_DPI,
  1646. FieldKey.DEVICE_SCREEN_HEIGHT_PIXELS,
  1647. FieldKey.DEVICE_SCREEN_WIDTH_PIXELS,
  1648. FieldKey.DEVICE_SIMULATOR,
  1649. FieldKey.DEVICE_ONLINE,
  1650. FieldKey.DEVICE_CHARGING,
  1651. FieldKey.DEVICE_CLASS,
  1652. FieldKey.GEO_COUNTRY_CODE,
  1653. FieldKey.GEO_REGION,
  1654. FieldKey.GEO_CITY,
  1655. FieldKey.GEO_SUBDIVISION,
  1656. FieldKey.ERROR_TYPE,
  1657. FieldKey.ERROR_VALUE,
  1658. FieldKey.ERROR_MECHANISM,
  1659. FieldKey.ERROR_HANDLED,
  1660. FieldKey.ERROR_UNHANDLED,
  1661. FieldKey.ERROR_RECEIVED,
  1662. FieldKey.ERROR_MAIN_THREAD,
  1663. FieldKey.LEVEL,
  1664. FieldKey.STACK_ABS_PATH,
  1665. FieldKey.STACK_FILENAME,
  1666. FieldKey.STACK_PACKAGE,
  1667. FieldKey.STACK_MODULE,
  1668. FieldKey.STACK_FUNCTION,
  1669. FieldKey.STACK_IN_APP,
  1670. FieldKey.STACK_COLNO,
  1671. FieldKey.STACK_LINENO,
  1672. FieldKey.STACK_STACK_LEVEL,
  1673. // contexts.key and contexts.value omitted on purpose.
  1674. // App context fields
  1675. FieldKey.APP_IN_FOREGROUND,
  1676. // Transaction event fields.
  1677. FieldKey.TRANSACTION_DURATION,
  1678. FieldKey.TRANSACTION_OP,
  1679. FieldKey.TRANSACTION_STATUS,
  1680. FieldKey.TRACE,
  1681. FieldKey.TRACE_SPAN,
  1682. FieldKey.TRACE_PARENT_SPAN,
  1683. FieldKey.TRACE_CLIENT_SAMPLE_RATE,
  1684. FieldKey.PROFILE_ID,
  1685. // Meta field that returns total count, usually for equations
  1686. FieldKey.TOTAL_COUNT,
  1687. // Field alises defined in src/sentry/api/event_search.py
  1688. FieldKey.PROJECT,
  1689. FieldKey.ISSUE,
  1690. FieldKey.USER_DISPLAY,
  1691. // Span Op fields
  1692. SpanOpBreakdown.SPANS_BROWSER,
  1693. SpanOpBreakdown.SPANS_DB,
  1694. SpanOpBreakdown.SPANS_HTTP,
  1695. SpanOpBreakdown.SPANS_RESOURCE,
  1696. SpanOpBreakdown.SPANS_UI,
  1697. ];
  1698. export enum ReplayFieldKey {
  1699. ACTIVITY = 'activity',
  1700. BROWSER_NAME = 'browser.name',
  1701. BROWSER_VERSION = 'browser.version',
  1702. COUNT_DEAD_CLICKS = 'count_dead_clicks',
  1703. COUNT_RAGE_CLICKS = 'count_rage_clicks',
  1704. COUNT_ERRORS = 'count_errors',
  1705. COUNT_SEGMENTS = 'count_segments',
  1706. COUNT_URLS = 'count_urls',
  1707. DURATION = 'duration',
  1708. ERROR_IDS = 'error_ids',
  1709. OS_NAME = 'os.name',
  1710. OS_VERSION = 'os.version',
  1711. SEEN_BY_ME = 'seen_by_me',
  1712. URLS = 'urls',
  1713. VIEWED_BY_ME = 'viewed_by_me',
  1714. }
  1715. export enum ReplayClickFieldKey {
  1716. CLICK_ALT = 'click.alt',
  1717. CLICK_CLASS = 'click.class',
  1718. CLICK_ID = 'click.id',
  1719. CLICK_LABEL = 'click.label',
  1720. CLICK_ROLE = 'click.role',
  1721. CLICK_SELECTOR = 'click.selector',
  1722. DEAD_SELECTOR = 'dead.selector',
  1723. RAGE_SELECTOR = 'rage.selector',
  1724. CLICK_TAG = 'click.tag',
  1725. CLICK_TESTID = 'click.testid',
  1726. CLICK_TEXT_CONTENT = 'click.textContent',
  1727. CLICK_TITLE = 'click.title',
  1728. CLICK_COMPONENT_NAME = 'click.component_name',
  1729. }
  1730. /**
  1731. * Some fields inside the ReplayRecord type are intentionally omitted:
  1732. * `environment` -> Not backend support, omitted because we have a dropdown for it
  1733. * `finishedAt` -> No backend support, omitted because we StartDate dropdown and duration field support
  1734. * `startedAt` -> No backend support, Omitted because we have StartDate dropdown
  1735. * `longestTransaction` -> value is always zero
  1736. * `title` -> value is always the empty string
  1737. */
  1738. export const REPLAY_FIELDS = [
  1739. ReplayFieldKey.ACTIVITY,
  1740. ReplayFieldKey.BROWSER_NAME,
  1741. ReplayFieldKey.BROWSER_VERSION,
  1742. ReplayFieldKey.COUNT_DEAD_CLICKS,
  1743. ReplayFieldKey.COUNT_RAGE_CLICKS,
  1744. ReplayFieldKey.COUNT_ERRORS,
  1745. ReplayFieldKey.COUNT_SEGMENTS,
  1746. ReplayFieldKey.COUNT_URLS,
  1747. FieldKey.DEVICE_BRAND,
  1748. FieldKey.DEVICE_FAMILY,
  1749. FieldKey.DEVICE_MODEL_ID,
  1750. FieldKey.DEVICE_NAME,
  1751. FieldKey.DIST,
  1752. ReplayFieldKey.DURATION,
  1753. ReplayFieldKey.ERROR_IDS,
  1754. FieldKey.ID,
  1755. ReplayFieldKey.OS_NAME,
  1756. ReplayFieldKey.OS_VERSION,
  1757. FieldKey.PLATFORM,
  1758. FieldKey.RELEASE,
  1759. FieldKey.SDK_NAME,
  1760. FieldKey.SDK_VERSION,
  1761. ReplayFieldKey.SEEN_BY_ME,
  1762. FieldKey.TRACE,
  1763. ReplayFieldKey.URLS,
  1764. FieldKey.USER_EMAIL,
  1765. FieldKey.USER_ID,
  1766. FieldKey.USER_IP,
  1767. FieldKey.USER_USERNAME,
  1768. ReplayFieldKey.VIEWED_BY_ME,
  1769. ];
  1770. const REPLAY_FIELD_DEFINITIONS: Record<ReplayFieldKey, FieldDefinition> = {
  1771. [ReplayFieldKey.ACTIVITY]: {
  1772. desc: t('Amount of activity in the replay from 0 to 10'),
  1773. kind: FieldKind.FIELD,
  1774. valueType: FieldValueType.INTEGER,
  1775. },
  1776. [ReplayFieldKey.BROWSER_NAME]: {
  1777. desc: t('Name of the browser'),
  1778. kind: FieldKind.FIELD,
  1779. valueType: FieldValueType.STRING,
  1780. },
  1781. [ReplayFieldKey.BROWSER_VERSION]: {
  1782. desc: t('Version number of the browser'),
  1783. kind: FieldKind.FIELD,
  1784. valueType: FieldValueType.STRING,
  1785. },
  1786. [ReplayFieldKey.COUNT_DEAD_CLICKS]: {
  1787. desc: t('Number of dead clicks in the replay'),
  1788. kind: FieldKind.FIELD,
  1789. valueType: FieldValueType.INTEGER,
  1790. },
  1791. [ReplayFieldKey.COUNT_RAGE_CLICKS]: {
  1792. desc: t('Number of rage clicks in the replay'),
  1793. kind: FieldKind.FIELD,
  1794. valueType: FieldValueType.INTEGER,
  1795. },
  1796. [ReplayFieldKey.COUNT_ERRORS]: {
  1797. desc: t('Number of errors in the replay'),
  1798. kind: FieldKind.FIELD,
  1799. valueType: FieldValueType.INTEGER,
  1800. },
  1801. [ReplayFieldKey.COUNT_SEGMENTS]: {
  1802. desc: t('Number of segments in the replay'),
  1803. kind: FieldKind.FIELD,
  1804. valueType: FieldValueType.INTEGER,
  1805. },
  1806. [ReplayFieldKey.COUNT_URLS]: {
  1807. desc: t('Number of urls visited within the replay'),
  1808. kind: FieldKind.FIELD,
  1809. valueType: FieldValueType.INTEGER,
  1810. },
  1811. [ReplayFieldKey.DURATION]: {
  1812. desc: t('Duration of the replay, in seconds'),
  1813. kind: FieldKind.FIELD,
  1814. valueType: FieldValueType.DURATION,
  1815. },
  1816. [ReplayFieldKey.ERROR_IDS]: {
  1817. desc: t('Error instance'),
  1818. kind: FieldKind.FIELD,
  1819. valueType: FieldValueType.STRING,
  1820. },
  1821. [ReplayFieldKey.OS_NAME]: {
  1822. desc: t('Name of the Operating System'),
  1823. kind: FieldKind.FIELD,
  1824. valueType: FieldValueType.STRING,
  1825. },
  1826. [ReplayFieldKey.OS_VERSION]: {
  1827. desc: t('Version number of the Operating System'),
  1828. kind: FieldKind.FIELD,
  1829. valueType: FieldValueType.STRING,
  1830. },
  1831. [ReplayFieldKey.SEEN_BY_ME]: {
  1832. desc: t('Whether you have seen this replay before (true/false)'),
  1833. kind: FieldKind.FIELD,
  1834. valueType: FieldValueType.BOOLEAN,
  1835. },
  1836. [ReplayFieldKey.URLS]: {
  1837. desc: t('List of urls that were visited within the replay'),
  1838. kind: FieldKind.FIELD,
  1839. valueType: FieldValueType.STRING,
  1840. },
  1841. [ReplayFieldKey.VIEWED_BY_ME]: {
  1842. desc: t('Whether you have seen this replay before (true/false)'),
  1843. kind: FieldKind.FIELD,
  1844. valueType: FieldValueType.BOOLEAN,
  1845. },
  1846. };
  1847. export const REPLAY_CLICK_FIELDS = [
  1848. ReplayClickFieldKey.CLICK_ALT,
  1849. ReplayClickFieldKey.CLICK_CLASS,
  1850. ReplayClickFieldKey.CLICK_ID,
  1851. ReplayClickFieldKey.CLICK_LABEL,
  1852. ReplayClickFieldKey.CLICK_ROLE,
  1853. ReplayClickFieldKey.CLICK_SELECTOR,
  1854. ReplayClickFieldKey.DEAD_SELECTOR,
  1855. ReplayClickFieldKey.RAGE_SELECTOR,
  1856. ReplayClickFieldKey.CLICK_TAG,
  1857. ReplayClickFieldKey.CLICK_TEXT_CONTENT,
  1858. ReplayClickFieldKey.CLICK_TITLE,
  1859. ReplayClickFieldKey.CLICK_TESTID,
  1860. ReplayClickFieldKey.CLICK_COMPONENT_NAME,
  1861. ];
  1862. // This is separated out from REPLAY_FIELD_DEFINITIONS so that it is feature-flaggable
  1863. const REPLAY_CLICK_FIELD_DEFINITIONS: Record<ReplayClickFieldKey, FieldDefinition> = {
  1864. [ReplayClickFieldKey.CLICK_ALT]: {
  1865. desc: t('`alt` of an element that was clicked'),
  1866. kind: FieldKind.FIELD,
  1867. valueType: FieldValueType.STRING,
  1868. },
  1869. [ReplayClickFieldKey.CLICK_CLASS]: {
  1870. desc: t('`class` of an element that was clicked'),
  1871. kind: FieldKind.FIELD,
  1872. valueType: FieldValueType.STRING,
  1873. },
  1874. [ReplayClickFieldKey.CLICK_ID]: {
  1875. desc: t('`id` of an element that was clicked'),
  1876. kind: FieldKind.FIELD,
  1877. valueType: FieldValueType.STRING,
  1878. },
  1879. [ReplayClickFieldKey.CLICK_LABEL]: {
  1880. desc: t('`aria-label` of an element that was clicked'),
  1881. kind: FieldKind.FIELD,
  1882. valueType: FieldValueType.STRING,
  1883. },
  1884. [ReplayClickFieldKey.CLICK_ROLE]: {
  1885. desc: t('`role` of an element that was clicked'),
  1886. kind: FieldKind.FIELD,
  1887. valueType: FieldValueType.STRING,
  1888. },
  1889. [ReplayClickFieldKey.CLICK_SELECTOR]: {
  1890. desc: t(
  1891. 'query using CSS selector-like syntax, supports class, id, and attribute selectors'
  1892. ),
  1893. kind: FieldKind.FIELD,
  1894. valueType: FieldValueType.STRING,
  1895. },
  1896. [ReplayClickFieldKey.DEAD_SELECTOR]: {
  1897. desc: t(
  1898. 'query using CSS selector-like syntax, supports class, id, and attribute selectors'
  1899. ),
  1900. kind: FieldKind.FIELD,
  1901. valueType: FieldValueType.STRING,
  1902. },
  1903. [ReplayClickFieldKey.RAGE_SELECTOR]: {
  1904. desc: t(
  1905. 'query using CSS selector-like syntax, supports class, id, and attribute selectors'
  1906. ),
  1907. kind: FieldKind.FIELD,
  1908. valueType: FieldValueType.STRING,
  1909. },
  1910. [ReplayClickFieldKey.CLICK_TAG]: {
  1911. desc: t('`tag` of an element that was clicked'),
  1912. kind: FieldKind.FIELD,
  1913. valueType: FieldValueType.STRING,
  1914. },
  1915. [ReplayClickFieldKey.CLICK_TESTID]: {
  1916. desc: t('`data-testid` or `data-test-id` of an element that was clicked'),
  1917. kind: FieldKind.FIELD,
  1918. valueType: FieldValueType.STRING,
  1919. },
  1920. [ReplayClickFieldKey.CLICK_TEXT_CONTENT]: {
  1921. desc: t('textContent of an element that was clicked'),
  1922. kind: FieldKind.FIELD,
  1923. valueType: FieldValueType.STRING,
  1924. },
  1925. [ReplayClickFieldKey.CLICK_TITLE]: {
  1926. desc: t('`title` of an element that was clicked'),
  1927. kind: FieldKind.FIELD,
  1928. valueType: FieldValueType.STRING,
  1929. },
  1930. [ReplayClickFieldKey.CLICK_COMPONENT_NAME]: {
  1931. desc: t('the name of the frontend component that was clicked'),
  1932. kind: FieldKind.FIELD,
  1933. valueType: FieldValueType.STRING,
  1934. },
  1935. };
  1936. export enum FeedbackFieldKey {
  1937. BROWSER_NAME = 'browser.name',
  1938. BROWSER_VERSION = 'browser.version',
  1939. EMAIL = 'contact_email',
  1940. LOCALE_LANG = 'locale.lang',
  1941. LOCALE_TIMEZONE = 'locale.timezone',
  1942. MESSAGE = 'message',
  1943. NAME = 'name',
  1944. OS_NAME = 'os.name',
  1945. OS_VERSION = 'os.version',
  1946. URL = 'url',
  1947. }
  1948. export const FEEDBACK_FIELDS = [
  1949. FieldKey.ASSIGNED,
  1950. FeedbackFieldKey.BROWSER_NAME,
  1951. FeedbackFieldKey.BROWSER_VERSION,
  1952. FieldKey.DEVICE_BRAND,
  1953. FieldKey.DEVICE_FAMILY,
  1954. FieldKey.DEVICE_MODEL_ID,
  1955. FieldKey.DEVICE_NAME,
  1956. FieldKey.DIST,
  1957. FeedbackFieldKey.EMAIL,
  1958. FieldKey.ENVIRONMENT,
  1959. FieldKey.ID,
  1960. FieldKey.IS,
  1961. FieldKey.LEVEL,
  1962. FeedbackFieldKey.LOCALE_LANG,
  1963. FeedbackFieldKey.LOCALE_TIMEZONE,
  1964. FeedbackFieldKey.MESSAGE,
  1965. FeedbackFieldKey.NAME,
  1966. FeedbackFieldKey.OS_NAME,
  1967. FeedbackFieldKey.OS_VERSION,
  1968. FieldKey.PLATFORM,
  1969. FieldKey.SDK_NAME,
  1970. FieldKey.SDK_VERSION,
  1971. FieldKey.TIMESTAMP,
  1972. FieldKey.TRANSACTION,
  1973. FeedbackFieldKey.URL,
  1974. FieldKey.USER_EMAIL,
  1975. FieldKey.USER_ID,
  1976. FieldKey.USER_IP,
  1977. FieldKey.USER_USERNAME,
  1978. ];
  1979. const FEEDBACK_FIELD_DEFINITIONS: Record<FeedbackFieldKey, FieldDefinition> = {
  1980. [FeedbackFieldKey.BROWSER_NAME]: {
  1981. desc: t('Name of the browser'),
  1982. kind: FieldKind.FIELD,
  1983. valueType: FieldValueType.STRING,
  1984. },
  1985. [FeedbackFieldKey.BROWSER_VERSION]: {
  1986. desc: t('Version number of the browser'),
  1987. kind: FieldKind.FIELD,
  1988. valueType: FieldValueType.STRING,
  1989. },
  1990. [FeedbackFieldKey.EMAIL]: {
  1991. desc: t('Contact email of the user writing the feedback'),
  1992. kind: FieldKind.FIELD,
  1993. valueType: FieldValueType.STRING,
  1994. },
  1995. [FeedbackFieldKey.LOCALE_LANG]: {
  1996. desc: t('Language preference of the user'),
  1997. kind: FieldKind.FIELD,
  1998. valueType: FieldValueType.STRING,
  1999. },
  2000. [FeedbackFieldKey.LOCALE_TIMEZONE]: {
  2001. desc: t('Timezone the feedback was submitted from'),
  2002. kind: FieldKind.FIELD,
  2003. valueType: FieldValueType.STRING,
  2004. },
  2005. [FeedbackFieldKey.MESSAGE]: {
  2006. desc: t('Message written by the user providing feedback'),
  2007. kind: FieldKind.FIELD,
  2008. valueType: FieldValueType.STRING,
  2009. },
  2010. [FeedbackFieldKey.NAME]: {
  2011. desc: t('Name of the user writing feedback'),
  2012. kind: FieldKind.FIELD,
  2013. valueType: FieldValueType.STRING,
  2014. },
  2015. [FeedbackFieldKey.OS_NAME]: {
  2016. desc: t('Name of the operating system'),
  2017. kind: FieldKind.FIELD,
  2018. valueType: FieldValueType.STRING,
  2019. },
  2020. [FeedbackFieldKey.OS_VERSION]: {
  2021. desc: t('Version number of the operating system'),
  2022. kind: FieldKind.FIELD,
  2023. valueType: FieldValueType.STRING,
  2024. },
  2025. [FeedbackFieldKey.URL]: {
  2026. desc: t('URL of the page that the feedback is triggered on'),
  2027. kind: FieldKind.FIELD,
  2028. valueType: FieldValueType.STRING,
  2029. },
  2030. };
  2031. export const getFieldDefinition = (
  2032. key: string,
  2033. type: 'event' | 'replay' | 'replay_click' | 'feedback' = 'event'
  2034. ): FieldDefinition | null => {
  2035. switch (type) {
  2036. case 'replay':
  2037. if (key in REPLAY_FIELD_DEFINITIONS) {
  2038. return REPLAY_FIELD_DEFINITIONS[key];
  2039. }
  2040. if (key in REPLAY_CLICK_FIELD_DEFINITIONS) {
  2041. return REPLAY_CLICK_FIELD_DEFINITIONS[key];
  2042. }
  2043. if (REPLAY_FIELDS.includes(key as FieldKey)) {
  2044. return EVENT_FIELD_DEFINITIONS[key];
  2045. }
  2046. return null;
  2047. case 'feedback':
  2048. if (key in FEEDBACK_FIELD_DEFINITIONS) {
  2049. return FEEDBACK_FIELD_DEFINITIONS[key];
  2050. }
  2051. if (FEEDBACK_FIELDS.includes(key as FieldKey)) {
  2052. return EVENT_FIELD_DEFINITIONS[key];
  2053. }
  2054. return null;
  2055. case 'event':
  2056. default:
  2057. return EVENT_FIELD_DEFINITIONS[key] ?? null;
  2058. }
  2059. };
  2060. export function makeTagCollection(fieldKeys: FieldKey[]): TagCollection {
  2061. return Object.fromEntries(
  2062. fieldKeys.map(fieldKey => [
  2063. fieldKey,
  2064. {
  2065. key: fieldKey,
  2066. name: fieldKey,
  2067. kind: getFieldDefinition(fieldKey)?.kind,
  2068. },
  2069. ])
  2070. );
  2071. }
  2072. export function isDeviceClass(key): boolean {
  2073. return key === FieldKey.DEVICE_CLASS;
  2074. }
  2075. export const DEVICE_CLASS_TAG_VALUES = ['high', 'medium', 'low'];