Пример #1
0
 def test(self):
     with self.tasks():
         snuba_query = create_snuba_query(
             QueryDatasets.EVENTS,
             "level:error",
             QueryAggregations.TOTAL,
             timedelta(minutes=10),
             timedelta(minutes=1),
             None,
         )
         subscription = create_snuba_subscription(self.project, "something",
                                                  snuba_query)
         snuba_query = create_snuba_query(
             QueryDatasets.EVENTS,
             "level:error",
             QueryAggregations.TOTAL,
             timedelta(minutes=10),
             timedelta(minutes=1),
             None,
         )
         other_subscription = create_snuba_subscription(
             self.create_project(organization=self.organization),
             "something", snuba_query)
     subscription_ids = [subscription.id, other_subscription.id]
     bulk_delete_snuba_subscriptions([subscription, other_subscription])
     assert (QuerySubscription.objects.filter(
         id__in=subscription_ids,
         status=QuerySubscription.Status.DELETING.value,
         subscription_id__isnull=False,
     ).count() == 2)
Пример #2
0
    def test(self):
        with self.tasks():
            snuba_query = create_snuba_query(
                QueryDatasets.EVENTS,
                "level:error",
                "count()",
                timedelta(minutes=10),
                timedelta(minutes=1),
                None,
            )
            subscription = create_snuba_subscription(self.project, "something", snuba_query)

        query = "level:warning"
        aggregate = "count_unique(tags[sentry:user])"
        time_window = timedelta(minutes=20)
        resolution = timedelta(minutes=2)
        subscription = QuerySubscription.objects.get(id=subscription.id)
        subscription_id = subscription.subscription_id
        snuba_query.update(
            query=query,
            time_window=int(time_window.total_seconds()),
            resolution=int(resolution.total_seconds()),
            environment=self.environment,
            aggregate=aggregate,
        )
        assert subscription_id is not None
        update_snuba_subscription(subscription, snuba_query)
        assert subscription.status == QuerySubscription.Status.UPDATING.value
        assert subscription.subscription_id == subscription_id
        assert subscription.snuba_query.query == query
        assert subscription.snuba_query.aggregate == aggregate
        assert subscription.snuba_query.time_window == int(time_window.total_seconds())
        assert subscription.snuba_query.resolution == int(resolution.total_seconds())
Пример #3
0
    def test_with_task(self):
        with self.tasks():
            snuba_query = create_snuba_query(
                QueryDatasets.EVENTS,
                "level:error",
                QueryAggregations.TOTAL,
                timedelta(minutes=10),
                timedelta(minutes=1),
                None,
            )
            subscription = create_snuba_subscription(self.project, "something",
                                                     snuba_query)

            query = "level:warning"
            aggregation = QueryAggregations.UNIQUE_USERS
            time_window = timedelta(minutes=20)
            resolution = timedelta(minutes=2)
            subscription = QuerySubscription.objects.get(id=subscription.id)
            subscription_id = subscription.subscription_id
            assert subscription_id is not None
            snuba_query.update(
                query=query,
                time_window=int(time_window.total_seconds()),
                resolution=int(resolution.total_seconds()),
                environment=self.environment,
                aggregate=translate_aggregation(aggregation),
            )
            update_snuba_subscription(subscription, snuba_query)
            subscription = QuerySubscription.objects.get(id=subscription.id)
            assert subscription.status == QuerySubscription.Status.ACTIVE.value
            assert subscription.subscription_id is not None
            assert subscription.subscription_id != subscription_id
Пример #4
0
    def test_with_task(self):
        with self.tasks():
            old_dataset = QueryDatasets.EVENTS
            snuba_query = create_snuba_query(
                old_dataset,
                "level:error",
                "count()",
                timedelta(minutes=10),
                timedelta(minutes=1),
                None,
            )
            subscription = create_snuba_subscription(self.project, "something", snuba_query)

            dataset = QueryDatasets.TRANSACTIONS
            query = "level:warning"
            aggregate = "count_unique(tags[sentry:user])"
            time_window = timedelta(minutes=20)
            resolution = timedelta(minutes=2)
            subscription = QuerySubscription.objects.get(id=subscription.id)
            subscription_id = subscription.subscription_id
            assert subscription_id is not None
            snuba_query.update(
                dataset=dataset.value,
                query=query,
                time_window=int(time_window.total_seconds()),
                resolution=int(resolution.total_seconds()),
                environment=self.environment,
                aggregate=aggregate,
            )
            update_snuba_subscription(subscription, old_dataset)
            subscription = QuerySubscription.objects.get(id=subscription.id)
            assert subscription.status == QuerySubscription.Status.ACTIVE.value
            assert subscription.subscription_id is not None
            assert subscription.subscription_id != subscription_id
