def add_notification_channels(self, notification_channels): """ Add notification channels to this alert. Parameters ---------- notification_channels : list of :class:`~verta.monitoring.notification_channel.entities.NotificationChannel` Notification channels. Examples -------- .. code-block:: python from verta.monitoring.notification_channel import SlackNotificationChannel channels = Client().monitoring.notification_channels channel = notification_channels.create( "Slack alerts", SlackNotificationChannel("https://hooks.slack.com/services/.../.../......"), ) alert.add_notification_channels([channel]) """ for channel in notification_channels: self._validate_notification_channel(channel) alert_msg = _AlertService.Alert() self._fetch_with_no_cache() alert_msg.CopyFrom(self._msg) alert_msg.notification_channels.update( {channel.id: True for channel in notification_channels}) self._update(alert_msg)
def _create_proto_internal( cls, conn, ctx, name, monitored_entity_id, alerter, summary_sample_query, notification_channels, created_at_millis, updated_at_millis, last_evaluated_at_millis, # TODO: should we allow `status` and `violating samples` on create? ): msg = _AlertService.CreateAlertRequest(alert=_AlertService.Alert( name=name, monitored_entity_id=monitored_entity_id, created_at_millis=created_at_millis, updated_at_millis=updated_at_millis, last_evaluated_at_millis=last_evaluated_at_millis, notification_channels={ channel.id: True for channel in notification_channels }, sample_find_base=summary_sample_query._to_proto_request(), alerter_type=alerter._TYPE, ), ) field = getattr(msg.alert, alerter._get_alert_field()) field.CopyFrom(alerter._as_proto()) endpoint = "/api/v1/alerts/createAlert" response = conn.make_proto_request("POST", endpoint, body=msg) alert_msg = conn.must_proto_response(response, _AlertService.Alert) return alert_msg
def _update_last_evaluated_at(self, last_evaluated_at=None): if last_evaluated_at is None: last_evaluated_at = time_utils.now() millis = time_utils.epoch_millis(last_evaluated_at) alert_msg = _AlertService.Alert(last_evaluated_at_millis=millis, ) self._update(alert_msg)
def test_sample_find_base_preserves_aggregation_flags(self, summary): """alert.summary_sample_query fully represents sample_find_base. The client used to drop `store_aggregate` and `allow_aggregate_samples` because of how :class:`SummarySampleQuery` was written. """ # define sample_find_base sample_find_base = _SummaryService.FindSummarySampleRequest( filter=_SummaryService.FilterQuerySummarySample( find_summaries=summary.alerts._build_summary_query( )._to_proto_request(), ), page_number=1, page_limit=-1, # following two fields are not exposed through client store_aggregate=True, allow_aggregate_samples=True, ) # create alert directly via REST API alerter = FixedAlerter(comparison.GreaterThan(0.7)) msg = _AlertService.CreateAlertRequest(alert=_AlertService.Alert( name=_utils.generate_default_name(), monitored_entity_id=summary._monitored_entity_id, sample_find_base=sample_find_base, alerter_type=alerter._TYPE, alerter_fixed=alerter._as_proto(), ), ) endpoint = "/api/v1/alerts/createAlert" response = summary.alerts._conn.make_proto_request("POST", endpoint, body=msg) alert_id = summary.alerts._conn.must_proto_response( response, _AlertService.Alert, ).id # retrieve alert via client and verify that fields are preserved alert = summary.alerts.get(id=alert_id) retrieved_sample_find_base = alert.summary_sample_query._to_proto_request( ) assert retrieved_sample_find_base.store_aggregate assert retrieved_sample_find_base.allow_aggregate_samples # verify full equality, minus time field added by alert retrieved_sample_find_base.filter.ClearField("created_at_after_millis") assert retrieved_sample_find_base == sample_find_base