organizationRateLimits.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import {RouteComponentProps} from 'react-router';
  2. import Field from 'sentry/components/forms/field';
  3. import RangeField from 'sentry/components/forms/fields/rangeField';
  4. import Form from 'sentry/components/forms/form';
  5. import {Panel, PanelAlert, PanelBody, PanelHeader} from 'sentry/components/panels';
  6. import {t, tct} from 'sentry/locale';
  7. import {Organization} from 'sentry/types';
  8. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  9. import TextBlock from 'sentry/views/settings/components/text/textBlock';
  10. type Props = RouteComponentProps<{}, {}> & {
  11. organization: Organization;
  12. };
  13. const getRateLimitValues = () => {
  14. const steps: number[] = [];
  15. let i = 0;
  16. while (i <= 1_000_000) {
  17. steps.push(i);
  18. if (i < 10_000) {
  19. i += 1_000;
  20. } else if (i < 100_000) {
  21. i += 10_000;
  22. } else {
  23. i += 100_000;
  24. }
  25. }
  26. return steps;
  27. };
  28. // We can just generate this once
  29. const ACCOUNT_RATE_LIMIT_VALUES = getRateLimitValues();
  30. const OrganizationRateLimit = ({organization}: Props) => {
  31. // TODO(billy): Update organization.quota in organizationStore with new values
  32. const {quota} = organization;
  33. const {maxRate, maxRateInterval, projectLimit, accountLimit} = quota;
  34. const initialData = {
  35. projectRateLimit: projectLimit || 100,
  36. accountRateLimit: accountLimit,
  37. };
  38. return (
  39. <div>
  40. <SettingsPageHeader title={t('Rate Limits')} />
  41. <Panel>
  42. <PanelHeader>{t('Adjust Limits')}</PanelHeader>
  43. <PanelBody>
  44. <PanelAlert type="info">
  45. {t(`Rate limits allow you to control how much data is stored for this
  46. organization. When a rate is exceeded the system will begin discarding
  47. data until the next interval.`)}
  48. </PanelAlert>
  49. <Form
  50. data-test-id="rate-limit-editor"
  51. saveOnBlur
  52. allowUndo
  53. apiMethod="PUT"
  54. apiEndpoint={`/organizations/${organization.slug}/`}
  55. initialData={initialData}
  56. >
  57. {!maxRate ? (
  58. <RangeField
  59. name="accountRateLimit"
  60. label={t('Account Limit')}
  61. min={0}
  62. max={1000000}
  63. allowedValues={ACCOUNT_RATE_LIMIT_VALUES}
  64. help={t(
  65. 'The maximum number of events to accept across this entire organization.'
  66. )}
  67. placeholder="e.g. 500"
  68. formatLabel={value =>
  69. !value
  70. ? t('No Limit')
  71. : tct('[number] per hour', {
  72. number: value.toLocaleString(),
  73. })
  74. }
  75. />
  76. ) : (
  77. <Field
  78. label={t('Account Limit')}
  79. help={t(
  80. 'The maximum number of events to accept across this entire organization.'
  81. )}
  82. >
  83. <TextBlock css={{marginBottom: 0}}>
  84. {tct(
  85. 'Your account is limited to a maximum of [maxRate] events per [maxRateInterval] seconds.',
  86. {
  87. maxRate,
  88. maxRateInterval,
  89. }
  90. )}
  91. </TextBlock>
  92. </Field>
  93. )}
  94. <RangeField
  95. name="projectRateLimit"
  96. label={t('Per-Project Limit')}
  97. help={t(
  98. 'The maximum percentage of the account limit (set above) that an individual project can consume.'
  99. )}
  100. step={5}
  101. min={50}
  102. max={100}
  103. formatLabel={value =>
  104. value !== 100 ? `${value}%` : t('No Limit \u2014 100%')
  105. }
  106. />
  107. </Form>
  108. </PanelBody>
  109. </Panel>
  110. </div>
  111. );
  112. };
  113. export default OrganizationRateLimit;