Пример #5
0
    def test_environment(self):
        snuba_query = create_snuba_query(
            QueryDatasets.EVENTS,
            "hello",
            "count_unique(tags[sentry:user])",
            timedelta(minutes=100),
            timedelta(minutes=2),
            self.environment,
        )

        new_env = self.create_environment()
        dataset = QueryDatasets.TRANSACTIONS
        query = "level:error"
        aggregate = "count()"
        time_window = timedelta(minutes=10)
        resolution = timedelta(minutes=1)
        event_types = snuba_query.event_types
        update_snuba_query(
            snuba_query, dataset, query, aggregate, time_window, resolution, new_env, None
        )
        assert snuba_query.dataset == dataset.value
        assert snuba_query.query == query
        assert snuba_query.aggregate == aggregate
        assert snuba_query.time_window == int(time_window.total_seconds())
        assert snuba_query.resolution == int(resolution.total_seconds())
        assert snuba_query.environment == new_env
        assert set(snuba_query.event_types) == set(event_types)
    def test_subscription_registered(self):
        registration_key = "registered_test"
        mock_callback = Mock()
        register_subscriber(registration_key)(mock_callback)
        with self.tasks():
            snuba_query = create_snuba_query(
                QueryDatasets.EVENTS,
                "hello",
                QueryAggregations.TOTAL,
                timedelta(minutes=10),
                timedelta(minutes=1),
                None,
            )
            sub = create_snuba_subscription(self.project, registration_key,
                                            snuba_query)
        sub.refresh_from_db()

        data = self.valid_wrapper
        data["payload"]["subscription_id"] = sub.subscription_id
        self.consumer.handle_message(self.build_mock_message(data))
        data = deepcopy(data)
        data["payload"]["values"] = data["payload"]["result"]
        data["payload"]["timestamp"] = parse_date(
            data["payload"]["timestamp"]).replace(tzinfo=pytz.utc)
        mock_callback.assert_called_once_with(data["payload"], sub)
Пример #7
0
 def test(self):
     dataset = QueryDatasets.EVENTS
     query = "level:error"
     aggregate = "count()"
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     snuba_query = create_snuba_query(dataset, query, aggregate, time_window, resolution, None)
     assert snuba_query.dataset == dataset.value
     assert snuba_query.query == query
     assert snuba_query.aggregate == aggregate
     assert snuba_query.time_window == int(time_window.total_seconds())
     assert snuba_query.resolution == int(resolution.total_seconds())
     assert snuba_query.environment is None
Пример #8
0
 def test(self):
     snuba_query = create_snuba_query(
         QueryDatasets.EVENTS,
         "release:123",
         "count()",
         timedelta(minutes=10),
         timedelta(minutes=1),
         None,
         [SnubaQueryEventType.EventType.DEFAULT, SnubaQueryEventType.EventType.ERROR],
     )
     assert set(snuba_query.event_types) == set(
         [SnubaQueryEventType.EventType.DEFAULT, SnubaQueryEventType.EventType.ERROR]
     )
Пример #9
0
 def test_with_task(self):
     with self.tasks():
         snuba_query = create_snuba_query(
             QueryDatasets.EVENTS,
             "level:error",
             "count()",
             timedelta(minutes=10),
             timedelta(minutes=1),
             None,
         )
         subscription = create_snuba_subscription(self.project, "something", snuba_query)
         subscription_id = subscription.id
         delete_snuba_subscription(subscription)
         assert not QuerySubscription.objects.filter(id=subscription_id).exists()
Пример #10
0
    def test(self):
        snuba_query = create_snuba_query(
            QueryDatasets.EVENTS,
            "hello",
            "count_unique(tags[sentry:user])",
            timedelta(minutes=100),
            timedelta(minutes=2),
            self.environment,
            [SnubaQueryEventType.EventType.ERROR],
        )
        dataset = QueryDatasets.TRANSACTIONS
        query = "level:error"
        aggregate = "count()"
        time_window = timedelta(minutes=10)
        resolution = timedelta(minutes=1)
        event_types = [
            SnubaQueryEventType.EventType.ERROR,
            SnubaQueryEventType.EventType.DEFAULT
        ]
        update_snuba_query(
            snuba_query,
            dataset,
            query,
            aggregate,
            time_window,
            resolution,
            None,
            event_types,
        )
        assert snuba_query.dataset == dataset.value
        assert snuba_query.query == query
        assert snuba_query.aggregate == aggregate
        assert snuba_query.time_window == int(time_window.total_seconds())
        assert snuba_query.resolution == int(resolution.total_seconds())
        assert snuba_query.environment is None
        assert set(snuba_query.event_types) == set(event_types)

        event_types = [SnubaQueryEventType.EventType.DEFAULT]
        update_snuba_query(
            snuba_query,
            dataset,
            query,
            aggregate,
            time_window,
            resolution,
            None,
            event_types,
        )
        assert set(snuba_query.event_types) == set(event_types)
