123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- import {Fragment} from 'react';
- import styled from '@emotion/styled';
- import {GroupingConfigItem} from 'sentry/components/events/groupingInfo';
- import {Field} from 'sentry/components/forms/type';
- import ExternalLink from 'sentry/components/links/externalLink';
- import {t, tct} from 'sentry/locale';
- import space from 'sentry/styles/space';
- import marked from 'sentry/utils/marked';
- // Export route to make these forms searchable by label/help
- export const route = '/settings/:orgId/projects/:projectId/issue-grouping/';
- const groupingConfigField: Field = {
- name: 'groupingConfig',
- type: 'select',
- label: t('Grouping Config'),
- saveOnBlur: false,
- saveMessageAlertType: 'info',
- saveMessage: t(
- 'Changing grouping config will apply to future events only (can take up to a minute).'
- ),
- selectionInfoFunction: args => {
- const {groupingConfigs, value} = args;
- const selection = groupingConfigs.find(({id}) => id === value);
- const changelog = selection?.changelog || '';
- if (!changelog) {
- return null;
- }
- return (
- <Changelog>
- <ChangelogTitle>
- {tct('New in version [version]', {version: selection.id})}:
- </ChangelogTitle>
- <div dangerouslySetInnerHTML={{__html: marked(changelog)}} />
- </Changelog>
- );
- },
- choices: ({groupingConfigs}) =>
- groupingConfigs.map(({id, hidden}) => [
- id.toString(),
- <GroupingConfigItem key={id} isHidden={hidden}>
- {id}
- </GroupingConfigItem>,
- ]),
- help: t('Sets the grouping algorithm to be used for new events.'),
- visible: ({features}) => features.has('set-grouping-config'),
- };
- export const fields: Record<string, Field> = {
- fingerprintingRules: {
- name: 'fingerprintingRules',
- type: 'string',
- label: t('Fingerprint Rules'),
- hideLabel: true,
- placeholder: t(
- 'error.type:MyException -> fingerprint-value\nstack.function:some_panic_function -> fingerprint-value'
- ),
- multiline: true,
- monospace: true,
- autosize: true,
- inline: false,
- maxRows: 20,
- saveOnBlur: false,
- saveMessageAlertType: 'info',
- saveMessage: t(
- 'Changing fingerprint rules will apply to future events only (can take up to a minute).'
- ),
- formatMessageValue: false,
- help: () => (
- <Fragment>
- <RuleDescription>
- {tct(
- `This can be used to modify the fingerprint rules on the server with custom rules.
- Rules follow the pattern [pattern]. To learn more about fingerprint rules, [docs:read the docs].`,
- {
- pattern: <code>matcher:glob -> fingerprint, values</code>,
- docs: (
- <ExternalLink href="https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/" />
- ),
- }
- )}
- </RuleDescription>
- <RuleExample>
- {`# force all errors of the same type to have the same fingerprint
- error.type:DatabaseUnavailable -> system-down
- # force all memory allocation errors to be grouped together
- stack.function:malloc -> memory-allocation-error`}
- </RuleExample>
- </Fragment>
- ),
- visible: true,
- },
- groupingEnhancements: {
- name: 'groupingEnhancements',
- type: 'string',
- label: t('Stack Trace Rules'),
- hideLabel: true,
- placeholder: t(
- 'stack.function:raise_an_exception ^-group\nstack.function:namespace::* +app'
- ),
- multiline: true,
- monospace: true,
- autosize: true,
- inline: false,
- maxRows: 20,
- saveOnBlur: false,
- saveMessageAlertType: 'info',
- saveMessage: t(
- 'Changing stack trace rules will apply to future events only (can take up to a minute).'
- ),
- formatMessageValue: false,
- help: () => (
- <Fragment>
- <RuleDescription>
- {tct(
- `This can be used to enhance the grouping algorithm with custom rules.
- Rules follow the pattern [pattern]. To learn more about stack trace rules, [docs:read the docs].`,
- {
- pattern: <code>matcher:glob [v^]?[+-]flag</code>,
- docs: (
- <ExternalLink href="https://docs.sentry.io/product/data-management-settings/event-grouping/stack-trace-rules/" />
- ),
- }
- )}
- </RuleDescription>
- <RuleExample>
- {`# remove all frames above a certain function from grouping
- stack.function:panic_handler ^-group
- # mark all functions following a prefix in-app
- stack.function:mylibrary_* +app`}
- </RuleExample>
- </Fragment>
- ),
- validate: () => [],
- visible: true,
- },
- groupingConfig: groupingConfigField,
- secondaryGroupingConfig: {
- ...groupingConfigField,
- name: 'secondaryGroupingConfig',
- label: t('Fallback/Secondary Grouping Config'),
- help: t(
- 'Sets the secondary grouping algorithm that should be run in addition to avoid creating too many new groups. Controlled by expiration date below.'
- ),
- saveMessage: t(
- 'Changing the secondary grouping strategy will affect how many new issues are created.'
- ),
- },
- secondaryGroupingExpiry: {
- name: 'secondaryGroupingExpiry',
- type: 'number',
- label: t('Expiration date of secondary grouping'),
- help: t(
- 'If this UNIX timestamp is in the past, the secondary grouping configuration stops applying automatically.'
- ),
- saveOnBlur: false,
- saveMessageAlertType: 'info',
- saveMessage: t(
- 'Changing the expiration date will affect how many new issues are created.'
- ),
- },
- groupingAutoUpdate: {
- name: 'groupingAutoUpdate',
- type: 'boolean',
- label: t('Automatically Update Grouping'),
- saveOnBlur: false,
- help: t(
- 'When enabled projects will in the future automatically update to the latest grouping algorithm. Right now this setting does nothing.'
- ),
- saveMessage: ({value}) =>
- value
- ? t(
- 'Enabling automatic upgrading will take effect on the next incoming event once auto updating has been rolled out.'
- )
- : t(
- 'Disabling auto updates will cause you to no longer receive improvements to the grouping algorithm.'
- ),
- },
- };
- const RuleDescription = styled('div')`
- margin-bottom: ${space(1)};
- margin-top: -${space(1)};
- margin-right: 36px;
- `;
- const RuleExample = styled('pre')`
- margin-bottom: ${space(1)};
- margin-right: 36px;
- `;
- const Changelog = styled('div')`
- position: relative;
- top: -1px;
- margin-bottom: -1px;
- padding: ${space(2)};
- border-bottom: 1px solid ${p => p.theme.innerBorder};
- background: ${p => p.theme.backgroundSecondary};
- font-size: ${p => p.theme.fontSizeMedium};
- &:last-child {
- border: 0;
- border-bottom-left-radius: ${p => p.theme.borderRadius};
- border-bottom-right-radius: ${p => p.theme.borderRadius};
- }
- `;
- const ChangelogTitle = styled('h3')`
- font-size: ${p => p.theme.fontSizeMedium};
- margin-bottom: ${space(0.75)} !important;
- `;
|