Пример #1
0
def check_project_alerts(project_id, **kwargs):
    """
    Given 'when' and 'count', which should signify recent times we compare it to
    historical data for this project and if over a given threshold, create an
    alert.
    """
    from sentry.app import tsdb
    from sentry.constants import DEFAULT_ALERT_PROJECT_THRESHOLD
    from sentry.models import ProjectOption, Alert

    threshold, min_events = ProjectOption.objects.get_value(
        project_id, 'alert:threshold', DEFAULT_ALERT_PROJECT_THRESHOLD)

    if not threshold and min_events:
        return

    end = datetime.now().replace(tzinfo=utc) - timedelta(seconds=10)
    start = end - timedelta(minutes=5)

    results = [v for _, v in tsdb.get_range(
        tsdb.models.project,
        [project_id],
        start=start,
        end=end,
        rollup=10,
    )[project_id]]

    half_intervals = int(len(results) / 2)
    previous_data, current_data = results[:half_intervals], results[half_intervals:]

    if not current_data:
        return

    current_avg = sum(current_data) / len(current_data)

    # if there first few points within previous data are empty, assume that the
    # project hasn't been active long enough for rates to be valid
    if not any(previous_data[:3]):
        return

    if min_events > current_avg:
        return

    mean = math.mean(previous_data)
    dev = math.mad(previous_data)
    previous_avg = (mean + dev * 2)

    pct_increase = (current_avg / previous_avg * 100) - 100

    logger.info('Rate of events for project %d changed from %.2f to %2.f',
        project_id, previous_avg, current_avg)

    if pct_increase > threshold and current_avg > previous_avg:
        Alert.maybe_alert(
            project_id=project_id,
            message='Rate of events increased from %.2f to %.2f' % (previous_avg, current_avg),
        )
Пример #2
0
def check_project_alerts(project_id, **kwargs):
    """
    Given 'when' and 'count', which should signify recent times we compare it to
    historical data for this project and if over a given threshold, create an
    alert.
    """
    from sentry.app import tsdb
    from sentry.constants import DEFAULT_ALERT_PROJECT_THRESHOLD
    from sentry.models import ProjectOption, Alert

    threshold, min_events = ProjectOption.objects.get_value(
        project_id, 'alert:threshold', DEFAULT_ALERT_PROJECT_THRESHOLD)

    if not threshold and min_events:
        return

    end = datetime.now().replace(tzinfo=utc) - timedelta(seconds=10)
    start = end - timedelta(minutes=5)

    results = [
        v for _, v in tsdb.get_range(
            tsdb.models.project,
            [project_id],
            start=start,
            end=end,
            rollup=10,
        )[project_id]
    ]

    half_intervals = int(len(results) / 2)
    previous_data, current_data = results[:half_intervals], results[
        half_intervals:]
    current_avg = sum(current_data) / len(current_data)

    # if there first few points within previous data are empty, assume that the
    # project hasn't been active long enough for rates to be valid
    if not any(previous_data[:3]):
        return

    if min_events > current_avg:
        return

    mean = math.mean(previous_data)
    dev = math.mad(previous_data)
    previous_avg = (mean + dev * 2)

    pct_increase = (current_avg / previous_avg * 100) - 100

    logger.info('Rate of events for project %d changed from %.2f to %2.f',
                project_id, previous_avg, current_avg)

    if pct_increase > threshold and current_avg > previous_avg:
        Alert.maybe_alert(
            project_id=project_id,
            message='Rate of events increased from %.2f to %.2f' %
            (previous_avg, current_avg),
        )
Пример #3
0
def check_project_alerts(project_id, when, count, **kwargs):
    """
    Given 'when' and 'count', which should signify recent times we compare it to historical data for this project
    and if over a given threshold, create an alert.
    """
    from sentry.conf import settings
    from sentry.models import ProjectCountByMinute, ProjectOption, Alert

    # TODO: make this use the cache
    try:
        threshold, min_events = ProjectOption.objects.get(
            project=project_id,
            key='alert:threshold',
        ).value
    except ProjectOption.DoesNotExist:
        threshold, min_events = settings.DEFAULT_ALERT_PROJECT_THRESHOLD

    if not threshold and min_events:
        return

    if min_events > count:
        return

    # number of 15 minute intervals to capture
    intervals = 8

    max_date = when - timedelta(minutes=MINUTE_NORMALIZATION)
    min_date = max_date - timedelta(minutes=(intervals * MINUTE_NORMALIZATION))

    # get historical data
    data = list(
        ProjectCountByMinute.objects.filter(
            project=project_id,
            date__lte=max_date,
            date__gt=min_date,
        ).values_list('times_seen', flat=True))

    # Bail if we don't have enough data points
    if len(data) != intervals:
        return

    mean = math.mean(data)
    dev = math.mad(data)
    previous = (mean + dev * 2) / MINUTE_NORMALIZATION

    pct_increase = count / previous * 100
    if pct_increase > threshold:
        Alert.maybe_alert(
            project_id=project_id,
            message='Rate of events per minute increased from %d to %d (+%d%%)'
            % (previous, count, pct_increase),
        )
Пример #4
0
def check_project_alerts(project_id, when, count, **kwargs):
    """
    Given 'when' and 'count', which should signify recent times we compare it to historical data for this project
    and if over a given threshold, create an alert.
    """
    from sentry.conf import settings
    from sentry.models import ProjectCountByMinute, ProjectOption, Alert

    # TODO: make this use the cache
    try:
        threshold, min_events = ProjectOption.objects.get(
            project=project_id,
            key='alert:threshold',
        ).value
    except ProjectOption.DoesNotExist:
        threshold, min_events = settings.DEFAULT_ALERT_PROJECT_THRESHOLD

    if not threshold and min_events:
        return

    if min_events > count:
        return

    # number of 15 minute intervals to capture
    intervals = 8

    max_date = when - timedelta(minutes=MINUTE_NORMALIZATION)
    min_date = max_date - timedelta(minutes=(intervals * MINUTE_NORMALIZATION))

    # get historical data
    data = list(ProjectCountByMinute.objects.filter(
        project=project_id,
        date__lte=max_date,
        date__gt=min_date,
    ).values_list('times_seen', flat=True))

    # Bail if we don't have enough data points
    if len(data) != intervals:
        return

    mean = math.mean(data)
    dev = math.mad(data)
    previous = (mean + dev * 2) / MINUTE_NORMALIZATION

    pct_increase = count / previous * 100
    if pct_increase > threshold:
        Alert.maybe_alert(
            project_id=project_id,
            message='Rate of events per minute increased from %d to %d (+%d%%)' % (previous, count, pct_increase),
        )
Пример #5
0
 def test_does_add_trending_events(self, get_accelerated):
     get_accelerated.return_value = [self.group]
     alert = Alert.maybe_alert(**self.params)
     assert alert is not None
     get_accelerated.assert_called_once_with([self.project.id],
                                             minutes=MINUTE_NORMALIZATION)
     assert list(alert.related_groups.all()) == [self.group]
Пример #6
0
 def test_does_add_trending_events(self, get_accelerated):
     get_accelerated.return_value = [self.group]
     alert = Alert.maybe_alert(**self.params)
     get_accelerated.assert_called_once_with([self.project.id], minutes=MINUTE_NORMALIZATION)
     assert list(alert.related_groups.all()) == [self.group]