Auditing allows site administrators to track almost every data-altering action taken in their community, from user logins and content creation to plugin configuration changes, permission changes and more. It’s never good to have a site end up in an unexpected state, but now you will be able to track exactly who changed what, when.
Details about entity creates, updates, and deletes are recorded, together with the account performing the action and other relevant metadata. The auditing service automatically generates a diff based on public writable properties of the entity that have changed, so modifications can be easily tracked.
The auditing log is located in Administration > Monitoring > Auditing. Here administrators can view, filter, and export recent audit data, or download archived audit data.
Data older than 14 days (configurable) is archived into .csv format and no longer viewable through the UI, but still able to be viewed via download. To configure Audit Archive settings go to Administration > Jobs > Auditing Archive Job
Example: Blog Post
When a user creates a blog post, an audit entry will be added for the create action. (Diff details are not shown for creates and deletes)
If the post is later edited (for example, if the original was not published and later published), another audit entry will be added showing the exact changes made.
Example: Deletes
Audit entries are also added when entities are deleted.
Example: Page Layout
Audit entries are also created for site configuration changes like settings, widgets, themes, page layouts, etc. The following is an example of a widget layout change on a page, and the resulting audit entry.
Example: Widgets
Details of widget edits are tracked similarly to themes, automations, and embeddables, with files as well as properties evaluated for changes. Below is an example of widget change that includes two files.
Example: Permissions
Permission changes and a few other features that don’t fit cleanly in a create/edit/delete archetype are logged in a custom format for readability.
Example: Plugin Configuration
Changes to plugin configuration, job schedules, and translations are logged separately.
Example: Site Settings
Site settings and other non-plugin configuration are also logged.
Export
In addition to the archive files, selected or individual entries can be exported in csv format as well.
"Id","Timestamp","Message","Entity Type","Entity Identifier","Entity Description","Entity Url","Action","MachineName","Service Type","Ip Address","AuthenticatedUserId","AuthenticatedUsername","ExecutingUserId","ExecutingUsername","ImpersonatingUserId","ImpersonatingUsername","Data"
"11579","7 May 2020 9:36 PM","<p>ada (2135) edited BlogPost ""<a href=""http://trunk.localhost.com/product/b/announcements/posts/product-update-for-may"">Product Update for May</a>"" (<a href=""http://trunk.localhost.com/product/b/announcements/posts/product-update-for-may"">d8b3cdad-2d41-4854-bdd2-169cedf83a3f</a>) in Blog ""<a href=""http://trunk.localhost.com/product/b/announcements"">Announcements</a>"" in Group ""<a href=""http://trunk.localhost.com/product/"">Product Information</a>"":</p><h4>Body</h4><pre><p>Here are the exciting things that happened last month:</p>
<ul>
<li>Added some features</li>
<li>Fixed some bugs</li>
<li>Polished some UI</li>
<ins class=""merge-added""><li>Wrote</ins> <ins class=""merge-added"">a</ins> <ins class=""merge-added"">blog</ins> <ins class=""merge-added"">post</ins><ins class=""merge-added""></li></ins>
</ul></pre><h4>Excerpt</h4><pre>Here are the exciting things that happened last month:
Added some features
Fixed some bugs
Polished some UI
<ins class=""merge-added"">Wrote</ins> <ins class=""merge-added"">a</ins> <ins class=""merge-added"">blog</ins> <ins class=""merge-added"">post</ins>
</pre><h4>IsApproved</h4><pre><del class=""merge-deleted"">False</del><ins class=""merge-added"">True</ins></pre><h4>IsPostEnabled</h4><pre><del class=""merge-deleted"">False</del><ins class=""merge-added"">True</ins></pre>","BlogPost","d8b3cdad-2d41-4854-bdd2-169cedf83a3f","Product Update for May","http://trunk.localhost.com/product/b/announcements/posts/product-update-for-may","Edited","US-801984","Web","127.0.0.1","2135","ada","2135","ada","","","{""entity"":{""identifier"":""d8b3cdad-2d41-4854-bdd2-169cedf83a3f"",""type"":""BlogPost"",""description"":""Product Update for May"",""location"":{""identifier"":""9ef0dbec-5468-42f2-8439-10c57c6b60a3"",""type"":""Blog"",""description"":""Announcements"",""location"":{""identifier"":""3bbd02a2-53d0-45a7-9e24-3bc8d1d8191c"",""type"":""Group"",""description"":""Product Information"",""location"":{""identifier"":""5f9e44b3-ac4a-470a-afb8-c23a46113aa4"",""type"":""Group"",""description"":""Trunk"",""url"":""~/""},""url"":""~/product/""},""url"":""~/product/b/announcements""},""url"":""~/product/b/announcements/posts/product-update-for-may""},""edits"":{""Body"":{""original"":""<p>Here are the exciting things that happened last month:</p>\n<ul>\n<li>Added some features</li>\n<li>Fixed some bugs</li>\n<li>Polished some UI</li>\n</ul>"",""edited"":""<p>Here are the exciting things that happened last month:</p>\n<ul>\n<li>Added some features</li>\n<li>Fixed some bugs</li>\n<li>Polished some UI</li>\n<li>Wrote a blog post</li>\n</ul>""},""Excerpt"":{""original"":""Here are the exciting things that happened last month:\n\nAdded some features\nFixed some bugs\nPolished some UI\n"",""edited"":""Here are the exciting things that happened last month:\n\nAdded some features\nFixed some bugs\nPolished some UI\nWrote a blog post\n""},""IsApproved"":{""original"":""False"",""edited"":""True""},""IsPostEnabled"":{""original"":""False"",""edited"":""True""}}}"
Extensibility
Auditing also provides several extensibility points for developers to enable their customizations to be audited. Check the documentation (when published for 12.0) for more details:
- IAuditable, IExtendedAuditable, IAuditableMessageOverride - API entity interfaces to allow integration with Auditing
- IAuditing - in-process API to add and list auditing records
- AuditableIgnore - attribute that can be added to an IAuditable entity's properties to exclude them from edit change detection