Search code examples
c#.net-coreazure-cosmosdbasp.net-core-webapiaudit.net

Audit.Net targeting cosmos container based on the controller


I'm using Audit.Net for logging all the controller actions in my application and it is an awesome library.

I'm using Azure Cosmos DB to audit all the events. I'm using below setup to connect Cosmos DB:

Configuration.Setup()
      .UseAzureCosmos(config => config
      .Endpoint(configuration["AuditSettings:ConnectionString"])
      .AuthKey(configuration["AuditSettings:AuthKey"])
      .Database(configuration["AuditSettings:Database"])
      .Container(configuration["AuditSettings:Container"])
      .ConnectionPolicy(new ConnectionPolicy
      {
        ConnectionMode = ConnectionMode.Direct,
        ConnectionProtocol = Protocol.Tcp
      }));

Currently all the events info is going into one container but now I want to use different containers for different controllers. For eg: For UserController actions I want to use UserContainer in Cosmos DB and for EmployeeController I want to use EmployeeContainer.

I should be able to setup the container for each controller I use, planning to use an attribute on the controller class to specify which container should be used for storing audit events info.

I'm unable to figure out how to access configuration within the controller context or in the context filters. I can get CurrentAuditScope from the controller instance but not sure how I can access configurator so that I can set the container dynamically before it writes to Cosmos DB.

Any ideas will be greatly appreciated.


Solution

  • A change could be requested here for the Azure Cosmos data provider to allow building the container name with a delegate function that takes the AuditEvent as a parameter.

    Similar to other data providers, like the SQL Server data provider.

    So you could setup like this:

    using Audit.WebApi;
    
    Audit.Core.Configuration.Setup()
        .UseAzureCosmos(_ => _
            .Endpoint("...")
            .AuthKey("...")
            .Database("...")
            .Container(auditEvent =>
            {
                return auditEvent.GetWebApiAuditAction().ControllerName;
            })
    

    In the meantime I think a workaround is to get the audit event directly from the current HttpContext, for example assuming asp.net core:

    public void Configure(IApplicationBuilder app, IHttpContextAccessor contextAccessor)
    {
        Audit.Core.Configuration.Setup()
            .UseAzureCosmos(_ => _
                .Endpoint("...")
                .AuthKey("...")
                .Database("...")
                .Container(() =>
                {
                    var action = 
    contextAccessor.HttpContext.Items["__private_AuditApiAction__"] as AuditApiAction;
                    return action.ControllerName;
                })
        ...
    }
    

    The magic string is from here