66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
import datetime
|
|
import random
|
|
|
|
from django.db import models
|
|
from django.contrib.postgres.fields import JSONField
|
|
from django.contrib.postgres.fields.jsonb import KeyTextTransform
|
|
from django.core.cache import cache
|
|
from django.utils import timezone
|
|
|
|
|
|
class EntryManager(models.Manager):
|
|
|
|
def extract(self, since=None, host=None, lines=None, **kwargs):
|
|
qs = Entry.objects.all()
|
|
if since:
|
|
timestamp = timezone.make_aware(datetime.datetime.strptime(since, "%Y-%m-%d %H:%M:%S"))
|
|
qs = qs.filter(timestamp__gt=timestamp)
|
|
if host:
|
|
qs = qs.filter(host__in=host)
|
|
qs = qs.filter(**self.parse_options(**kwargs))
|
|
if lines:
|
|
qs = qs.order_by('-timestamp')
|
|
qs = qs[:int(lines)][::-1]
|
|
else:
|
|
qs = qs.order_by('timestamp')
|
|
return qs
|
|
|
|
def parse_options(self, **kwargs):
|
|
# todo mode='contains' require jsonb KeyTextTransform and probably annotations
|
|
options = {}
|
|
for k, v in kwargs.items():
|
|
if not v or v == ['']:
|
|
continue
|
|
if k == 'priority':
|
|
v = [str(n) for n in range(0, int(v))]
|
|
options['data__' + k.upper() + '__in'] = v
|
|
return options
|
|
|
|
def hosts(self):
|
|
value = cache.get('hosts')
|
|
if value is None:
|
|
value = sorted(self.model.objects.all().values_list('host', flat=True).distinct(), key=lambda x: x.lower())
|
|
cache.set('hosts', value, 600 * random.random())
|
|
return value
|
|
|
|
def units(self):
|
|
value = cache.get('units')
|
|
if value is None:
|
|
value = sorted([v for v in self.model.objects.all().annotate(unit=KeyTextTransform('_SYSTEMD_UNIT', 'data')).values_list('unit', flat=True).distinct() if v], key=lambda x: x.lower())
|
|
cache.set('units', value, 600 * random.random())
|
|
return value
|
|
|
|
|
|
class Entry(models.Model):
|
|
timestamp = models.DateTimeField(db_index=True)
|
|
host = models.CharField(max_length=128, db_index=True)
|
|
data = JSONField()
|
|
objects = EntryManager()
|
|
|
|
def __str__(self):
|
|
return '%s %s %s' % (self.timestamp, self.host, self.data)
|
|
|
|
@property
|
|
def unit(self):
|
|
return self.data.get('_SYSTEMD_UNIT', '').replace('.service', '')
|