def notify_digest(self, project, digest): start, end, counts = get_digest_metadata(digest) # If there is only one group in this digest (regardless of how many # rules it appears in), we should just render this using the single # notification template. If there is more than one record for a group, # just choose the most recent one. if len(counts) == 1: group = counts.keys()[0] record = max( itertools.chain.from_iterable( groups.get(group, []) for groups in digest.itervalues(), ), key=lambda record: record.timestamp, ) notification = Notification(record.value.event, rules=record.value.rules) return self.notify(notification) context = { 'start': start, 'end': end, 'project': project, 'digest': digest, 'counts': counts, } self._send_mail( subject=render_to_string('sentry/emails/digests/subject.txt', context).rstrip(), template='sentry/emails/digests/body.txt', html_template='sentry/emails/digests/body.html', project=project, context=context, )
def notify_digest(self, project, digest): user_ids = self.get_send_to(project) for user_id, digest in get_personalized_digests(project.id, digest, user_ids): start, end, counts = get_digest_metadata(digest) # If there is only one group in this digest (regardless of how many # rules it appears in), we should just render this using the single # notification template. If there is more than one record for a group, # just choose the most recent one. if len(counts) == 1: group = six.next(iter(counts)) record = max( itertools.chain.from_iterable( groups.get(group, []) for groups in six.itervalues(digest) ), key=lambda record: record.timestamp, ) notification = Notification(record.value.event, rules=record.value.rules) return self.notify(notification) context = { 'start': start, 'end': end, 'project': project, 'digest': digest, 'counts': counts, } headers = { 'X-Sentry-Project': project.slug, } group = six.next(iter(counts)) subject = self.get_digest_subject(group, counts, start) self.add_unsubscribe_link(context, user_id, project) self._send_mail( subject=subject, template='sentry/emails/digests/body.txt', html_template='sentry/emails/digests/body.html', project=project, reference=project, headers=headers, type='notify.digest', context=context, send_to=[user_id], )
def notify_digest(self, project, digest): start, end, counts = get_digest_metadata(digest) # If there is only one group in this digest (regardless of how many # rules it appears in), we should just render this using the single # notification template. If there is more than one record for a group, # just choose the most recent one. if len(counts) == 1: group = counts.keys()[0] record = max( itertools.chain.from_iterable( groups.get(group, []) for groups in digest.itervalues(), ), key=lambda record: record.timestamp, ) notification = Notification(record.value.event, rules=record.value.rules) return self.notify(notification) context = { 'start': start, 'end': end, 'project': project, 'digest': digest, 'counts': counts, } # TODO: Everything below should instead use `_send_mail` for consistency. subject_prefix = project.get_option('subject_prefix', settings.EMAIL_SUBJECT_PREFIX) if subject_prefix: subject_prefix = subject_prefix.rstrip() + ' ' message = self._build_message( subject=subject_prefix + render_to_string('sentry/emails/digests/subject.txt', context).rstrip(), template='sentry/emails/digests/body.txt', html_template='sentry/emails/digests/body.html', project=project, context=context, ) if message is not None: message.send()
def digest(request): seed = request.GET.get('seed', str(time.time())) logger.debug('Using random seed value: %s') random = Random(seed) now = datetime.utcnow().replace(tzinfo=pytz.utc) # TODO: Refactor all of these into something more manageable. org = Organization( id=1, slug='example', name='Example Organization', ) team = Team( id=1, slug='example', name='Example Team', organization=org, ) project = Project( id=1, slug='example', name='Example Project', team=team, organization=org, ) rules = {i: Rule( id=i, project=project, label="Rule #%s" % (i,), ) for i in xrange(1, random.randint(2, 4))} state = { 'project': project, 'groups': {}, 'rules': rules, 'event_counts': {}, 'user_counts': {}, } records = [] group_sequence = itertools.count(1) event_sequence = itertools.count(1) for i in xrange(random.randint(1, 30)): group_id = next(group_sequence) culprit = '{module} in {function}'.format( module='.'.join( ''.join(random.sample(WORDS, random.randint(1, int(random.paretovariate(2.2))))) for word in xrange(1, 4) ), function=random.choice(WORDS) ) group = state['groups'][group_id] = Group( id=group_id, project=project, message=words(int(random.weibullvariate(8, 4)), common=False), culprit=culprit, level=random.choice(LOG_LEVELS.keys()), ) offset = timedelta(seconds=0) for i in xrange(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) event = Event( id=next(event_sequence), event_id=uuid.uuid4().hex, project=project, group=group, message=group.message, data=load_data('python'), datetime=now - offset, ) records.append( Record( event.event_id, Notification( event, random.sample(state['rules'], random.randint(1, len(state['rules']))), ), to_timestamp(event.datetime), ) ) state['event_counts'][group_id] = random.randint(10, 1e4) state['user_counts'][group_id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) return MailPreview( html_template='sentry/emails/digests/body.html', text_template='sentry/emails/digests/body.txt', context={ 'project': project, 'counts': counts, 'digest': digest, 'start': start, 'end': end, }, ).render()
def digest(request): random = get_random(request) # TODO: Refactor all of these into something more manageable. org = Organization( id=1, slug='example', name='Example Organization', ) team = Team( id=1, slug='example', name='Example Team', organization=org, ) project = Project( id=1, slug='example', name='Example Project', team=team, organization=org, ) rules = {i: Rule( id=i, project=project, label="Rule #%s" % (i,), ) for i in range(1, random.randint(2, 4))} state = { 'project': project, 'groups': {}, 'rules': rules, 'event_counts': {}, 'user_counts': {}, } records = [] event_sequence = itertools.count(1) group_generator = make_group_generator(random, project) for i in range(random.randint(1, 30)): group = next(group_generator) state['groups'][group.id] = group offset = timedelta(seconds=0) for i in range(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) event = Event( id=next(event_sequence), event_id=uuid.uuid4().hex, project=project, group=group, message=group.message, data=load_data('python'), datetime=to_datetime( random.randint( to_timestamp(group.first_seen), to_timestamp(group.last_seen), ), ) ) records.append( Record( event.event_id, Notification( event, random.sample(state['rules'], random.randint(1, len(state['rules']))), ), to_timestamp(event.datetime), ) ) state['event_counts'][group.id] = random.randint(10, 1e4) state['user_counts'][group.id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) context = { 'project': project, 'counts': counts, 'digest': digest, 'start': start, 'end': end, } add_unsubscribe_link(context) return MailPreview( html_template='sentry/emails/digests/body.html', text_template='sentry/emails/digests/body.txt', context=context, ).render(request)
def digest(request): seed = request.GET.get("seed", str(time.time())) logger.debug("Using random seed value: %s") random = Random(seed) now = datetime.utcnow().replace(tzinfo=pytz.utc) # TODO: Refactor all of these into something more manageable. org = Organization(id=1, slug="example", name="Example Organization") team = Team(id=1, slug="example", name="Example Team", organization=org) project = Project(id=1, slug="example", name="Example Project", team=team, organization=org) rules = {i: Rule(id=i, project=project, label="Rule #%s" % (i,)) for i in xrange(1, random.randint(2, 4))} state = {"project": project, "groups": {}, "rules": rules, "event_counts": {}, "user_counts": {}} records = [] group_sequence = itertools.count(1) event_sequence = itertools.count(1) for i in xrange(random.randint(1, 30)): group_id = next(group_sequence) culprit = "{module} in {function}".format( module=".".join( "".join(random.sample(WORDS, random.randint(1, int(random.paretovariate(2.2))))) for word in xrange(1, 4) ), function=random.choice(WORDS), ) group = state["groups"][group_id] = Group( id=group_id, project=project, message=words(int(random.weibullvariate(8, 4)), common=False), culprit=culprit, level=random.choice(LOG_LEVELS.keys()), ) offset = timedelta(seconds=0) for i in xrange(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) event = Event( id=next(event_sequence), event_id=uuid.uuid4().hex, project=project, group=group, message=group.message, data=load_data("python"), datetime=now - offset, ) records.append( Record( event.event_id, Notification(event, random.sample(state["rules"], random.randint(1, len(state["rules"])))), to_timestamp(event.datetime), ) ) state["event_counts"][group_id] = random.randint(10, 1e4) state["user_counts"][group_id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) return MailPreview( html_template="sentry/emails/digests/body.html", text_template="sentry/emails/digests/body.txt", context={"project": project, "counts": counts, "digest": digest, "start": start, "end": end}, ).render()
def digest(request): random = get_random(request) # TODO: Refactor all of these into something more manageable. org = Organization( id=1, slug='example', name='Example Organization', ) project = Project( id=1, slug='example', name='Example Project', organization=org, ) rules = { i: Rule( id=i, project=project, label="Rule #%s" % (i, ), ) for i in range(1, random.randint(2, 4)) } state = { 'project': project, 'groups': {}, 'rules': rules, 'event_counts': {}, 'user_counts': {}, } records = [] event_sequence = itertools.count(1) group_generator = make_group_generator(random, project) for i in range(random.randint(1, 30)): group = next(group_generator) state['groups'][group.id] = group offset = timedelta(seconds=0) for i in range(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) event = Event(id=next(event_sequence), event_id=uuid.uuid4().hex, project=project, group=group, message=group.message, data=load_data('python'), datetime=to_datetime( random.randint( to_timestamp(group.first_seen), to_timestamp(group.last_seen), ), )) records.append( Record( event.event_id, Notification( event, random.sample(state['rules'], random.randint(1, len(state['rules']))), ), to_timestamp(event.datetime), )) state['event_counts'][group.id] = random.randint(10, 1e4) state['user_counts'][group.id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) context = { 'project': project, 'counts': counts, 'digest': digest, 'start': start, 'end': end, 'referrer': 'digest_email', } add_unsubscribe_link(context) return MailPreview( html_template='sentry/emails/digests/body.html', text_template='sentry/emails/digests/body.txt', context=context, ).render(request)
def digest(request): random = get_random(request) # TODO: Refactor all of these into something more manageable. org = Organization(id=1, slug="example", name="Example Organization") project = Project(id=1, slug="example", name="Example Project", organization=org) rules = { i: Rule(id=i, project=project, label=f"Rule #{i}") for i in range(1, random.randint(2, 4)) } state = { "project": project, "groups": {}, "rules": rules, "event_counts": {}, "user_counts": {}, } records = [] group_generator = make_group_generator(random, project) for i in range(random.randint(1, 30)): group = next(group_generator) state["groups"][group.id] = group offset = timedelta(seconds=0) for i in range(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) data = dict(load_data("python")) data["message"] = group.message data.pop("logentry", None) event_manager = EventManager(data) event_manager.normalize() data = event_manager.get_data() data["timestamp"] = random.randint(to_timestamp(group.first_seen), to_timestamp(group.last_seen)) event = eventstore.create_event(event_id=uuid.uuid4().hex, group_id=group.id, project_id=project.id, data=data.data) records.append( Record( event.event_id, Notification( event, random.sample(list(state["rules"].keys()), random.randint(1, len(state["rules"]))), ), to_timestamp(event.datetime), )) state["event_counts"][group.id] = random.randint(10, 1e4) state["user_counts"][group.id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) context = { "project": project, "counts": counts, "digest": digest, "start": start, "end": end, "referrer": "digest_email", } add_unsubscribe_link(context) return MailPreview( html_template="sentry/emails/digests/body.html", text_template="sentry/emails/digests/body.txt", context=context, ).render(request)
def notify_digest(self, project, digest, target_type, target_identifier=None): metrics.incr("mail_adapter.notify_digest") user_ids = self.get_send_to(project, target_type, target_identifier) logger.info( "mail.adapter.notify_digest", extra={ "project_id": project.id, "target_type": target_type.value, "target_identifier": target_identifier, "user_ids": user_ids, }, ) for user_id, digest in get_personalized_digests( target_type, project.id, digest, user_ids): start, end, counts = get_digest_metadata(digest) # If there is only one group in this digest (regardless of how many # rules it appears in), we should just render this using the single # notification template. If there is more than one record for a group, # just choose the most recent one. if len(counts) == 1: group = next(iter(counts)) record = max( itertools.chain.from_iterable( groups.get(group, []) for groups in digest.values()), key=lambda record: record.timestamp, ) notification = Notification(record.value.event, rules=record.value.rules) return self.notify(notification, target_type, target_identifier) context = { "start": start, "end": end, "project": project, "digest": digest, "counts": counts, } headers = { "X-Sentry-Project": project.slug, "X-SMTPAPI": json.dumps({"category": "digest_email"}), } group = next(iter(counts)) subject = self.get_digest_subject(group, counts, start) self.add_unsubscribe_link(context, user_id, project, "alert_digest") self._send_mail( subject=subject, template="sentry/emails/digests/body.txt", html_template="sentry/emails/digests/body.html", project=project, reference=project, headers=headers, type="notify.digest", context=context, send_to=[user_id], )
def digest(request): seed = request.GET.get('seed', str(time.time())) logger.debug('Using random seed value: %s') random = Random(seed) now = datetime.utcnow().replace(tzinfo=pytz.utc) # TODO: Refactor all of these into something more manageable. org = Organization( id=1, slug='example', name='Example Organization', ) team = Team( id=1, slug='example', name='Example Team', organization=org, ) project = Project( id=1, slug='example', name='Example Project', team=team, organization=org, ) rules = { i: Rule( id=i, project=project, label="Rule #%s" % (i, ), ) for i in xrange(1, random.randint(2, 4)) } state = { 'project': project, 'groups': {}, 'rules': rules, 'event_counts': {}, 'user_counts': {}, } records = [] group_sequence = itertools.count(1) event_sequence = itertools.count(1) for i in xrange(random.randint(1, 30)): group_id = next(group_sequence) culprit = '{module} in {function}'.format( module='.'.join(''.join( random.sample( WORDS, random.randint(1, int(random.paretovariate(2.2))))) for word in xrange(1, 4)), function=random.choice(WORDS)) group = state['groups'][group_id] = Group( id=group_id, project=project, message=words(int(random.weibullvariate(8, 4)), common=False), culprit=culprit, level=random.choice(LOG_LEVELS.keys()), ) offset = timedelta(seconds=0) for i in xrange(random.randint(1, 10)): offset += timedelta(seconds=random.random() * 120) event = Event( id=next(event_sequence), event_id=uuid.uuid4().hex, project=project, group=group, message=group.message, data=load_data('python'), datetime=now - offset, ) records.append( Record( event.event_id, Notification( event, random.sample(state['rules'], random.randint(1, len(state['rules']))), ), to_timestamp(event.datetime), )) state['event_counts'][group_id] = random.randint(10, 1e4) state['user_counts'][group_id] = random.randint(10, 1e4) digest = build_digest(project, records, state) start, end, counts = get_digest_metadata(digest) return MailPreview( html_template='sentry/emails/digests/body.html', text_template='sentry/emails/digests/body.txt', context={ 'project': project, 'counts': counts, 'digest': digest, 'start': start, 'end': end, }, ).render()