misc: add filtering

This commit is contained in:
Christophe Siraut 2020-09-10 15:28:20 +02:00
parent 8736c1753c
commit 8e4088be2a
6 changed files with 53 additions and 23 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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):

View File

@ -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>