Skip to content

2.4 Audit trailing

Marjan Nikolovski edited this page Apr 9, 2021 · 1 revision

Purpose

Audit trailing is the act of recording events that occur in our software, in the simplest case, to a single log file.

A transaction log is a file of the communications between a system and the users of that system, or a data collection method that automatically captures the type, content, or time of transactions made by a person with that system.

Signals offers single implementation for the Auditing aspect out of the box:

  • Signals.Aspects.Auditing.AuditNET

Only one implementation can be active at a time.

How to use

When we implement any type of process an audit provider is automatically injected in the process context. Every time there is a call to some process, the call name, time and payload are logged automatically.

// will write an audit trail with process name, payload and start and end time in audit log
public class MyProcess : BusinessProcess<VoidResult>
{
    /// <summary>
    /// Authenticate process
    /// </summary>
    /// <returns></returns>
    public override VoidResult Auth()
    {
        return Ok();
    }

    /// <summary>
    /// Validate process
    /// </summary>
    /// <returns></returns>
    public override VoidResult Validate()
    {
        return Ok();
    }

    /// <summary>
    /// Handle process
    /// </summary>
    /// <returns></returns>
    public override VoidResult Handle()
    {
        // add data in audit instance to describe the audit entry
        var audit = new AuditEntry();

        // will write an audit trail with audit data in audit log
        Context.AuditProvider.Audit(audit, () => {
            // Some code
        });

        return Ok();
    }
}

Other more manual way of using the audit provider is through the IAuditProvider instance.

public class MyClass
{
    public void LogData()
    {
        var auditProvider = SystemBootstrapper.GetInstance<IAuditProvider>();

        // add data in audit instance to describe the audit entry
        var audit = new AuditEntry();

        // will write an audit trail with audit data in audit log
        auditProvider.Audit(audit, () => {
            // Some code
        });
    }
}

Configuration

We configure the audit trailing aspect by using an instance of Signals.Aspects.Auditing.Configurations.IAuditingConfiguration which we pass in the ApplicationBootstrapConfiguration instance (web or background) at startup.

Properties explanation

DatabaseAuditingConfiguration

  • ConnectionString: Connection string to database
  • TableName: Logs table name

FileAuditingConfiguration

  • DirectoryPath: Path to audit files. Default AppDomain.CurrentDomain.BaseDirectory
  • FilenameBuilder: File name building function. Default ````() => $"{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid().ToString()}.json";```

Examples

Using Signals.Aspects.Auditing.AuditNET

DatabaseLoggingConfiguration

services
    .AddSignals(config =>
    {
        config.LoggingConfiguration = new DatabaseLoggingConfiguration
        {
            ConnectionString = myConnectionString,
            TableName = "AuditTrail",
        };
    });

FileLoggingConfiguration

services
    .AddSignals(config =>
    {
        config.LoggingConfiguration = new FileLoggingConfiguration
        {
            FilenameBuilder = () => $"{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid().ToString()}.json",
            DirectoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "audit")
        };
    });

Extending logging

  1. Install package Signals.Aspects.Auditing
  2. Create class with implementation of Signals.Aspects.Auditing.Configurations.IAuditingConfiguration
/// <summary>
/// Auditing configuration contract
/// </summary>
public class MyAuditingConfiguration : IAuditingConfiguration
{
    /// <summary>
    /// Custom property
    /// </summary>
    public string MyProperty { get; set; }
}
  1. Create class with implementation of Signals.Aspects.Auditing.IAuditProvider
/// <summary>
/// Audit provider contract
/// </summary>
public class MyAuditProvider : IAuditProvider
{
    /// <summary>
    /// Creates audit for the audit entry
    /// </summary>
    /// <param name="auditEntry"></param>
    /// <param name="action"></param>
    void Audit(AuditEntry auditEntry, Action action);

    /// <summary>
    /// Creates audit for the audit entry
    /// </summary>
    /// <param name="auditEntry"></param>
    /// <param name="action"></param>
    T Audit<T>(AuditEntry auditEntry, Func<T> action);

    /// <summary>
    /// Creates new audit entry and returns it
    /// </summary>
    /// <returns></returns>
    AuditEntry Entry();
}
  1. Use our implementation of IAuditingConfiguration when configuring our application
public static IServiceProvider AddSignals(this IServiceCollection services)
{
    services
        .AddSignals(config =>
        {
            config.AuditingConfiguration = new MyAuditingConfiguration
            {
                MyProperty = "my_value"
            };;
        });
}
Clone this wiki locally