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)
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())
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
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
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)
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
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] )
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()
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)
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
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
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])
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
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
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)
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
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
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
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
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