Пример #11
0
    def test(self):
        type = "something"
        dataset = QueryDatasets.EVENTS
        query = "level:error"
        time_window = timedelta(minutes=10)
        resolution = timedelta(minutes=1)
        snuba_query = create_snuba_query(
            dataset, query, "count()", time_window, resolution, self.environment
        )
        subscription = create_snuba_subscription(self.project, type, snuba_query)

        assert subscription.status == QuerySubscription.Status.CREATING.value
        assert subscription.project == self.project
        assert subscription.type == type
        assert subscription.subscription_id is None
 def create_subscription(self):
     with self.tasks():
         snuba_query = create_snuba_query(
             QueryDatasets.EVENTS,
             "hello",
             "count()",
             timedelta(minutes=1),
             timedelta(minutes=1),
             None,
         )
         sub = create_snuba_subscription(self.project, self.registration_key, snuba_query)
         sub.subscription_id = self.subscription_id
         sub.status = 0
         sub.save()
     return sub
Пример #13
0
 def test_environment(self):
     dataset = QueryDatasets.EVENTS
     query = "level:error"
     aggregation = QueryAggregations.TOTAL
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     snuba_query = create_snuba_query(dataset, query, aggregation,
                                      time_window, resolution,
                                      self.environment)
     assert snuba_query.dataset == dataset.value
     assert snuba_query.query == query
     assert snuba_query.aggregate == translate_aggregation(aggregation)
     assert snuba_query.time_window == int(time_window.total_seconds())
     assert snuba_query.resolution == int(resolution.total_seconds())
     assert snuba_query.environment == self.environment
Пример #14
0
 def test_environment(self):
     dataset = QueryDatasets.EVENTS
     query = "level:error"
     aggregate = "count()"
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     snuba_query = create_snuba_query(
         dataset, query, aggregate, time_window, resolution, self.environment
     )
     assert snuba_query.dataset == dataset.value
     assert snuba_query.query == query
     assert snuba_query.aggregate == aggregate
     assert snuba_query.time_window == int(time_window.total_seconds())
     assert snuba_query.resolution == int(resolution.total_seconds())
     assert snuba_query.environment == self.environment
     assert set(snuba_query.event_types) == set([SnubaQueryEventType.EventType.ERROR])
Пример #15
0
 def test_translated_query(self):
     type = "something"
     dataset = QueryDatasets.EVENTS
     query = "event.type:error"
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     with self.tasks():
         snuba_query = create_snuba_query(
             dataset, query, "count()", time_window, resolution, self.environment
         )
         subscription = create_snuba_subscription(self.project, type, snuba_query)
     subscription = QuerySubscription.objects.get(id=subscription.id)
     assert subscription.status == QuerySubscription.Status.ACTIVE.value
     assert subscription.project == self.project
     assert subscription.type == type
     assert subscription.subscription_id is not None
Пример #16
0
 def test_with_task(self):
     with self.tasks():
         type = "something"
         dataset = QueryDatasets.EVENTS
         query = "level:error"
         aggregation = QueryAggregations.TOTAL
         time_window = timedelta(minutes=10)
         resolution = timedelta(minutes=1)
         snuba_query = create_snuba_query(dataset, query, aggregation,
                                          time_window, resolution,
                                          self.environment)
         subscription = create_snuba_subscription(self.project, type,
                                                  snuba_query)
         subscription = QuerySubscription.objects.get(id=subscription.id)
         assert subscription.status == QuerySubscription.Status.ACTIVE.value
         assert subscription.project == self.project
         assert subscription.type == type
         assert subscription.subscription_id is not None
Пример #17
0
def convert_alert_rule_to_snuba_query(alert_rule):
    """
    Temporary method to convert existing alert rules to have a snuba query
    """
    if alert_rule.snuba_query:
        return

    with transaction.atomic():
        snuba_query = create_snuba_query(
            QueryDatasets(alert_rule.dataset),
            alert_rule.query,
            QueryAggregations(alert_rule.aggregation),
            timedelta(minutes=alert_rule.time_window),
            timedelta(minutes=alert_rule.resolution),
            alert_rule.environment,
        )
        alert_rule.update(snuba_query=snuba_query)
        alert_rule.query_subscriptions.all().update(snuba_query=snuba_query)
Пример #18
0
 def test(self):
     with self.tasks():
         snuba_query = create_snuba_query(
             QueryDatasets.EVENTS,
             "level:error",
             "count()",
             timedelta(minutes=10),
             timedelta(minutes=1),
             None,
         )
         subscription = create_snuba_subscription(self.project, "something", snuba_query)
     # Refetch since snuba creation happens in a task
     subscription = QuerySubscription.objects.get(id=subscription.id)
     subscription_id = subscription.subscription_id
     assert subscription_id is not None
     delete_snuba_subscription(subscription)
     assert subscription.status == QuerySubscription.Status.DELETING.value
     assert subscription.subscription_id == subscription_id
