Shout-out to eventlog

30 October 2014   4 comments   Django

http://eventlog.rtfd.org/

Mind That Age!

This blog post is 4 years old! Most likely, its content is outdated. Especially if it's technical.

If you do things with the Django ORM and want an audit trails of all changes you have two options:

  1. Insert some cleverness into a pre_save signal that writes down all changes some way.

  2. Use eventlog and manually log things in your views.

(you have other options too but I'm trying to make a point here)

eventlog is almost embarrassingly simple. It's basically just a model with three fields:

You use it like this:

from eventlog.models import log

def someview(request):
    if request.method == 'POST':
        form = SomeModelForm(request.POST)
        if form.is_valid():
            new_thing = form.save()
            log(request.user, 'mymodel.create', {
                'id': new_thing.id,
                'name': new_thing.name,
                # You can put anything JSON 
                # compatible in here
            })
            return redirect('someotherview')
    else:
        form = SomeModelForm()
    return render(request, 'view.html', {'form': form})

That's all it does. You then have to do something with it. Suppose you have an admin page that only privileged users can see. You can make a simple table/dashboard with these like this:

from eventlog.models import Log  # Log the model, not log the function

def all_events(request):
    all = Log.objects.all()
    return render(request, 'all_events.html', {'all': all})

And something like this to to all_events.html:

<table>
  <tr>
    <th>Who</th><th>When</th><th>What</th><th>Details</th>
  </tr>
  {% for event in all %}
  <tr>
    <td>{{ event.user.username }}</td>
    <td>{{ event.timestamp | date:"D d M Y" }}</td>
    <td>{{ event.action }}</td>
    <td>{{ event.extra }}</td>
  </tr>
  {% endfor %}
</table>

What I like about it is that it's very deliberate. By putting it into views at very specific points you're making it an audit log of actions, not of data changes.

Projects with overly complex model save signals tend to dig themselves into holes that make things slow and complicated. And it's not unrealistic that you'll then record events that aren't particularly important to review. For example, a cron job that increments a little value or something. It's more interesting to see what humans have done.

I just wanted to thank the Eldarion guys for eventlog. It's beautifully simple and works perfectly for me.

Comments

Greg Taylor
We started with something like this, but ended up not liking the DB bloat that this sort of thing causes. We also started finding that we were using our event log data for some light analytics, which isn't something we had anticipated.

After pondering a number of alternative methods (breaking the event log out into its own DB was the leading candidate), we discovered Keen.io. You throw event logs at it and you can do all kinds of filtering/graphing/statistical calculations based on the key/value pairs within each body.

I don't work for Keen.io, but we really love it at Pathwright. Avoids a lot of unnecessary DB writes and DB bloat, plus our less technical business staff can still figure out how to query it without involving a developer.
Peter Bengtsson
Keen.io looks awesome! I just spent a coupla' minutes skimming their docs and stuff.

However, even though it uses a "persistent connection" it's still a HTTPS POST over the network every time it needs to send something. Blocking too. Perhaps it's doable to "up" that to be a gevent greenlet or something so it can send async but that's probably not trivial.

As far as bloat is concerned, I think this is where it matters. I use my eventlog only to send events when users do something that relates to changing the state (e.g. doing a POST) so there aren't that many events actually.
birmancat
with postgres you could do this entirely inside the db server. See http://gmod.org/wiki/Chado_Audit_Module for example sql. No code in django needed at all
Peter Bengtsson
But then you'd get every insert or update or something, right?

That's no explicit and not very deliberate.

Your email will never ever be published


Related posts

Previous:
Go vs. Python 24 October 2014
Next:
uwsgi and uid 03 November 2014
Related by Keyword:
How do log ALL PostgreSQL SQL happening 20 July 2015
Javascript tip: nifty use of the console.log function in Firebug 07 November 2010
Related by Text:
jQuery and Highslide JS 08 January 2008
I'm back! Peterbe.com has been renewed 05 June 2005
Anti-McCain propaganda videos 12 August 2008
Ever wondered how much $87 Billion is? 04 November 2003
Guake, not Yakuake or Yeahconsole 23 January 2010