forked from getsentry/sentry
/
cleanup.py
100 lines (86 loc) · 3.93 KB
/
cleanup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
sentry.queue.tasks.cleanup
~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2010 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
def cleanup(days=30, logger=None, site=None, server=None, level=None,
project=None):
"""
Deletes a portion of the trailing data in Sentry based on
their creation dates. For example, if ``days`` is 30, this
would attempt to clean up all data thats older than 30 days.
:param logger: limit all deletion scopes to messages from the
specified logger.
:param site: limit the message deletion scope to the specified
site.
:param server: limit the message deletion scope to the specified
server.
:param level: limit all deleteion scopes to messages that are greater
than or equal to level.
"""
import datetime
from sentry.models import Group, Event, MessageCountByMinute, \
MessageFilterValue, FilterValue
from sentry.utils.query import RangeQuerySetWrapper, SkinnyQuerySet
# TODO: we should collect which messages above were deleted
# and potentially just send out post_delete signals where
# GroupedMessage can update itself accordingly
ts = datetime.datetime.utcnow() - datetime.timedelta(days=days)
# Message
qs = SkinnyQuerySet(Event).filter(datetime__lte=ts)
if logger:
qs = qs.filter(logger=logger)
if site:
qs = qs.filter(site=site)
if server:
qs = qs.filter(server_name=server)
if level:
qs = qs.filter(level__gte=level)
if project:
qs = qs.filter(project=project)
groups_to_check = set()
for obj in RangeQuerySetWrapper(qs):
print ">>> Removing <%s: id=%s>" % (obj.__class__.__name__, obj.pk)
obj.delete()
groups_to_check.add(obj.group_id)
if not (server or site):
# MessageCountByMinute
qs = SkinnyQuerySet(MessageCountByMinute).filter(date__lte=ts)
if logger:
qs = qs.filter(group__logger=logger)
if level:
qs = qs.filter(group__level__gte=level)
if project:
qs = qs.filter(project=project)
for obj in RangeQuerySetWrapper(qs):
print ">>> Removing <%s: id=%s>" % (obj.__class__.__name__, obj.pk)
obj.delete()
# GroupedMessage
qs = SkinnyQuerySet(Group).filter(last_seen__lte=ts)
if logger:
qs = qs.filter(logger=logger)
if level:
qs = qs.filter(level__gte=level)
if project:
qs = qs.filter(project=project)
for obj in RangeQuerySetWrapper(qs):
for key, value in SkinnyQuerySet(MessageFilterValue).filter(group=obj).values_list('key', 'value'):
if not MessageFilterValue.objects.filter(key=key, value=value).exclude(group=obj).exists():
print ">>> Removing <FilterValue: key=%s, value=%s>" % (key, value)
FilterValue.objects.filter(key=key, value=value).delete()
print ">>> Removing <%s: id=%s>" % (obj.__class__.__name__, obj.pk)
obj.delete()
# attempt to cleanup any groups that may now be empty
groups_to_delete = []
for group_id in groups_to_check:
if not Event.objects.filter(group=group_id).exists():
groups_to_delete.append(group_id)
if groups_to_delete:
for obj in SkinnyQuerySet(Group).filter(pk__in=groups_to_delete):
for key, value in SkinnyQuerySet(MessageFilterValue).filter(group=obj).values_list('key', 'value'):
if not MessageFilterValue.objects.filter(key=key, value=value).exclude(group=obj).exists():
print ">>> Removing <FilterValue: key=%s, value=%s>" % (key, value)
FilterValue.objects.filter(key=key, value=value).delete()
print ">>> Removing <%s: id=%s>" % (obj.__class__.__name__, obj.pk)
obj.delete()