Audit logs or audit trails are records of data changes made in the system. These trails capture the source of change (user or another application) and details of the change. I have seen that such requirements are provided like security requirements, "the application should be secure". In other words most of the times auditing requirements are implicit and not much time is spent in specifying how it would be used. The expectation is that when (if ever) such information is required it better be there. What usually follows is that the technical people define the requirements and come up with the solution.
Most of the time the solution is something like: persist the change source (or user), date(time) or modification, column name, table name, old value and new value. This is the safest solution, because when implemented all the information about all changes are present in the database. There are couple of ways of implementing this. Do this in the code or use database triggers. This solution needs to be mindful of the following:
Even if we leave the technical challenges aside, generic record level auditing has one fundamental issue which is how we make sense of these changes.
Aggregate.
Consider promoting audit logs to functional level.
Perform audit logging in service layer instead of indiscriminately doing it in repository layer. Passing user context via the layer(s) to the repository.