def report_success(trial): # pragma: no cover """ Reports a trial success... essentially a noop but useful for mocking in tests """ logger.info(f"Flowserver trial message flow for run {str(trial.run.uuid)} succeeded") analytics.gauge("temba.flowserver_trial.campaign_pass")
def test_gauge(self, mock_get_backends): good = MagicMock() mock_get_backends.return_value = [BadBackend(), good] analytics.gauge("foo_level", 123) good.gauge.assert_called_once_with("foo_level", 123)
def report_success(trial): # pragma: no cover """ Reports a trial success... essentially a noop but useful for mocking in tests """ logger.info(f"Trial resume for run {str(trial.run.uuid)} in flow '{trial.run.flow.name}' succeeded") analytics.gauge("temba.flowserver_trial.resume_pass")
def mage_handle_new_contact(org, contact): """ Contacts created Mage are only saved to the database. Here we take care of the other stuff """ # possible to have dynamic groups based on name contact.handle_update(attrs=('name',)) analytics.gauge('temba.contact_created')
def handle_new_contact(org, contact): """ Contacts created by mage or courier are only saved to the database. Here we take care of the other stuff """ # possible to have dynamic groups based on name contact.handle_update(attrs=("name", ), is_new=True) analytics.gauge("temba.contact_created")
def handle_new_contact(org, contact): """ Contacts created by courier are only saved to the database. Here we take care of the other stuff """ # possible to have dynamic groups based on name contact.handle_update(fields=("name",), is_new=True, urns=[str(u) for u in contact.get_urns()]) analytics.gauge("temba.contact_created")
def handle_new_contact(org, contact): """ Contacts created by courier are only saved to the database. Here we take care of the other stuff """ # possible to have dynamic groups based on name contact.handle_update(fields=("name", ), is_new=True, urns=[str(u) for u in contact.get_urns()]) analytics.gauge("temba.contact_created")
def mage_handle_new_message(org, msg): """ Messages created Mage are only saved to the database. Here we take care of the other stuff """ # Mage no longer assigns topups if not msg.topup_id: msg.topup_id = org.decrement_credit() msg.save(update_fields=('topup_id',)) analytics.gauge('temba.msg_incoming_%s' % msg.channel.channel_type.lower())
def mage_handle_new_message(org, msg): """ Messages created Mage are only saved to the database. Here we take care of the other stuff """ # Mage no longer assigns topups if not msg.topup_id: (msg.topup_id, amount) = org.decrement_credit() msg.save(update_fields=('topup_id',)) # set the preferred channel for this contact msg.contact.set_preferred_channel(msg.channel) analytics.gauge('temba.msg_incoming_%s' % msg.channel.channel_type.lower())
def report_failure(trial): # pragma: no cover """ Reports a trial failure to sentry """ logger.error( "trial message flow in flowserver produced different output", extra={ "org": trial.flow.org.name, "flow": {"uuid": str(trial.flow.uuid), "name": trial.flow.name}, "run_id": trial.run.id, "differences": trial.differences, }, ) analytics.gauge("temba.flowserver_trial.campaign_fail")
def handle_new_message(org, msg): """ Messages created by courier are only saved to the database. Here we take care of the other stuff """ if not msg.topup_id: (msg.topup_id, amount) = org.decrement_credit() msg.save(update_fields=("topup_id", )) # set the preferred channel for this contact msg.contact.set_preferred_channel(msg.channel) # if this contact is stopped, unstop them if msg.contact.is_stopped: msg.contact.unstop(msg.channel.created_by) analytics.gauge("temba.msg_incoming_%s" % msg.channel.channel_type.lower())
def handle_new_message(org, msg): """ Messages created by courier are only saved to the database. Here we take care of the other stuff """ if not msg.topup_id: (msg.topup_id, amount) = org.decrement_credit() msg.save(update_fields=("topup_id",)) # set the preferred channel for this contact msg.contact.set_preferred_channel(msg.channel) # if this contact is stopped, unstop them if msg.contact.is_stopped: msg.contact.unstop(msg.channel.created_by) analytics.gauge("temba.msg_incoming_%s" % msg.channel.channel_type.lower())
def report_failure(trial): # pragma: no cover """ Reports a trial failure to sentry """ logger.error( f"Trial resume (simple={'yes' if trial.is_simple else 'no'}) in flowserver produced different output", extra={ "org": trial.run.org.name, "flow": {"uuid": str(trial.run.flow.uuid), "name": trial.run.flow.name}, "run_id": trial.run.id, "differences": trial.differences, }, ) if trial.is_simple: analytics.gauge("temba.flowserver_trial.resume_simple_fail") else: analytics.gauge("temba.flowserver_trial.resume_fail")
def _maybe_scale(self, req=None): if self.should_run(): self.collect_stats() analytics.gauge('temba.celery_active_workers_%s' % (self.bound_queues,), self.processes) logging_msg = '_maybe_scale => CUR: (%s) CON: (%s,%s), Qty: %s, CPU: %s, Mem: %s, Db: %s' % ( self.processes, self.min_concurrency, self.max_concurrency, self.qty, self.max_cpu_bound_workers, self.max_memory_bound_workers, self.max_db_bound_workers ) LOG.info(logging_msg) self._debug(logging_msg) max_target_procs = min( self.qty, self.max_concurrency, self.max_cpu_bound_workers, self.max_memory_bound_workers, self.max_db_bound_workers ) if max_target_procs > self.processes: n = min((max_target_procs - self.processes), settings.AUTOSCALE_MAX_WORKER_INC_BY) self._debug('SCALE_UP => %s + %s = %s' % (self.processes, n, self.processes + n)) self.scale_up(n) analytics.gauge('temba.celery_worker_scale_up_%s' % (self.bound_queues,), n) return True min_target_procs = max(self.min_concurrency, max_target_procs) if min_target_procs < self.processes: n = min((self.processes - min_target_procs), settings.AUTOSCALE_MAX_WORKER_DEC_BY) self._debug('SCALE_DOWN => %s - %s = %s' % (self.processes, n, self.processes - n)) self.scale_down(n) analytics.gauge('temba.celery_worker_scale_down_%s' % (self.bound_queues,), n) return True
def collect_message_metrics_task(): """ Collects message metrics and sends them to our analytics. """ from .models import INCOMING, OUTGOING, PENDING, QUEUED, ERRORED, INITIALIZING from temba.utils import analytics r = get_redis_connection() # only do this if we aren't already running key = 'collect_message_metrics' if not r.get(key): with r.lock(key, timeout=900): # current # of queued messages (excluding Android) count = Msg.current_messages.filter(direction=OUTGOING, status=QUEUED).exclude(channel=None).\ exclude(topup=None).exclude(channel__channel_type='A').exclude(next_attempt__gte=timezone.now()).count() analytics.gauge('temba.current_outgoing_queued', count) # current # of initializing messages (excluding Android) count = Msg.current_messages.filter(direction=OUTGOING, status=INITIALIZING).exclude(channel=None).exclude(topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_initializing', count) # current # of pending messages (excluding Android) count = Msg.current_messages.filter(direction=OUTGOING, status=PENDING).exclude(channel=None).exclude(topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_pending', count) # current # of errored messages (excluding Android) count = Msg.current_messages.filter(direction=OUTGOING, status=ERRORED).exclude(channel=None).exclude(topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_errored', count) # current # of android outgoing messages waiting to be sent count = Msg.current_messages.filter(direction=OUTGOING, status__in=[PENDING, QUEUED], channel__channel_type='A').exclude(channel=None).exclude(topup=None).count() analytics.gauge('temba.current_outgoing_android', count) # current # of pending incoming messages that haven't yet been handled count = Msg.current_messages.filter(direction=INCOMING, status=PENDING).exclude(channel=None).count() analytics.gauge('temba.current_incoming_pending', count) # stuff into redis when we last run, we do this as a canary as to whether our tasks are falling behind or not running cache.set('last_cron', timezone.now())
def collect_message_metrics_task(): # pragma: needs cover """ Collects message metrics and sends them to our analytics. """ from .models import INCOMING, OUTGOING, PENDING, QUEUED, ERRORED, INITIALIZING from temba.utils import analytics # current # of queued messages (excluding Android) count = ( Msg.objects.filter(direction=OUTGOING, status=QUEUED) .exclude(channel=None) .exclude(topup=None) .exclude(channel__channel_type="A") .exclude(next_attempt__gte=timezone.now()) .count() ) analytics.gauge("temba.current_outgoing_queued", count) # current # of initializing messages (excluding Android) count = ( Msg.objects.filter(direction=OUTGOING, status=INITIALIZING) .exclude(channel=None) .exclude(topup=None) .exclude(channel__channel_type="A") .count() ) analytics.gauge("temba.current_outgoing_initializing", count) # current # of pending messages (excluding Android) count = ( Msg.objects.filter(direction=OUTGOING, status=PENDING) .exclude(channel=None) .exclude(topup=None) .exclude(channel__channel_type="A") .count() ) analytics.gauge("temba.current_outgoing_pending", count) # current # of errored messages (excluding Android) count = ( Msg.objects.filter(direction=OUTGOING, status=ERRORED) .exclude(channel=None) .exclude(topup=None) .exclude(channel__channel_type="A") .count() ) analytics.gauge("temba.current_outgoing_errored", count) # current # of android outgoing messages waiting to be sent count = ( Msg.objects.filter(direction=OUTGOING, status__in=[PENDING, QUEUED], channel__channel_type="A") .exclude(channel=None) .exclude(topup=None) .count() ) analytics.gauge("temba.current_outgoing_android", count) # current # of pending incoming messages that haven't yet been handled count = Msg.objects.filter(direction=INCOMING, status=PENDING).exclude(channel=None).count() analytics.gauge("temba.current_incoming_pending", count) # stuff into redis when we last run, we do this as a canary as to whether our tasks are falling behind or not running cache.set("last_cron", timezone.now())
def collect_message_metrics_task(): # pragma: needs cover """ Collects message metrics and sends them to our analytics. """ from .models import INCOMING, OUTGOING, PENDING, QUEUED, ERRORED, INITIALIZING from temba.utils import analytics # current # of queued messages (excluding Android) count = Msg.objects.filter(direction=OUTGOING, status=QUEUED).exclude(channel=None).\ exclude(topup=None).exclude(channel__channel_type='A').exclude(next_attempt__gte=timezone.now()).count() analytics.gauge('temba.current_outgoing_queued', count) # current # of initializing messages (excluding Android) count = Msg.objects.filter( direction=OUTGOING, status=INITIALIZING).exclude(channel=None).exclude( topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_initializing', count) # current # of pending messages (excluding Android) count = Msg.objects.filter( direction=OUTGOING, status=PENDING).exclude(channel=None).exclude( topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_pending', count) # current # of errored messages (excluding Android) count = Msg.objects.filter( direction=OUTGOING, status=ERRORED).exclude(channel=None).exclude( topup=None).exclude(channel__channel_type='A').count() analytics.gauge('temba.current_outgoing_errored', count) # current # of android outgoing messages waiting to be sent count = Msg.objects.filter(direction=OUTGOING, status__in=[PENDING, QUEUED], channel__channel_type='A').exclude( channel=None).exclude(topup=None).count() analytics.gauge('temba.current_outgoing_android', count) # current # of pending incoming messages that haven't yet been handled count = Msg.objects.filter(direction=INCOMING, status=PENDING).exclude(channel=None).count() analytics.gauge('temba.current_incoming_pending', count) # stuff into redis when we last run, we do this as a canary as to whether our tasks are falling behind or not running cache.set('last_cron', timezone.now())
def collect_message_metrics_task(): # pragma: needs cover """ Collects message metrics and sends them to our analytics. """ # current # of queued messages (excluding Android) count = (Msg.objects.filter( direction=Msg.DIRECTION_OUT, status=Msg.STATUS_QUEUED).exclude( channel=None).exclude(channel__channel_type="A").exclude( next_attempt__gte=timezone.now()).count()) analytics.gauge("temba.current_outgoing_queued", count) # current # of initializing messages (excluding Android) count = (Msg.objects.filter( direction=Msg.DIRECTION_OUT, status=Msg.STATUS_INITIALIZING).exclude( channel=None).exclude(channel__channel_type="A").count()) analytics.gauge("temba.current_outgoing_initializing", count) # current # of pending messages (excluding Android) count = (Msg.objects.filter( direction=Msg.DIRECTION_OUT, status=Msg.STATUS_PENDING).exclude( channel=None).exclude(channel__channel_type="A").count()) analytics.gauge("temba.current_outgoing_pending", count) # current # of errored messages (excluding Android) count = (Msg.objects.filter( direction=Msg.DIRECTION_OUT, status=Msg.STATUS_ERRORED).exclude( channel=None).exclude(channel__channel_type="A").count()) analytics.gauge("temba.current_outgoing_errored", count) # current # of android outgoing messages waiting to be sent count = (Msg.objects.filter( direction=Msg.DIRECTION_OUT, status__in=[Msg.STATUS_PENDING, Msg.STATUS_QUEUED], channel__channel_type="A").exclude(channel=None).count()) analytics.gauge("temba.current_outgoing_android", count) # current # of pending incoming messages older than a minute that haven't yet been handled minute_ago = timezone.now() - timedelta(minutes=1) count = (Msg.objects.filter( direction=Msg.DIRECTION_IN, status=Msg.STATUS_PENDING, created_on__lte=minute_ago).exclude(channel=None).count()) analytics.gauge("temba.current_incoming_pending", count) # stuff into redis when we last run, we do this as a canary as to whether our tasks are falling behind or not running cache.set("last_cron", timezone.now())