def get_score_clause(cls): engine = get_db_engine() if engine.startswith('postgresql'): return 'log(times_seen) * 600 + last_seen::abstime::int' if engine.startswith('mysql'): return 'log(times_seen) * 600 + unix_timestamp(last_seen)' return 'times_seen'
def get_score_clause(cls): engine = get_db_engine() if engine.startswith('postgresql'): return 'times_seen / (pow((floor(extract(epoch from now() - last_seen) / 3600) + 2), 1.25) + 1)' if engine.startswith('mysql'): return 'times_seen / (pow((floor((unix_timestamp(now()) - unix_timestamp(last_seen)) / 3600) + 2), 1.25) + 1)' return 'times_seen'
def group(request, group_id): group = get_object_or_404(GroupedMessage, pk=group_id) message_list = group.message_set.all() obj = message_list.order_by('-id')[0] if '__sentry__' in obj.data: module, args, frames = obj.data['__sentry__']['exc'] obj.class_name = str(obj.class_name) # We fake the exception class due to many issues with imports/builtins/etc exc_type = type(obj.class_name, (Exception,), {}) exc_value = exc_type(obj.message) exc_value.args = args reporter = ImprovedExceptionReporter(obj.request, exc_type, exc_value, frames, obj.data['__sentry__'].get('template')) traceback = mark_safe(reporter.get_traceback_html()) elif group.traceback: traceback = mark_safe('<pre>%s</pre>' % (group.traceback,)) unique_urls = message_list.filter(url__isnull=False).values_list('url', 'logger', 'view', 'checksum').annotate(times_seen=Count('url')).values('url', 'times_seen').order_by('-times_seen') unique_servers = message_list.filter(server_name__isnull=False).values_list('server_name', 'logger', 'view', 'checksum').annotate(times_seen=Count('server_name')).values('server_name', 'times_seen').order_by('-times_seen') def iter_data(obj): for k, v in obj.data.iteritems(): if k.startswith('_') or k in ['url']: continue yield k, v json_data = iter_data(obj) # TODO: this should be a template tag engine = get_db_engine() if SimpleLineChart and not engine.startswith('sqlite'): today = datetime.datetime.now() chart_qs = message_list\ .filter(datetime__gte=today - datetime.timedelta(hours=24))\ .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\ .annotate(num=Count('id')).values_list('hour', 'num') rows = dict(chart_qs) if rows: max_y = max(rows.values()) else: max_y = 1 chart = SimpleLineChart(300, 80, y_range=[0, max_y]) chart.add_data([max_y]*30) chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1]) chart.add_data([0]*30) chart.fill_solid(chart.BACKGROUND, 'eeeeee') chart.add_fill_range('eeeeee', 0, 1) chart.add_fill_range('e0ebff', 1, 2) chart.set_colours(['eeeeee', '999999', 'eeeeee']) chart.set_line_style(1, 1) chart_url = chart.get_url() return render_to_response('sentry/group/details.html', locals())
def test_get_db_engine(self): from sentry.helpers import get_db_engine _databases = getattr(settings, 'DATABASES', {}).copy() _engine = settings.DATABASE_ENGINE settings.DATABASE_ENGINE = '' settings.DATABASES['default'] = {'ENGINE': 'blah.sqlite3'} self.assertEquals(get_db_engine(), 'sqlite3') settings.DATABASE_ENGINE = 'mysql' self.assertEquals(get_db_engine(), 'sqlite3') settings.DATABASES['default'] = {'ENGINE': 'blah.mysql'} self.assertEquals(get_db_engine(), 'mysql') settings.DATABASES = _databases settings.DATABASE_ENGINE = _engine
def evaluate(self, node, qn, connection): engine = get_db_engine(getattr(connection, 'alias', 'default')) if engine.startswith('postgresql'): sql = 'log(times_seen) * 600 + last_seen::abstime::int' elif engine.startswith('mysql'): sql = 'log(times_seen) * 600 + unix_timestamp(last_seen)' else: # XXX: if we cant do it atomicly let's do it the best we can sql = self.group.get_score() return (sql, [])
def create_sort_index(cls, sender, db, created_models, **kwargs): # This is only supported in postgres engine = get_db_engine() if not engine.startswith('postgresql'): return if cls not in created_models: return from django.db import connections cursor = connections[db].cursor() cursor.execute("create index sentry_groupedmessage_score on sentry_groupedmessage ((%s))" % (cls.get_score_clause(),)) cursor.close()
def create_sort_index(cls, sender, db, created_models, **kwargs): # This is only supported in postgres engine = get_db_engine() if not engine.startswith('postgresql'): return if cls not in created_models: return from django.db import connections try: cursor = connections[db].cursor() cursor.execute("create index sentry_groupedmessage_score on sentry_groupedmessage ((%s))" % (cls.get_score_clause(),)) cursor.close() except: transaction.rollback_unless_managed()
def chart_data(group, max_days=90): hours = max_days * 24 today = datetime.datetime.now().replace(microsecond=0, second=0, minute=0) min_date = today - datetime.timedelta(hours=hours) if hasattr(group, '_state'): from django.db import connections conn = connections[group._state.db] else: from django.db import connection as conn if get_db_engine(getattr(conn, 'alias', 'default')).startswith('oracle'): method = conn.ops.date_trunc_sql('hh24', 'datetime') else: method = conn.ops.date_trunc_sql('hour', 'datetime') chart_qs = list(group.message_set.all()\ .filter(datetime__gte=min_date)\ .extra(select={'grouper': method}).values('grouper')\ .annotate(num=Count('id')).values_list('grouper', 'num')\ .order_by('grouper')) if not chart_qs: return {} rows = dict(chart_qs) #just skip zeroes first_seen = hours while not rows.get(today - datetime.timedelta( hours=first_seen)) and first_seen > 24: first_seen -= 1 return { 'points': [ rows.get(today - datetime.timedelta(hours=d), 0) for d in xrange(first_seen, -1, -1) ], 'categories': [ str(today - datetime.timedelta(hours=d)) for d in xrange(first_seen, -1, -1) ], }
def group_message_list(request, group_id): group = get_object_or_404(GroupedMessage, pk=group_id) message_list = group.message_set.all().order_by('-datetime') unique_urls = message_list.filter(url__isnull=False).values_list('url', 'logger', 'view', 'checksum').annotate(times_seen=Count('url')).values('url', 'times_seen').order_by('-times_seen') unique_servers = message_list.filter(server_name__isnull=False).values_list('server_name', 'logger', 'view', 'checksum').annotate(times_seen=Count('server_name')).values('server_name', 'times_seen').order_by('-times_seen') engine = get_db_engine() if SimpleLineChart and not engine.startswith('sqlite'): today = datetime.datetime.now() chart_qs = message_list\ .filter(datetime__gte=today - datetime.timedelta(hours=24))\ .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\ .annotate(num=Count('id')).values_list('hour', 'num') rows = dict(chart_qs) if rows: max_y = max(rows.values()) else: max_y = 1 chart = SimpleLineChart(300, 80, y_range=[0, max_y]) chart.add_data([max_y]*30) chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1]) chart.add_data([0]*30) chart.fill_solid(chart.BACKGROUND, 'eeeeee') chart.add_fill_range('eeeeee', 0, 1) chart.add_fill_range('e0ebff', 1, 2) chart.set_colours(['eeeeee', '999999', 'eeeeee']) chart.set_line_style(1, 1) chart_url = chart.get_url() page = 'messages' return render_to_response('sentry/group/message_list.html', locals())
def chart_data(group, max_days=90): hours = max_days*24 today = datetime.datetime.now().replace(microsecond=0, second=0, minute=0) min_date = today - datetime.timedelta(hours=hours) if hasattr(group, '_state'): from django.db import connections conn = connections[group._state.db] else: from django.db import connection as conn if get_db_engine(getattr(conn, 'alias', 'default')).startswith('oracle'): method = conn.ops.date_trunc_sql('hh24', 'datetime') else: method = conn.ops.date_trunc_sql('hour', 'datetime') chart_qs = list(group.message_set.all()\ .filter(datetime__gte=min_date)\ .extra(select={'grouper': method}).values('grouper')\ .annotate(num=Count('id')).values_list('grouper', 'num')\ .order_by('grouper')) if not chart_qs: return {} rows = dict(chart_qs) #just skip zeroes first_seen = hours while not rows.get(today - datetime.timedelta(hours=first_seen)) and first_seen > 24: first_seen -= 1 return { 'points': [rows.get(today-datetime.timedelta(hours=d), 0) for d in xrange(first_seen, -1, -1)], 'categories': [str(today-datetime.timedelta(hours=d)) for d in xrange(first_seen, -1, -1)], }
def can_chart(group): engine = get_db_engine() return SimpleLineChart and not engine.startswith('sqlite')