Anixe.IO.AuditlogClient 2.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Anixe.IO.AuditlogClient --version 2.0.0                
NuGet\Install-Package Anixe.IO.AuditlogClient -Version 2.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Anixe.IO.AuditlogClient" Version="2.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Anixe.IO.AuditlogClient --version 2.0.0                
#r "nuget: Anixe.IO.AuditlogClient, 2.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Anixe.IO.AuditlogClient as a Cake Addin
#addin nuget:?package=Anixe.IO.AuditlogClient&version=2.0.0

// Install Anixe.IO.AuditlogClient as a Cake Tool
#tool nuget:?package=Anixe.IO.AuditlogClient&version=2.0.0                

AuditlogClient

Anixe.IO.AuditlogClient allows you to quickly integrate your asp .net core application with anixe auditlog.

How to integrate

add in csproj as a package reference

<PackageReference Include="Anixe.IO.AuditlogClient" Version="1.0.3" />

add section to appsettings.json

{
  ...
  "AuditlogClient" : {
    "Applicaton" : "geolocations", // application name
    "Middleware" : {
      "TenantFieldName": "tenant", // define a field which contains tenant
      "EntityIdFieldName": "id",//define a field which contains entity id
      "EntityIdType": "geo", // if the application has only one entity type, then you can predefine it here.
      "IncludeMethods": [],
      "ExcludeMethods": [ // omit theese requests with http method
        "OPTIONS",
        "HEAD"
      ],
      "IncludeUrls": [],
      "ExcludeUrls": [ // do not log for theese incoming requests urls to avoid measuring healthchecks
        "/ping",
        "$health$", //$..$ to match all urls which contains health
        "/status$" // ...$ to match all urls which start with /status
      ],
      "IncludeUsers": [],
      "ExcludeUsers": ["geoimporter"] // if you know whom to exclude
    },
    "LogSender" : {
      "Async": true, // use bacground worker to send logs
      "BaseUri" : "http://localhost:5005", // auditlog server uri
      "Timeout": "00:01:00", // timeout for sending single message
      "MaxMessageBytes": 4096, // buffer in bytes for payload
      "RetryPolicy": {
        "Enabled": true // enable default retry policy
      }
    }
  }
}

Register dependencies. The registration method registers AuditlogMessage instance in DI container with per http request lifecycle. So you can expect it as a depencency also.

    public void ConfigureServices(IServiceCollection services)
    {
      services.UseAnixeAuditlogClient(this.config, opts =>
      {
        // override some configuration
      });
    }

Default convention

  • Auditlog message properties are filled from HttpContext
    • Timestamp is DateTime.UtcNow of HTTP request
    • Action is based on HTTP method
    • SubAction is made from conroller and action
    • User is taken from Identity.Name
    • EntityType is taken from configuration
    • EntityId is taken from asp .net core route field defined by Middleware::EntityIdFieldName setting
    • RequestId is taken from asp .net core items field with id "rid" for not define will generate on his own
    • Tenant is taken from asp .net core route field defined by Middleware::TenantFieldName setting
    • LogSender is provided by default with following features:
    • It sends log in background as IHostedService or in foreground based on Async setting.
    • RetryPolicy is going to retry sending logs until timeout occurs in case of communication error with auditlog server.

How to override convention

  • Use options in appsettings to customise the convention
    • LogSender:MaxCapacity determines log queue if log sender works in background as IHostedService
    • LogSender:Timeout determines maximum time for one log entry to be send. Is is also valid to retry policy
    • LogSender:RetryPolicy:Enabled enables default retry policy
    • LogSender:RetryPolicy:RetryHttpCodes determines http status codes received from auditlog server which will trigger retry action. Defaults are: 408,500,502,503,504
    • LogSender:RetryPolicy:SleepDurationMs determines time between retries
  • Use argument of UseAnixeAuditlogClient method to provide custom retry policy programically
  • Expect AuditlogMessage from DI to provide your own data into log message. The object's lifecycle is per http request (scoped).
  • AuditlogMessage instance is also available in HttpContext.Items[nameof(AuditlogMessage)]

How to restrict client against sending logs from unwanted actions

  • use ExcludeMethods configuration, eg. "ExcludeMethods": ["HEAD"]
  • use ExcludeUrls configuration, eg. "ExcludeUrls": ["/ping", "/health"]
  • usr ExcludeUsers configuration, eg. "ExcludeUsers": ["roe_importer", "geo_importer"]

similar for inclusion filters: IncludeMethods, IncludeUrls, IncludeUsers; which works as whilelist:

How to add own data to auditlog message

after registration, the AuditlogMessage instance is registered in DI container with per http request lifecycle (so we carefull with singletons). So you can expect it as a depencency during http request execution. It is also available in http context items under nameof(AuditlogMessage) key.

Provide BeforeAction or AfterAction methods

