Audit Trail API
Log in a third-party storage
To store the audit log in an additional third-party storage, to send a notification, or just monitor the logged events, implement an IAuditLogger with its single Log method in the following way:
using Telerik.Sitefinity.AuditTrail;
namespace SitefinityWebApp
{
public class CustomLogger : IAuditLogger
{
public void Log(IAuditInfo info)
{
// custom implementation
}
}
}
Register the logger in the container (a name is required) in the following way:
using System;
using Telerik.Microsoft.Practices.Unity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.AuditTrail;
namespace SitefinityWebApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
ObjectFactory.Container.RegisterType<IAuditLogger, CustomLogger>("CustomLogger");
}
}
}
For more details on implementation, see Integrate Audit trail module with Elasticsearch and Kibana
NOTE: The
Logmethod is called synchronously during event handling, which means that the time your logging takes is added to the overall operation time (for example, to publishing an item). Plan carefully the performance implications and if needed, introduce some asynchronicity in your code. Alternatively, introduce an out-of-process message queue or a logging agent to ensure the quick completion of the operation.
Log additional or custom events
To implement audit for your custom events or for Sitefinity's CMS events not implemented out-of-the-box, register an event handler along with the corresponding converters as demonstrated by the following code:
Event code
using System;
using Telerik.Sitefinity.AuditTrail;
using Telerik.Sitefinity.Services.Events;
namespace SitefinityWebApp
{
public partial class AuditSnippets
{
// The event interface is skipped for brevity.
public class CustomEvent : IEvent
{
public string Message { get; set; }
public string Origin { get; set; } // Required by IEvent.
}
internal class CustomEventConverter : IAuditInfoConverter<CustomEvent>
{
public IAuditInfo Convert(CustomEvent evt)
{
var info = new AuditInfo();
// For now setting those two is required.
info.Key = evt.GetType().FullName;
info.Timestamp = DateTime.UtcNow;
// Here go any custom fields, displayed in Kibana.
info.Fields["Message"] = evt.Message;
return info;
}
}
}
}
Global.asax
using System;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.AuditTrail;
namespace SitefinityWebApp.Snippets
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped1;
}
private void Bootstrapper_Bootstrapped1(object sender, EventArgs e)
{
var registry = ObjectFactory.Resolve<AuditRegistry>();
registry.RegisterEventHandler<SitefinityWebApp.AuditSnippets.CustomEvent, SitefinityWebApp.AuditSnippets.CustomEventConverter>();
}
}
}
Augment logged information
To augment the logged event information, for instance loading additional information, implement an IAuditInfoProcessor with its single Process method and register it the container (the name is required).
Following is an example code that adds the display name of the current user (first name and last name) to each log entry:
Event code
using System;
using Telerik.Sitefinity.AuditTrail;
using Telerik.Sitefinity.Modules.UserProfiles;
namespace SitefinityWebApp
{
public partial class AuditAPISnippets
{
internal class CustomEventAuditProcessor : IAuditInfoPostProcessor
{
public void Process(IAuditInfo info)
{
object userID;
if (!info.Fields.TryGetValue(AuditField.UserID, out userID))
return;
info.Fields["UserDisplayName"] = UserProfilesHelper.GetUserDisplayName((Guid)userID);
}
}
}
}
Global.asax
using System;
using Telerik.Microsoft.Practices.Unity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.AuditTrail;
namespace SitefinityWebApp.Snippets
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
ObjectFactory.Container.RegisterType<IAuditInfoPostProcessor, SitefinityWebApp.AuditAPISnippets.CustomEventAuditProcessor>("CustomEventAuditProcessor");
}
}
}