From 47f61365a6d9292c0ee1422fd8d4c8d166ce51ed Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Tue, 25 Apr 2023 10:25:45 -0700 Subject: [PATCH 1/8] initial checkin --- src/sentry/conf/server.py | 1 + src/sentry/monitors/endpoints/base.py | 4 +- .../monitor_ingest_checkin_details.py | 4 +- .../endpoints/monitor_ingest_checkin_index.py | 4 +- .../organization_monitor_checkin_index.py | 2 +- .../endpoints/organization_monitor_details.py | 3 ++ src/sentry/monitors/models.py | 39 +------------------ src/sentry/monitors/serializers.py | 4 -- 8 files changed, 10 insertions(+), 51 deletions(-) diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py index 9be705659b330d..aebdd4f8e74004 100644 --- a/src/sentry/conf/server.py +++ b/src/sentry/conf/server.py @@ -1075,6 +1075,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME(): "auth:register": True, # Enables the new artifact bundle uploads "organizations:artifact-bundles": False, + "organizations:monitors": True, # Enables alert creation on indexed events in UI (use for PoC/testing only) "organizations:alert-allow-indexed": False, # Enables tagging javascript errors from the browser console. diff --git a/src/sentry/monitors/endpoints/base.py b/src/sentry/monitors/endpoints/base.py index 1c0facc66567f0..3c06a7f6eccea1 100644 --- a/src/sentry/monitors/endpoints/base.py +++ b/src/sentry/monitors/endpoints/base.py @@ -225,7 +225,7 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): # which is unfinished (thus still mutable) if checkin_id == "latest": checkin = ( - MonitorCheckIn.objects.filter(monitor=monitor) + MonitorCheckIn.objects.filter(monitorenvironment__monitor=monitor) .exclude(status__in=CheckInStatus.FINISHED_VALUES) .order_by("-date_added") .first() @@ -240,6 +240,6 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): raise ParameterValidationError("Invalid check-in UUID") try: - return MonitorCheckIn.objects.get(monitor=monitor, guid=checkin_id) + return MonitorCheckIn.objects.get(monitorenvironment__monitor=monitor, guid=checkin_id) except MonitorCheckIn.DoesNotExist: raise ResourceDoesNotExist diff --git a/src/sentry/monitors/endpoints/monitor_ingest_checkin_details.py b/src/sentry/monitors/endpoints/monitor_ingest_checkin_details.py index 332bc1e4ca4afd..e46bcf2b562f11 100644 --- a/src/sentry/monitors/endpoints/monitor_ingest_checkin_details.py +++ b/src/sentry/monitors/endpoints/monitor_ingest_checkin_details.py @@ -102,12 +102,10 @@ def put( checkin.update(**params) if checkin.status == CheckInStatus.ERROR: - monitor_failed = monitor.mark_failed(current_datetime) - monitor_environment.mark_failed(current_datetime) + monitor_failed = monitor_environment.mark_failed(current_datetime) if not monitor_failed: return self.respond(serialize(checkin, request.user), status=208) else: - monitor.mark_ok(checkin, current_datetime) monitor_environment.mark_ok(checkin, current_datetime) return self.respond(serialize(checkin, request.user)) diff --git a/src/sentry/monitors/endpoints/monitor_ingest_checkin_index.py b/src/sentry/monitors/endpoints/monitor_ingest_checkin_index.py index fa02d4592d7755..57d215c4fab898 100644 --- a/src/sentry/monitors/endpoints/monitor_ingest_checkin_index.py +++ b/src/sentry/monitors/endpoints/monitor_ingest_checkin_index.py @@ -186,14 +186,12 @@ def post( signal_first_checkin(project, monitor) if checkin.status == CheckInStatus.ERROR and monitor.status != MonitorStatus.DISABLED: - monitor_failed = monitor.mark_failed(last_checkin=checkin.date_added) - monitor_environment.mark_failed(last_checkin=checkin.date_added) + monitor_failed = monitor_environment.mark_failed(last_checkin=checkin.date_added) if not monitor_failed: if isinstance(request.auth, ProjectKey): return self.respond(status=200) return self.respond(serialize(checkin, request.user), status=200) else: - monitor.mark_ok(checkin, checkin.date_added) monitor_environment.mark_ok(checkin, checkin.date_added) if isinstance(request.auth, ProjectKey): diff --git a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py index 2f7d7bf4d60391..c0ab7042b66be4 100644 --- a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py +++ b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py @@ -57,7 +57,7 @@ def get(self, request: Request, organization, project, monitor) -> Response: raise ParseError(detail="Invalid date range") queryset = MonitorCheckIn.objects.filter( - monitor_id=monitor.id, date_added__gte=start, date_added__lte=end + monitorenvironment__monitor__id=monitor.id, date_added__gte=start, date_added__lte=end ) environments = get_environments(request, organization) diff --git a/src/sentry/monitors/endpoints/organization_monitor_details.py b/src/sentry/monitors/endpoints/organization_monitor_details.py index 7a3b808deeae17..2d979786210619 100644 --- a/src/sentry/monitors/endpoints/organization_monitor_details.py +++ b/src/sentry/monitors/endpoints/organization_monitor_details.py @@ -99,6 +99,7 @@ def put(self, request: Request, organization, project, monitor) -> Response: if "slug" in result: params["slug"] = result["slug"] if "status" in result: + # TODO(rjo100): resets status if monitor is failed, needs fixing with environments if result["status"] == MonitorStatus.ACTIVE: if monitor.status not in (MonitorStatus.OK, MonitorStatus.ERROR): params["status"] = MonitorStatus.ACTIVE @@ -111,6 +112,8 @@ def put(self, request: Request, organization, project, monitor) -> Response: if params: monitor.update(**params) + if params.get("status"): + MonitorEnvironment.objects.filter(monitor=monitor).update(status=params["status"]) self.create_audit_entry( request=request, organization=organization, diff --git a/src/sentry/monitors/models.py b/src/sentry/monitors/models.py index cadd467910b4dd..cfcdfba8095c1e 100644 --- a/src/sentry/monitors/models.py +++ b/src/sentry/monitors/models.py @@ -218,43 +218,6 @@ def get_next_scheduled_checkin(self, last_checkin): ) return next_checkin + timedelta(minutes=int(self.config.get("checkin_margin") or 0)) - def mark_failed(self, last_checkin=None, reason=MonitorFailure.UNKNOWN): - if last_checkin is None: - next_checkin_base = timezone.now() - last_checkin = self.last_checkin or timezone.now() - else: - next_checkin_base = last_checkin - - new_status = MonitorStatus.ERROR - if reason == MonitorFailure.MISSED_CHECKIN: - new_status = MonitorStatus.MISSED_CHECKIN - - affected = ( - type(self) - .objects.filter( - Q(last_checkin__lte=last_checkin) | Q(last_checkin__isnull=True), id=self.id - ) - .update( - next_checkin=self.get_next_scheduled_checkin(next_checkin_base), - status=new_status, - last_checkin=last_checkin, - ) - ) - if not affected: - return False - - return True - - def mark_ok(self, checkin: MonitorCheckIn, ts: datetime): - params = { - "last_checkin": ts, - "next_checkin": self.get_next_scheduled_checkin(ts), - } - if checkin.status == CheckInStatus.OK and self.status != MonitorStatus.DISABLED: - params["status"] = MonitorStatus.OK - - Monitor.objects.filter(id=self.id).exclude(last_checkin__gt=ts).update(**params) - @region_silo_only_model class MonitorCheckIn(Model): @@ -417,7 +380,7 @@ def mark_ok(self, checkin: MonitorCheckIn, ts: datetime): "last_checkin": ts, "next_checkin": self.monitor.get_next_scheduled_checkin(ts), } - if checkin.status == CheckInStatus.OK and self.status != MonitorStatus.DISABLED: + if checkin.status == CheckInStatus.OK and self.monitor.status != MonitorStatus.DISABLED: params["status"] = MonitorStatus.OK MonitorEnvironment.objects.filter(id=self.id).exclude(last_checkin__gt=ts).update(**params) diff --git a/src/sentry/monitors/serializers.py b/src/sentry/monitors/serializers.py index f3521ab1c7c5d7..3c424089f6e391 100644 --- a/src/sentry/monitors/serializers.py +++ b/src/sentry/monitors/serializers.py @@ -86,8 +86,6 @@ def serialize(self, obj, attrs, user): "name": obj.name, "slug": obj.slug, "config": config, - "lastCheckIn": obj.last_checkin, - "nextCheckIn": obj.next_checkin, "dateCreated": obj.date_added, "project": attrs["project"], "environments": attrs["environments"], @@ -102,8 +100,6 @@ class MonitorSerializerResponse(TypedDict): type: str config: Any dateCreated: datetime - lastCheckIn: datetime - nextCheckIn: datetime project: ProjectSerializerResponse environments: MonitorEnvironmentSerializerResponse From e4f85d746c2aada3cd6a1c9173848ed708924aac Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Tue, 25 Apr 2023 11:18:46 -0700 Subject: [PATCH 2/8] test --- src/sentry/monitors/consumers/check_in.py | 2 - .../organization_monitor_checkin_index.py | 3 +- src/sentry/monitors/tasks.py | 2 - .../test_monitor_ingest_checkin_index.py | 15 ------ ...test_organization_monitor_checkin_index.py | 13 ++++- .../endpoints/test_organization_monitors.py | 6 +-- tests/sentry/monitors/test_models.py | 37 ++++++-------- .../sentry/monitors/test_monitor_consumer.py | 49 +++++++------------ tests/sentry/monitors/test_tasks.py | 38 +++++--------- 9 files changed, 62 insertions(+), 103 deletions(-) diff --git a/src/sentry/monitors/consumers/check_in.py b/src/sentry/monitors/consumers/check_in.py index 3f3a3b4be83316..ff02510e486c3c 100644 --- a/src/sentry/monitors/consumers/check_in.py +++ b/src/sentry/monitors/consumers/check_in.py @@ -161,10 +161,8 @@ def _process_message(wrapper: Dict) -> None: signal_first_checkin(project, monitor) if check_in.status == CheckInStatus.ERROR and monitor.status != MonitorStatus.DISABLED: - monitor.mark_failed(start_time) monitor_environment.mark_failed(start_time) else: - monitor.mark_ok(check_in, start_time) monitor_environment.mark_ok(check_in, start_time) metrics.incr( diff --git a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py index c0ab7042b66be4..c9e142930f27e2 100644 --- a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py +++ b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py @@ -56,8 +56,9 @@ def get(self, request: Request, organization, project, monitor) -> Response: if start is None or end is None: raise ParseError(detail="Invalid date range") + # TODO(rjo100): switch this to query monitor environment when hack is removed queryset = MonitorCheckIn.objects.filter( - monitorenvironment__monitor__id=monitor.id, date_added__gte=start, date_added__lte=end + monitor__id=monitor.id, date_added__gte=start, date_added__lte=end ) environments = get_environments(request, organization) diff --git a/src/sentry/monitors/tasks.py b/src/sentry/monitors/tasks.py index 8249dab6d8bd43..9133e7255c5d71 100644 --- a/src/sentry/monitors/tasks.py +++ b/src/sentry/monitors/tasks.py @@ -70,7 +70,6 @@ def check_monitors(current_datetime=None): monitor_environment=monitor_environment, status=CheckInStatus.MISSED, ) - monitor_environment.monitor.mark_failed(reason=MonitorFailure.MISSED_CHECKIN) monitor_environment.mark_failed(reason=MonitorFailure.MISSED_CHECKIN) qs = ( @@ -106,5 +105,4 @@ def check_monitors(current_datetime=None): status__in=[CheckInStatus.OK, CheckInStatus.ERROR], ).exists() if not has_newer_result: - monitor_environment.monitor.mark_failed(reason=MonitorFailure.DURATION) monitor_environment.mark_failed(reason=MonitorFailure.DURATION) diff --git a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_index.py b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_index.py index ca5e43687fc379..cdd95e36aa307d 100644 --- a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_index.py +++ b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_index.py @@ -75,11 +75,6 @@ def test_passing(self, mock_record): checkin = MonitorCheckIn.objects.get(guid=resp.data["id"]) assert checkin.status == CheckInStatus.OK - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.OK assert monitor_environment.last_checkin == checkin.date_added @@ -109,11 +104,6 @@ def test_failing(self): checkin = MonitorCheckIn.objects.get(guid=resp.data["id"]) assert checkin.status == CheckInStatus.ERROR - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.ERROR - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.ERROR assert monitor_environment.last_checkin == checkin.date_added @@ -132,11 +122,6 @@ def test_disabled(self): checkin = MonitorCheckIn.objects.get(guid=resp.data["id"]) assert checkin.status == CheckInStatus.ERROR - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.DISABLED - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.DISABLED assert monitor_environment.last_checkin == checkin.date_added diff --git a/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_index.py b/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_index.py index b591c2efe00c4e..26743c3c8128a8 100644 --- a/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_index.py +++ b/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_index.py @@ -20,14 +20,18 @@ def setUp(self): def test_simple(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin1 = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added - timedelta(minutes=2), status=CheckInStatus.OK, ) checkin2 = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added - timedelta(minutes=1), status=CheckInStatus.OK, @@ -44,10 +48,12 @@ def test_simple(self): def test_statsperiod_constraints(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) checkin = MonitorCheckIn.objects.create( project_id=self.project.id, monitor_id=monitor.id, + monitor_environment_id=monitor_environment.id, status=MonitorStatus.OK, date_added=timezone.now() - timedelta(hours=12), ) @@ -79,6 +85,8 @@ def test_simple_environment(self): monitor = self._create_monitor() monitor_environment = self._create_monitor_environment(monitor, name="jungle") + monitor_environment_2 = self._create_monitor_environment(monitor, name="volcano") + checkin1 = MonitorCheckIn.objects.create( monitor=monitor, monitor_environment=monitor_environment, @@ -88,6 +96,7 @@ def test_simple_environment(self): ) MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment_2, project_id=self.project.id, date_added=monitor.date_added - timedelta(minutes=1), status=CheckInStatus.OK, @@ -105,6 +114,7 @@ def test_hack_environment_production_includes_all(self): monitor = self._create_monitor() monitor_environment = self._create_monitor_environment(monitor, name="production") + checkin1 = MonitorCheckIn.objects.create( monitor=monitor, monitor_environment=monitor_environment, @@ -114,6 +124,7 @@ def test_hack_environment_production_includes_all(self): ) checkin2 = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=None, project_id=self.project.id, date_added=monitor.date_added - timedelta(minutes=1), status=CheckInStatus.OK, @@ -128,7 +139,7 @@ def test_hack_environment_production_includes_all(self): status=CheckInStatus.OK, ) - # When querying for he production environment checkins all non + # When querying for the production environment checkins all non # environment checkins are included resp = self.get_success_response( self.organization.slug, diff --git a/tests/sentry/monitors/endpoints/test_organization_monitors.py b/tests/sentry/monitors/endpoints/test_organization_monitors.py index 6bc1d4872ff613..679e2cf13167f9 100644 --- a/tests/sentry/monitors/endpoints/test_organization_monitors.py +++ b/tests/sentry/monitors/endpoints/test_organization_monitors.py @@ -105,10 +105,10 @@ def test_monitor_environment(self): self.check_valid_response(response, [monitor]) def test_monitor_environment_include_new(self): - monitor = self._create_monitor( - status=MonitorStatus.OK, last_checkin=datetime.now() - timedelta(minutes=1) + monitor = self._create_monitor() + self._create_monitor_environment( + monitor, status=MonitorStatus.OK, last_checkin=datetime.now() - timedelta(minutes=1) ) - self._create_monitor_environment(monitor) monitor_visible = self._create_monitor(name="visible") diff --git a/tests/sentry/monitors/test_models.py b/tests/sentry/monitors/test_models.py index d6d23bac8bca75..4d96544d183402 100644 --- a/tests/sentry/monitors/test_models.py +++ b/tests/sentry/monitors/test_models.py @@ -19,59 +19,64 @@ class MonitorTestCase(TestCase): def test_next_run_crontab_implicit(self): ts = datetime(2019, 1, 1, 1, 10, 20, tzinfo=timezone.utc) - monitor = Monitor(last_checkin=ts, config={"schedule": "* * * * *"}) - assert monitor.get_next_scheduled_checkin(ts) == datetime( + monitor = Monitor(config={"schedule": "* * * * *"}) + monitor_environment = MonitorEnvironment(monitor=monitor, last_checkin=ts) + + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 1, 11, tzinfo=timezone.utc ) monitor.config["schedule"] = "*/5 * * * *" - assert monitor.get_next_scheduled_checkin(ts) == datetime( + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 1, 15, tzinfo=timezone.utc ) def test_next_run_crontab_explicit(self): ts = datetime(2019, 1, 1, 1, 10, 20, tzinfo=timezone.utc) monitor = Monitor( - last_checkin=ts, config={"schedule": "* * * * *", "schedule_type": ScheduleType.CRONTAB}, ) - assert monitor.get_next_scheduled_checkin(ts) == datetime( + monitor_environment = MonitorEnvironment(monitor=monitor, last_checkin=ts) + + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 1, 11, tzinfo=timezone.utc ) monitor.config["schedule"] = "*/5 * * * *" - assert monitor.get_next_scheduled_checkin(ts) == datetime( + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 1, 15, tzinfo=timezone.utc ) def test_next_run_crontab_explicit_timezone(self): ts = datetime(2019, 1, 1, 1, 10, 20, tzinfo=timezone.utc) monitor = Monitor( - last_checkin=ts, config={ "schedule": "0 12 * * *", "schedule_type": ScheduleType.CRONTAB, "timezone": "UTC", }, ) - assert monitor.get_next_scheduled_checkin(ts) == datetime( + monitor_environment = MonitorEnvironment(monitor=monitor, last_checkin=ts) + + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 12, 00, tzinfo=timezone.utc ) # Europe/Berlin == UTC+01:00. # the run should be represented 1 hours earlier in UTC time monitor.config["timezone"] = "Europe/Berlin" - assert monitor.get_next_scheduled_checkin(ts) == datetime( + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 1, 1, 11, 00, tzinfo=timezone.utc ) def test_next_run_interval(self): ts = datetime(2019, 1, 1, 1, 10, 20, tzinfo=timezone.utc) monitor = Monitor( - last_checkin=ts, config={"schedule": [1, "month"], "schedule_type": ScheduleType.INTERVAL}, ) - assert monitor.get_next_scheduled_checkin(ts) == datetime( + monitor_environment = MonitorEnvironment(monitor=monitor, last_checkin=ts) + + assert monitor_environment.monitor.get_next_scheduled_checkin(ts) == datetime( 2019, 2, 1, 1, 10, 20, tzinfo=timezone.utc ) @@ -125,10 +130,7 @@ def test_mark_failed_default_params(self, mock_insert_data_to_database_legacy): monitor=monitor, environment=self.environment, status=monitor.status, - next_checkin=monitor.next_checkin, - last_checkin=monitor.last_checkin, ) - assert monitor.mark_failed() assert monitor_environment.mark_failed() assert len(mock_insert_data_to_database_legacy.mock_calls) == 1 @@ -172,10 +174,7 @@ def test_mark_failed_with_reason(self, mock_insert_data_to_database_legacy): monitor=monitor, environment=self.environment, status=monitor.status, - next_checkin=monitor.next_checkin, - last_checkin=monitor.last_checkin, ) - assert monitor.mark_failed(reason=MonitorFailure.DURATION) assert monitor_environment.mark_failed(reason=MonitorFailure.DURATION) assert len(mock_insert_data_to_database_legacy.mock_calls) == 1 @@ -219,15 +218,11 @@ def test_mark_failed_with_missed_reason(self, mock_insert_data_to_database_legac monitor=monitor, environment=self.environment, status=monitor.status, - next_checkin=monitor.next_checkin, - last_checkin=monitor.last_checkin, ) - assert monitor.mark_failed(reason=MonitorFailure.MISSED_CHECKIN) assert monitor_environment.mark_failed(reason=MonitorFailure.MISSED_CHECKIN) monitor.refresh_from_db() monitor_environment.refresh_from_db() - assert monitor.status == MonitorStatus.MISSED_CHECKIN assert monitor_environment.status == MonitorStatus.MISSED_CHECKIN assert len(mock_insert_data_to_database_legacy.mock_calls) == 1 diff --git a/tests/sentry/monitors/test_monitor_consumer.py b/tests/sentry/monitors/test_monitor_consumer.py index 35f78623874e80..a18bc67f6e76fa 100644 --- a/tests/sentry/monitors/test_monitor_consumer.py +++ b/tests/sentry/monitors/test_monitor_consumer.py @@ -94,11 +94,6 @@ def test_payload(self) -> None: checkin = MonitorCheckIn.objects.get(guid=self.message_guid) assert checkin.status == CheckInStatus.OK - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.OK assert monitor_environment.last_checkin == checkin.date_added @@ -115,11 +110,6 @@ def test_passing(self) -> None: checkin = MonitorCheckIn.objects.get(guid=self.guid) assert checkin.status == CheckInStatus.OK - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.OK assert monitor_environment.last_checkin == checkin.date_added @@ -136,11 +126,6 @@ def test_failing(self): checkin = MonitorCheckIn.objects.get(guid=self.guid) assert checkin.status == CheckInStatus.ERROR - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.ERROR - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.ERROR assert monitor_environment.last_checkin == checkin.date_added @@ -157,11 +142,6 @@ def test_disabled(self): checkin = MonitorCheckIn.objects.get(guid=self.guid) assert checkin.status == CheckInStatus.ERROR - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.DISABLED - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.DISABLED assert monitor_environment.last_checkin == checkin.date_added @@ -188,11 +168,6 @@ def test_monitor_environment(self): checkin = MonitorCheckIn.objects.get(guid=self.guid) assert checkin.status == CheckInStatus.OK - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) - monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) assert monitor_environment.status == MonitorStatus.OK assert monitor_environment.environment.name == "jungle" @@ -212,10 +187,15 @@ def test_monitor_create(self): checkin = MonitorCheckIn.objects.get(guid=self.guid) assert checkin.status == CheckInStatus.OK - monitor = Monitor.objects.get(slug="my-new-monitor") - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) + monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) + assert monitor_environment.status == MonitorStatus.OK + assert monitor_environment.monitor.name == "my-new-monitor" + assert monitor_environment.environment.name == "production" + assert monitor_environment.last_checkin == checkin.date_added + assert ( + monitor_environment.next_checkin + == monitor_environment.monitor.get_next_scheduled_checkin(checkin.date_added) + ) @pytest.mark.django_db def test_monitor_update(self): @@ -231,9 +211,14 @@ def test_monitor_update(self): monitor = Monitor.objects.get(id=monitor.id) assert monitor.config["schedule"] == "13 * * * *" - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin == checkin.date_added - assert monitor.next_checkin == monitor.get_next_scheduled_checkin(checkin.date_added) + + monitor_environment = MonitorEnvironment.objects.get(id=checkin.monitor_environment.id) + assert monitor_environment.status == MonitorStatus.OK + assert monitor_environment.last_checkin == checkin.date_added + assert ( + monitor_environment.next_checkin + == monitor_environment.monitor.get_next_scheduled_checkin(checkin.date_added) + ) def test_rate_limit(self): monitor = self._create_monitor(slug="my-monitor") diff --git a/tests/sentry/monitors/test_tasks.py b/tests/sentry/monitors/test_tasks.py index 6532f373505cfb..172b6ac331a877 100644 --- a/tests/sentry/monitors/test_tasks.py +++ b/tests/sentry/monitors/test_tasks.py @@ -37,7 +37,6 @@ def test_missing_checkin(self): check_monitors() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.MISSED_CHECKIN).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.MISSED_CHECKIN ).exists() @@ -66,7 +65,6 @@ def test_missing_checkin_but_disabled(self): check_monitors() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.DISABLED).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.DISABLED ).exists() @@ -92,7 +90,6 @@ def test_missing_checkin_but_pending_deletion(self): check_monitors() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.PENDING_DELETION).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.PENDING_DELETION ).exists() @@ -118,9 +115,6 @@ def test_missing_checkin_but_deletion_in_progress(self): check_monitors() - assert Monitor.objects.filter( - id=monitor.id, status=MonitorStatus.DELETION_IN_PROGRESS - ).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.DELETION_IN_PROGRESS ).exists() @@ -149,7 +143,6 @@ def test_not_missing_checkin(self): check_monitors() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.OK).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.OK ).exists() @@ -163,8 +156,6 @@ def test_timeout_with_no_future_complete_checkin(self): monitor = Monitor.objects.create( organization_id=org.id, project_id=project.id, - next_checkin=current_datetime + timedelta(hours=12, minutes=1), - last_checkin=current_datetime + timedelta(hours=12), type=MonitorType.CRON_JOB, config={"schedule": "0 0 * * *"}, status=MonitorStatus.OK, @@ -173,7 +164,8 @@ def test_timeout_with_no_future_complete_checkin(self): monitor_environment = MonitorEnvironment.objects.create( monitor=monitor, environment=self.environment, - next_checkin=monitor.next_checkin, + next_checkin=current_datetime + timedelta(hours=12, minutes=1), + last_checkin=current_datetime + timedelta(hours=12), status=monitor.status, ) checkin = MonitorCheckIn.objects.create( @@ -189,8 +181,8 @@ def test_timeout_with_no_future_complete_checkin(self): monitor_environment=monitor_environment, project_id=project.id, status=CheckInStatus.IN_PROGRESS, - date_added=monitor.last_checkin, - date_updated=monitor.last_checkin, + date_added=monitor_environment.last_checkin, + date_updated=monitor_environment.last_checkin, ) assert checkin.date_added == checkin.date_updated == current_datetime @@ -203,7 +195,6 @@ def test_timeout_with_no_future_complete_checkin(self): id=checkin2.id, status=CheckInStatus.IN_PROGRESS ).exists() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.ERROR).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.ERROR ).exists() @@ -217,8 +208,6 @@ def test_timeout_with_future_complete_checkin(self): monitor = Monitor.objects.create( organization_id=org.id, project_id=project.id, - next_checkin=current_datetime + timedelta(hours=12, minutes=1), - last_checkin=current_datetime + timedelta(hours=12), type=MonitorType.CRON_JOB, config={"schedule": "0 0 * * *"}, status=MonitorStatus.OK, @@ -227,7 +216,8 @@ def test_timeout_with_future_complete_checkin(self): monitor_environment = MonitorEnvironment.objects.create( monitor=monitor, environment=self.environment, - next_checkin=monitor.next_checkin, + next_checkin=current_datetime + timedelta(hours=12, minutes=1), + last_checkin=current_datetime + timedelta(hours=12), status=monitor.status, ) checkin = MonitorCheckIn.objects.create( @@ -243,8 +233,8 @@ def test_timeout_with_future_complete_checkin(self): monitor_environment=monitor_environment, project_id=project.id, status=CheckInStatus.OK, - date_added=monitor.last_checkin, - date_updated=monitor.last_checkin, + date_added=monitor_environment.last_checkin, + date_updated=monitor_environment.last_checkin, ) assert checkin.date_added == checkin.date_updated == current_datetime @@ -255,7 +245,6 @@ def test_timeout_with_future_complete_checkin(self): assert MonitorCheckIn.objects.filter(id=checkin2.id, status=CheckInStatus.OK).exists() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.OK).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.OK ).exists() @@ -269,8 +258,6 @@ def test_timeout_with_via_configuration(self): monitor = Monitor.objects.create( organization_id=org.id, project_id=project.id, - next_checkin=current_datetime + timedelta(hours=1, minutes=1), - last_checkin=current_datetime + timedelta(hours=1), type=MonitorType.CRON_JOB, config={"schedule": "0 0 * * *", "max_runtime": 60}, status=MonitorStatus.OK, @@ -279,7 +266,8 @@ def test_timeout_with_via_configuration(self): monitor_environment = MonitorEnvironment.objects.create( monitor=monitor, environment=self.environment, - next_checkin=monitor.next_checkin, + next_checkin=current_datetime + timedelta(hours=1, minutes=1), + last_checkin=current_datetime + timedelta(hours=1), status=monitor.status, ) checkin = MonitorCheckIn.objects.create( @@ -297,7 +285,6 @@ def test_timeout_with_via_configuration(self): assert MonitorCheckIn.objects.filter(id=checkin.id, status=CheckInStatus.ERROR).exists() - assert Monitor.objects.filter(id=monitor.id, status=MonitorStatus.ERROR).exists() assert MonitorEnvironment.objects.filter( id=monitor_environment.id, status=MonitorStatus.ERROR ).exists() @@ -311,8 +298,6 @@ def test_killswitch(self): monitor = Monitor.objects.create( organization_id=org.id, project_id=project.id, - next_checkin=current_datetime + timedelta(hours=12, minutes=1), - last_checkin=current_datetime + timedelta(hours=12), type=MonitorType.CRON_JOB, config={"schedule": "0 0 * * *"}, status=MonitorStatus.OK, @@ -321,7 +306,8 @@ def test_killswitch(self): monitor_environment = MonitorEnvironment.objects.create( monitor=monitor, environment=self.environment, - next_checkin=monitor.next_checkin, + next_checkin=current_datetime + timedelta(hours=12, minutes=1), + last_checkin=current_datetime + timedelta(hours=12), status=monitor.status, ) checkin = MonitorCheckIn.objects.create( From 2d28f7a391ceccc2a93c586e4bf02d9b68ceb860 Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Tue, 25 Apr 2023 11:19:09 -0700 Subject: [PATCH 3/8] remove config --- src/sentry/conf/server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py index aebdd4f8e74004..9be705659b330d 100644 --- a/src/sentry/conf/server.py +++ b/src/sentry/conf/server.py @@ -1075,7 +1075,6 @@ def SOCIAL_AUTH_DEFAULT_USERNAME(): "auth:register": True, # Enables the new artifact bundle uploads "organizations:artifact-bundles": False, - "organizations:monitors": True, # Enables alert creation on indexed events in UI (use for PoC/testing only) "organizations:alert-allow-indexed": False, # Enables tagging javascript errors from the browser console. From 0f747c1088e82e3c0d9eef01cd6eb13c4e909ee6 Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Tue, 25 Apr 2023 12:01:58 -0700 Subject: [PATCH 4/8] fixed tests --- src/sentry/monitors/endpoints/base.py | 4 +- .../test_monitor_ingest_checkin_attachment.py | 39 +++++++++++++++++-- .../test_monitor_ingest_checkin_details.py | 21 +++------- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/sentry/monitors/endpoints/base.py b/src/sentry/monitors/endpoints/base.py index 3c06a7f6eccea1..4043bebb97d133 100644 --- a/src/sentry/monitors/endpoints/base.py +++ b/src/sentry/monitors/endpoints/base.py @@ -225,7 +225,7 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): # which is unfinished (thus still mutable) if checkin_id == "latest": checkin = ( - MonitorCheckIn.objects.filter(monitorenvironment__monitor=monitor) + MonitorCheckIn.objects.filter(monitor_environment__monitor=monitor) .exclude(status__in=CheckInStatus.FINISHED_VALUES) .order_by("-date_added") .first() @@ -240,6 +240,6 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): raise ParameterValidationError("Invalid check-in UUID") try: - return MonitorCheckIn.objects.get(monitorenvironment__monitor=monitor, guid=checkin_id) + return MonitorCheckIn.objects.get(monitor_environment__monitor=monitor, guid=checkin_id) except MonitorCheckIn.DoesNotExist: raise ResourceDoesNotExist diff --git a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_attachment.py b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_attachment.py index 54f4613cf65c79..3cf9cab989290d 100644 --- a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_attachment.py +++ b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_attachment.py @@ -5,8 +5,14 @@ from django.urls import reverse from django.utils import timezone -from sentry.models import File -from sentry.monitors.models import CheckInStatus, Monitor, MonitorCheckIn, MonitorType +from sentry.models import Environment, File +from sentry.monitors.models import ( + CheckInStatus, + Monitor, + MonitorCheckIn, + MonitorEnvironment, + MonitorType, +) from sentry.testutils import MonitorIngestTestCase from sentry.testutils.silo import region_silo_test @@ -22,16 +28,31 @@ def _create_monitor(self): return Monitor.objects.create( organization_id=self.organization.id, project_id=self.project.id, - next_checkin=timezone.now() - timedelta(minutes=1), type=MonitorType.CRON_JOB, config={"schedule": "* * * * *"}, date_added=timezone.now() - timedelta(minutes=1), ) + def _create_monitor_environment(self, monitor, name="production", **kwargs): + environment = Environment.get_or_create(project=self.project, name=name) + + monitorenvironment_defaults = { + "status": monitor.status, + "next_checkin": timezone.now() - timedelta(minutes=1), + **kwargs, + } + + return MonitorEnvironment.objects.create( + monitor=monitor, environment=environment, **monitorenvironment_defaults + ) + def test_upload(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, @@ -60,8 +81,11 @@ def test_upload(self): def test_upload_no_file(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, @@ -83,8 +107,11 @@ def test_upload_no_file(self): ) def test_upload_file_too_big(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, @@ -107,8 +134,11 @@ def test_upload_file_too_big(self): def test_duplicate_upload(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, @@ -151,8 +181,11 @@ def test_duplicate_upload(self): def test_invalid_file_upload(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) + checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, diff --git a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_details.py b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_details.py index b1ba1092c228fb..9b97d167e6f10b 100644 --- a/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_details.py +++ b/tests/sentry/monitors/endpoints/test_monitor_ingest_checkin_details.py @@ -104,11 +104,6 @@ def test_passing(self): checkin.monitor_environment.environment.name == monitor_environment.environment.name ) - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.next_checkin > checkin.date_added - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin > checkin.date_added - monitor_environment = MonitorEnvironment.objects.get(id=monitor_environment.id) assert monitor_environment.next_checkin > checkin.date_added assert monitor_environment.status == MonitorStatus.OK @@ -116,8 +111,12 @@ def test_passing(self): def test_passing_with_slug(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) checkin = MonitorCheckIn.objects.create( - monitor=monitor, project_id=self.project.id, date_added=monitor.date_added + monitor=monitor, + monitor_environment=monitor_environment, + project_id=self.project.id, + date_added=monitor.date_added, ) path = reverse( @@ -147,11 +146,6 @@ def test_failing(self): checkin = MonitorCheckIn.objects.get(id=checkin.id) assert checkin.status == CheckInStatus.ERROR - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.next_checkin > checkin.date_added - assert monitor.status == MonitorStatus.ERROR - assert monitor.last_checkin > checkin.date_added - monitor_environment = MonitorEnvironment.objects.get(id=monitor_environment.id) assert monitor_environment.next_checkin > checkin.date_added assert monitor_environment.status == MonitorStatus.ERROR @@ -196,11 +190,6 @@ def test_latest_returns_last_unfinished(self): checkin3 = MonitorCheckIn.objects.get(id=checkin3.id) assert checkin3.status == CheckInStatus.OK - monitor = Monitor.objects.get(id=monitor.id) - assert monitor.next_checkin > checkin2.date_added - assert monitor.status == MonitorStatus.OK - assert monitor.last_checkin > checkin2.date_added - monitor_environment = MonitorEnvironment.objects.get(id=monitor_environment.id) assert monitor_environment.next_checkin > checkin2.date_added assert monitor_environment.status == MonitorStatus.OK From 54d581f5265fbed33155d798ec1a71f4f11b3ff3 Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Tue, 25 Apr 2023 12:31:56 -0700 Subject: [PATCH 5/8] fixed more tests --- .../endpoints/test_organization_monitor_checkin_attachment.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_attachment.py b/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_attachment.py index 203e44bb584931..dce5d9354837c8 100644 --- a/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_attachment.py +++ b/tests/sentry/monitors/endpoints/test_organization_monitor_checkin_attachment.py @@ -18,8 +18,10 @@ def test_download(self): file.putfile(ContentFile(b"some data!")) monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, @@ -32,8 +34,10 @@ def test_download(self): def test_download_no_file(self): monitor = self._create_monitor() + monitor_environment = self._create_monitor_environment(monitor) checkin = MonitorCheckIn.objects.create( monitor=monitor, + monitor_environment=monitor_environment, project_id=self.project.id, date_added=monitor.date_added, status=CheckInStatus.IN_PROGRESS, From 540e0c43849b82c8da88fd57a7d6f7a80f3d0163 Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Wed, 26 Apr 2023 11:05:20 -0700 Subject: [PATCH 6/8] Update organization_monitor_checkin_index.py --- .../monitors/endpoints/organization_monitor_checkin_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py index c9e142930f27e2..366604eda397f3 100644 --- a/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py +++ b/src/sentry/monitors/endpoints/organization_monitor_checkin_index.py @@ -58,7 +58,7 @@ def get(self, request: Request, organization, project, monitor) -> Response: # TODO(rjo100): switch this to query monitor environment when hack is removed queryset = MonitorCheckIn.objects.filter( - monitor__id=monitor.id, date_added__gte=start, date_added__lte=end + monitor_id=monitor.id, date_added__gte=start, date_added__lte=end ) environments = get_environments(request, organization) From f9c9e6288e6abc8579af293fdf19763bd6c74efe Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Wed, 26 Apr 2023 15:20:12 -0700 Subject: [PATCH 7/8] undo changes --- src/sentry/monitors/endpoints/base.py | 4 ++-- src/sentry/monitors/endpoints/organization_monitor_details.py | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sentry/monitors/endpoints/base.py b/src/sentry/monitors/endpoints/base.py index 4043bebb97d133..1c0facc66567f0 100644 --- a/src/sentry/monitors/endpoints/base.py +++ b/src/sentry/monitors/endpoints/base.py @@ -225,7 +225,7 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): # which is unfinished (thus still mutable) if checkin_id == "latest": checkin = ( - MonitorCheckIn.objects.filter(monitor_environment__monitor=monitor) + MonitorCheckIn.objects.filter(monitor=monitor) .exclude(status__in=CheckInStatus.FINISHED_VALUES) .order_by("-date_added") .first() @@ -240,6 +240,6 @@ def try_checkin_lookup(monitor: Monitor, checkin_id: str): raise ParameterValidationError("Invalid check-in UUID") try: - return MonitorCheckIn.objects.get(monitor_environment__monitor=monitor, guid=checkin_id) + return MonitorCheckIn.objects.get(monitor=monitor, guid=checkin_id) except MonitorCheckIn.DoesNotExist: raise ResourceDoesNotExist diff --git a/src/sentry/monitors/endpoints/organization_monitor_details.py b/src/sentry/monitors/endpoints/organization_monitor_details.py index 2d979786210619..7a3b808deeae17 100644 --- a/src/sentry/monitors/endpoints/organization_monitor_details.py +++ b/src/sentry/monitors/endpoints/organization_monitor_details.py @@ -99,7 +99,6 @@ def put(self, request: Request, organization, project, monitor) -> Response: if "slug" in result: params["slug"] = result["slug"] if "status" in result: - # TODO(rjo100): resets status if monitor is failed, needs fixing with environments if result["status"] == MonitorStatus.ACTIVE: if monitor.status not in (MonitorStatus.OK, MonitorStatus.ERROR): params["status"] = MonitorStatus.ACTIVE @@ -112,8 +111,6 @@ def put(self, request: Request, organization, project, monitor) -> Response: if params: monitor.update(**params) - if params.get("status"): - MonitorEnvironment.objects.filter(monitor=monitor).update(status=params["status"]) self.create_audit_entry( request=request, organization=organization, From 9f8143c823022a9c7b8825f7d8f20829b9c1ac39 Mon Sep 17 00:00:00 2001 From: Richard Ortenberg Date: Wed, 26 Apr 2023 16:57:43 -0700 Subject: [PATCH 8/8] fix status display for Monitor object --- src/sentry/monitors/models.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sentry/monitors/models.py b/src/sentry/monitors/models.py index cfcdfba8095c1e..27c1ebfb265030 100644 --- a/src/sentry/monitors/models.py +++ b/src/sentry/monitors/models.py @@ -218,6 +218,17 @@ def get_next_scheduled_checkin(self, last_checkin): ) return next_checkin + timedelta(minutes=int(self.config.get("checkin_margin") or 0)) + def get_status_display(self) -> str: + for status_id, display in MonitorStatus.as_choices(): + if status_id in [ + ObjectStatus.ACTIVE, + ObjectStatus.DISABLED, + ObjectStatus.PENDING_DELETION, + ObjectStatus.DELETION_IN_PROGRESS, + ]: + return display + return "active" + @region_silo_only_model class MonitorCheckIn(Model):