Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this the best approach to creating an audit trail?

Tags:

php

mysql

audit

I'm trying to create some functionality that keeps an audit trail of how data in a given user form has been changed over time, with a dated audit at the foot of that page. For example:

02/04/09 21:49 Name changed from "Tom" to "Chris".

I'm doing this by storing the data in it's present format in the session and then on save checking whether there are any differences in the data being stored. If there are, I'm storing the data how it was before the latest edit in a table called history, and storing the new values in the current user table.

Is this the best approach to be taking?

like image 422
cw84 Avatar asked Nov 30 '22 20:11

cw84


2 Answers

I'm not sure there is one "best approach", there are so many variables to take into consideration, including how far down the development path you are.

Having been through both code-based and db-trigger auditing solutions, I've listed some comments below; I hope you can see where you are now at (in terms of development) could affect these issues:

  • If you need to map the user who changed the data (which you normally do) then db triggers will need to get this information somehow. Not impossible, but more work and several ways to approach this (db user executing query, common user column in each table, etc.)
  • If you use db triggers and you rely on affected rows count returned from queries, then your audit triggers need to have this turned off, or your existing code modified to account for them.
  • IMHO db triggers offer more security, and offer an easier path to audit automation, however they are not foolproof, as anyone with appropriate access can disable the triggers, modify data and then enable them again. In other words, ensure your db security access rights are tight.
  • Having a single table for history is not a bad way to go, although you will have more work to do (and data to store) if you are auditing history for multiple tables, especially when it comes to reconstructing the audit trail. You also have to consider locking issues if there are many tables trying to write to one audit table.
  • Having an audit history table for each table is another option. You just need each column in the audit table to be nullable, as well as storing date and time of action (insert/update/delete) and the user associated with the action.
  • If you go with the single table option, unless you have a lot of time to spend on this, don't get too fancy trying to audit only on updates or deletes, although it may be tempting to avoid inserts (since most apps do this more often than updates or deletes), reconstructing the audit history takes a fair bit of work.
  • If your servers or data span multiple time-zones, then consider using an appropriate datetime type to be able to store and reconstruct the timeline, i.e. store audit event date in UTC as well as including the timezone offset.
  • These audit tables can get huge, so have a strategy if they start affecting performance. Options include table partitioning onto different discs, archiving, etc. basically think about this now and not when it becomes a problem :)
like image 69
si618 Avatar answered Dec 06 '22 16:12

si618


One suggestion; this would be relatively easy to do in a database trigger. In that case, you would never have to worry about whether the code running the update remembers to add a history record.

like image 26
Chase Seibert Avatar answered Dec 06 '22 15:12

Chase Seibert