I see four issues raised in the article and the following discussion:
1. Efficiency: author seems to show that there is no difference (or at worst) small difference in efficiency between using triggers and stored procedures for logging transactions to the audit trail table(s), but perhaps I missed something on that.
2. Security: some people are very concerned about someone else maliciously manipulating their database (banking, eg.). The audit trail task should be completely independent from the insert/edit/delete, and be automatic. In that case triggers seem to be the safest way to have a solid audit trail.
3. Clarity: triggers are hidden from the readers of the code – unless the readers of the code know about the trigger’s existence when they look at the insert/edit/delete procedures, they would not be able to understand how the code works.
4. Maintainability: if multiple insert/edit/delete routines exist and triggers are not used, then each routine must include identical audit-trail code. Changing the audit-trail task requires going back and changing all versions, or else the system gets broken.
For those who do not need to worry about 1 or 2 (like me), then clarity and maintainability are the core issues. The time-tested solution to this is modularity: extract the audit-trail code to its own stored procedure, and include a call to the audit-trail procedure in every insert/edit/delete procedure. This way changes to the audit-trail task occurs in one place only, and changing it shouldn't affect the other code. Similarly, if the insert/edit/delete code is modular, then changes to it need to occur in one place only, even if you have several specialized routines. The cost is efficiency -- the extra overhead of a second procedure call each time -- but if this is not a big concern then the benefit of clarity will outweigh the cost.