In Startup.cs provide necessary hook.

    public void ConfigureServices(IServiceCollection services)
    {
      services.UseAnixeAuditlogClient(this.config, opts =>
      {
        opts.BeforeControllerAction = BeforeAction;
      });
    }

    public static void BeforeAction(AuditlogMessage msg, object model)
    {
      var obj = model as IDictionary<string, object>;
      if(obj != null && obj.TryGetValue("request", out var tmp))
      {
        var request = tmp as LocationRequestModel;
        if (request != null)
        {
          msg.EntityId = request.geo_path;
        }
      }
    }

The controller example

public class MyController : Controller
{
  private readonly IMyService svc;

  public MyController(IMyService svc)
  {
    this.svc = svc;
  }

  public async Task<IActionResult> PostAsync(MyRequestMessage c, [FromService]AuditlogMessage msg)
  {
    var response = await this.svc.DoSomethingAsync(IMyService svc, msg);
    return Ok(response);
  }
}

The programically resolve example

public class MyCustomClass
{
  private readonly ServiceProvider di;

  public MyCustomClass(ServiceProvider di)
  {
    this.di = di;
  }

  public void Foo()
  {
    var msg = di.GetService<AuditlogMessage>();
    msg.SubAction = "foo";
    ...
  }
}

The HttpContextAccessor example

public class MyCustomClass
{
  private readonly IHttpContextAccessor accessor;

  public MyCustomClass(IHttpContextAccessor accessor)
  {
    this.accessor = accessor;
  }

  public void Foo()
  {
    var msg = accessor.HttpContext.Items[nameof(AuditlogMessage)];
    msg.SubAction = "foo";
    ...
  }
}

Disable logging into Auditlogs for Controller or Action

public class MyController : Controller
{
  private readonly IMyService svc;

  public MyController(IMyService svc)
  {
    this.svc = svc;
  }

  [DisableAuditlogFilter]
  public async Task<IActionResult> PostAsync(MyRequestMessage c, [FromService]AuditlogMessage msg)
  {
    var response = await this.svc.DoSomethingAsync(IMyService svc, msg);
    return Ok(response);
  }
}

Overrdie AuditlogMessage values with controller or controller's action AuditlogActionAttribute which has precedence over other settings

public class MyController : Controller
{
  private readonly IMyService svc;

  public MyController(IMyService svc)
  {
    this.svc = svc;
  }

  [HttpPost]
  [AuditlogAction(action: "create", subaction: "create", entityType: "my_custom_type", title = "title")] // all properties are optional
  public async Task<IActionResult> PostAsync(MyRequestMessage c)
  {
    var response = await this.svc.DoSomethingAsync(IMyService svc, msg);
    return Ok(response);
  }
}

Take entity type name from controller's Routing attribute

put {template} keyword in AuditlogClient:Middleware:EntityIdTypeFieldName to enable taking the value from router's template

in appsettings.json

{
  ...
  "AuditlogClient": {
      "Applicaton": "vestia",
      "LogSender": {
        ...
      },
      "Middleware": {
          ...
          "EntityIdTypeFieldName": "{template}", // a special keyword
          ...
      }
  }
}

You should expect AuditlogMessage.EntityType filled with value from router template. This example checks it in controller's code.

[Routing("my_resource")]
public class MyController : Controller
{
  private readonly IMyService svc;

  public MyController(IMyService svc)
  {
    this.svc = svc;
  }

  [HttpPost]
  public async Task<IActionResult> PostAsync(MyRequestMessage c, [FromService]AuditlogMessage msg)
  {
    Assert.True(mgs.EntityType == "my_resource");
    var response = await this.svc.DoSomethingAsync(IMyService svc, msg);
    return Ok(response);
  }
}
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0 1,312 1/8/2024
2.0.0 2,046 1/9/2023
1.1.1 3,725 10/29/2021
1.1.0 567 8/31/2021
1.0.24 379 7/8/2021
1.0.23 1,715 1/27/2021
1.0.22 2,436 1/22/2021
1.0.21 468 1/22/2021 1.0.21 is deprecated because it has critical bugs.
1.0.20 423 1/22/2021
1.0.19 477 1/15/2021
1.0.18 440 11/27/2020
1.0.17 442 11/20/2020
1.0.16 425 11/13/2020
1.0.15 890 9/1/2020
1.0.14 5,646 6/29/2020
1.0.13 921 5/25/2020
1.0.12 523 5/25/2020
1.0.11 1,352 4/27/2020
1.0.10 698 3/26/2020
1.0.9 792 3/19/2020
1.0.8 587 3/3/2020
1.0.7 511 2/27/2020
1.0.6 1,330 1/22/2020
1.0.5 1,078 10/10/2019
1.0.4 661 10/10/2019
1.0.3 819 9/24/2019
1.0.2 701 9/24/2019
1.0.1 667 8/27/2019