dynamicSamplingMetricsAccuracyAlert.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {useEffect} from 'react';
  2. import Alert from 'sentry/components/alert';
  3. import Button from 'sentry/components/button';
  4. import {t} from 'sentry/locale';
  5. import {Organization, Project} from 'sentry/types';
  6. import {defined} from 'sentry/utils';
  7. import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  8. import {useOrganizationStats} from 'sentry/utils/useOrganizationStats';
  9. import {getClientSampleRates} from 'sentry/views/settings/project/server-side-sampling/utils';
  10. export const dynamicSamplingMetricsAccuracyMessage = t(
  11. 'The accuracy of performance metrics can be improved by adjusting your client-side sample rate.'
  12. );
  13. type Props = {
  14. organization: Organization;
  15. /**
  16. * The project that the user is currently viewing.
  17. * If there are more projects selected, this shall be undefined.
  18. */
  19. selectedProject?: Project;
  20. };
  21. // This alert will be shown if there is:
  22. // - all the required feature flags are enabled
  23. // - only one project selected
  24. // - the use viewing this has project:write permission
  25. // - if the diff between the current and recommended sample rates is equal or greater than 50%
  26. // - if we don't display other dynamic sampling alerts. According to the code this cans till be shown toegther with global sdk updates alert
  27. export function DynamicSamplingMetricsAccuracyAlert({
  28. organization,
  29. selectedProject,
  30. }: Props) {
  31. const requiredFeatureFlagsEnabled =
  32. organization.features.includes('server-side-sampling') &&
  33. organization.features.includes('server-side-sampling-ui') &&
  34. organization.features.includes('dynamic-sampling-performance-cta');
  35. const organizationStats = useOrganizationStats({
  36. organizationSlug: organization.slug,
  37. queryParameters: {
  38. project: selectedProject?.id,
  39. category: 'transaction',
  40. field: 'sum(quantity)',
  41. interval: '1h',
  42. statsPeriod: '48h',
  43. groupBy: 'outcome',
  44. },
  45. queryOptions: {
  46. enabled:
  47. // Only show if all required feature flags are enabled and a project is selected
  48. requiredFeatureFlagsEnabled && !!selectedProject?.id,
  49. staleTime: 1000 * 60 * 60, // a request will be considered fresh (or not stale) for 1 hour, dismissing the need for a new request
  50. },
  51. });
  52. const {diff: clientSamplingDiff} = getClientSampleRates(organizationStats.data);
  53. const recommendChangingClientSdk =
  54. defined(clientSamplingDiff) && clientSamplingDiff >= 50;
  55. const showAlert =
  56. requiredFeatureFlagsEnabled && !!selectedProject && recommendChangingClientSdk;
  57. useEffect(() => {
  58. if (!showAlert) {
  59. return;
  60. }
  61. trackAdvancedAnalyticsEvent('sampling.performance.metrics.accuracy.alert', {
  62. organization,
  63. project_id: selectedProject.id,
  64. });
  65. }, [showAlert, selectedProject?.id, organization]);
  66. if (!showAlert) {
  67. return null;
  68. }
  69. return (
  70. <Alert
  71. type="warning"
  72. showIcon
  73. trailingItems={
  74. <Button
  75. priority="link"
  76. borderless
  77. to={
  78. organization.access.includes('project:write')
  79. ? `/settings/${organization.slug}/projects/${selectedProject.slug}/dynamic-sampling/rules/uniform/?referrer=performance.rate-alert`
  80. : `/settings/${organization.slug}/projects/${selectedProject.slug}/dynamic-sampling/?referrer=performance.rate-alert`
  81. }
  82. >
  83. {t('Adjust Sample Rates')}
  84. </Button>
  85. }
  86. >
  87. {dynamicSamplingMetricsAccuracyMessage}
  88. </Alert>
  89. );
  90. }