Пример #19
0
 def test(self):
     dataset = QueryDatasets.EVENTS
     snuba_query = create_snuba_query(
         dataset,
         "hello",
         "count_unique(tags[sentry:user])",
         timedelta(minutes=100),
         timedelta(minutes=2),
         self.environment,
     )
     query = "level:error"
     aggregate = "count()"
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     update_snuba_query(snuba_query, query, aggregate, time_window, resolution, None)
     assert snuba_query.dataset == dataset.value
     assert snuba_query.query == query
     assert snuba_query.aggregate == aggregate
     assert snuba_query.time_window == int(time_window.total_seconds())
     assert snuba_query.resolution == int(resolution.total_seconds())
     assert snuba_query.environment is None
Пример #20
0
    def test_subscriptions(self):
        dataset = QueryDatasets.EVENTS
        snuba_query = create_snuba_query(
            dataset,
            "hello",
            "count_unique(tags[sentry:user])",
            timedelta(minutes=100),
            timedelta(minutes=2),
            self.environment,
        )
        sub = create_snuba_subscription(self.project, "hi", snuba_query)

        new_env = self.create_environment()
        query = "level:error"
        aggregate = "count()"
        time_window = timedelta(minutes=10)
        resolution = timedelta(minutes=1)
        update_snuba_query(snuba_query, query, aggregate, time_window, resolution, new_env)
        sub.refresh_from_db()
        assert sub.snuba_query == snuba_query
        assert sub.status == QuerySubscription.Status.UPDATING.value
Пример #21
0
 def test(self):
     dataset = QueryDatasets.EVENTS
     snuba_query = create_snuba_query(
         dataset,
         "hello",
         QueryAggregations.UNIQUE_USERS,
         timedelta(minutes=100),
         timedelta(minutes=2),
         self.environment,
     )
     query = "level:error"
     aggregation = QueryAggregations.TOTAL
     time_window = timedelta(minutes=10)
     resolution = timedelta(minutes=1)
     update_snuba_query(snuba_query, query, aggregation, time_window,
                        resolution, None)
     assert snuba_query.dataset == dataset.value
     assert snuba_query.query == query
     assert snuba_query.aggregate == translate_aggregation(aggregation)
     assert snuba_query.time_window == int(time_window.total_seconds())
     assert snuba_query.resolution == int(resolution.total_seconds())
     assert snuba_query.environment is None
Пример #22
0
def create_alert_rule(
    organization,
    projects,
    name,
    query,
    aggregation,
    time_window,
    threshold_period,
    environment=None,
    include_all_projects=False,
    excluded_projects=None,
):
    """
    Creates an alert rule for an organization.

    :param organization:
    :param projects: A list of projects to subscribe to the rule. This will be overriden
    if `include_all_projects` is True
    :param name: Name for the alert rule. This will be used as part of the
    incident name, and must be unique per project
    :param query: An event search query to subscribe to and monitor for alerts
    :param aggregation: A QueryAggregation to fetch for this alert rule
    :param time_window: Time period to aggregate over, in minutes
    :param environment: An optional environment that this rule applies to
    :param threshold_period: How many update periods the value of the
    subscription needs to exceed the threshold before triggering
    :param include_all_projects: Whether to include all current and future projects
    from this organization
    :param excluded_projects: List of projects to exclude if we're using
    `include_all_projects`.

    :return: The created `AlertRule`
    """
    dataset = QueryDatasets.EVENTS
    resolution = DEFAULT_ALERT_RULE_RESOLUTION
    validate_alert_rule_query(query)
    if AlertRule.objects.filter(organization=organization, name=name).exists():
        raise AlertRuleNameAlreadyUsedError()
    with transaction.atomic():
        snuba_query = create_snuba_query(
            dataset,
            query,
            aggregation,
            timedelta(minutes=time_window),
            timedelta(minutes=resolution),
            environment,
        )
        alert_rule = AlertRule.objects.create(
            organization=organization,
            snuba_query=snuba_query,
            name=name,
            threshold_period=threshold_period,
            include_all_projects=include_all_projects,
        )

        if include_all_projects:
            excluded_projects = excluded_projects if excluded_projects else []
            projects = Project.objects.filter(
                organization=organization).exclude(
                    id__in=[p.id for p in excluded_projects])
            exclusions = [
                AlertRuleExcludedProjects(alert_rule=alert_rule,
                                          project=project)
                for project in excluded_projects
            ]
            AlertRuleExcludedProjects.objects.bulk_create(exclusions)

        subscribe_projects_to_alert_rule(alert_rule, projects)

    return alert_rule