misc: add filtering
This commit is contained in:
parent
8736c1753c
commit
8e4088be2a
|
@ -16,10 +16,12 @@ class Command(BaseCommand):
|
|||
def add_arguments(self, parser):
|
||||
parser.add_argument("--full", action="store_true")
|
||||
parser.add_argument("-n", "--lines", default=100)
|
||||
parser.add_argument('options', nargs="*")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
_, columns = os.popen("stty size", "r").read().split()
|
||||
for entry in Entry.objects.dump(lines=options['lines']):
|
||||
kwargs = {k: v for (k, v) in [o.split('=') for o in options['options']]}
|
||||
for entry in Entry.objects.dump(lines=options['lines'], **kwargs):
|
||||
line = "%s %s %s %s" % (
|
||||
entry.timestamp.astimezone().strftime("%b %d %X"),
|
||||
entry.host,
|
||||
|
|
|
@ -1,22 +1,35 @@
|
|||
from django.db import models
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from django.contrib.postgres.fields.jsonb import KeyTextTransform
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
class EntryManager(models.Manager):
|
||||
def dump(self, host=None, message=None, lines=100):
|
||||
if message:
|
||||
qs = Entry.objects.annotate(message=KeyTextTransform('MESSAGE', 'data'))
|
||||
else:
|
||||
qs = Entry.objects.all()
|
||||
|
||||
def dump(self, timestamp=None, host=None, lines=100, **kwargs):
|
||||
qs = Entry.objects.all()
|
||||
if host:
|
||||
qs = qs.filter(host=host)
|
||||
if message:
|
||||
qs = qs.filter(message__contains=message)
|
||||
qs = qs.filter(**self.parse_options(**kwargs))
|
||||
if lines:
|
||||
qs = qs.order_by('-timestamp')[:int(lines)][::-1]
|
||||
return qs
|
||||
|
||||
def parse_options(self, mode='exact', **kwargs):
|
||||
# todo mode='contains' require jsonb KeyTextTransform and probably annotations
|
||||
options = {}
|
||||
for k, v in kwargs.items():
|
||||
options['data__' + k.upper() + '__%s' % mode] = v
|
||||
return options
|
||||
|
||||
@cached_property
|
||||
def hosts(self):
|
||||
return self.model.objects.all().values_list('host', flat=True).distinct()
|
||||
|
||||
@cached_property
|
||||
def units(self):
|
||||
return self.model.objects.all().annotate(unit=KeyTextTransform('_SYSTEMD_UNIT', 'data')).values_list('unit', flat=True).distinct()
|
||||
|
||||
|
||||
class Entry(models.Model):
|
||||
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}Mailtracker{% endblock %}</title>
|
||||
<title>{% block title %}Logtracker{% endblock %}</title>
|
||||
<style>td {white-space: nowrap}</style>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -3,7 +3,28 @@
|
|||
{% block content %}
|
||||
<h1>Logtracker</h1>
|
||||
|
||||
<div style='position:absolute;right:0;'>
|
||||
<form action='.' style='display:inline;'>
|
||||
<select name="host" onchange="this.form.submit()">
|
||||
<option>Hosts</option>
|
||||
{% for h in hosts %}
|
||||
<option value="{{ h }}">{{ h }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<form action='.' style='display:inline;'>
|
||||
<select name="_SYSTEMD_UNIT" onchange="this.form.submit()">
|
||||
<option>Units</option>
|
||||
{% for u in units %}
|
||||
<option value="{{ u }}">{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h2>Journal entries</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -33,8 +33,14 @@ class EntriesList(LoginRequiredMixin, ListView):
|
|||
def get_queryset(self):
|
||||
lines = self.request.GET.get('lines', 100)
|
||||
host = self.request.GET.get('host')
|
||||
message = self.request.GET.get('message')
|
||||
return Entry.objects.dump(host=host, lines=lines, message=message)
|
||||
options = {k: v for k, v in self.request.GET.items() if k not in ('lines', 'host', 'timestamp')}
|
||||
return Entry.objects.dump(host=host, lines=lines, **options)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
data = super().get_context_data(**kwargs)
|
||||
data['hosts'] = Entry.objects.hosts
|
||||
data['units'] = Entry.objects.units
|
||||
return data
|
||||
|
||||
|
||||
class HomeView(LoginRequiredMixin, TemplateView):
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}Mailtracker{% endblock %}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue