Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The property value exceeds the maximum allowed size (64KB). If the property value is a string, it is UTF-16 encoded and the maximum number of characters should be 32K or less. #722

Open
santoshpatro opened this issue Jan 16, 2025 · 1 comment

Comments

@santoshpatro
Copy link

Hi Daniel,

Thanks a lot for sharing with us a great library which has a very good documentation also : https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.WebApi/README.md for implementation of Audit Trail.

I need your help for a scenario detailed at : https://stackoverflow.com/questions/79362056/property-value-exceeds-the-maximum-allowed-size-64kb-if-the-property-value-is

Any help on this request is much appreciated

Thanks,
Santosh

@thepirat000
Copy link
Owner

Consider that with your current configuration, the middleware will log all requests, including those that do not reach an action method (e.g., unresolved routes or parsing errors). Additionally, it logs all request headers, response headers, and the response body.

You can probably optimize your middleware configuration by applying more filtering and using an OnSaving global custom action to modify audit events before saving. This can help reduce the size of your audit logs. Here's an example:

app.UseAuditMiddleware(_ => _
    .FilterByRequest(r => 
        !r.Method.Equals(nameof(HttpMethod.Get), StringComparison.OrdinalIgnoreCase) 
        && r.Path.StartsWithSegments("/api"))
    .WithEventType("{verb}:{url}")
    .IncludeHeaders()
    .IncludeResponseHeaders()
    .IncludeResponseBody());

// Add a custom action to process and trim large audit data
Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaving, scope =>
{
    var action = scope.GetWebApiAuditAction();

    // Truncate excessively large headers
    foreach (var headerKey in action.Headers.Keys)
    {
        if (action.Headers[headerKey]?.Length > 1024)
        {
            action.Headers[headerKey] = "too long...";
        }
    }

    // Truncate excessively large response headers
    foreach (var headerKey in action.ResponseHeaders.Keys)
    {
        if (action.ResponseHeaders[headerKey]?.Length > 1024)
        {
            action.ResponseHeaders[headerKey] = "too long...";
        }
    }

    // Truncate excessively large response bodies
    // NOTE: The action.ResponseBody.Length is derived from the Content-Length response header. If the server does not send this header, it will be null.
    if (action.ResponseBody is { Value: not null, Length: > 16384 })
    {
        action.ResponseBody.Value = "too long...";
    }
});

You might also consider setting up a fallback mechanism to log failed audit events in an alternative location for debugging purposes.

One approach is to use the Audit.NET.Polly library. For instance:

using Audit.AzureStorageTables.Providers;
using Audit.Polly;
using Audit.Core.Providers;

var azureTableStorage = new AzureTableDataProvider(config => config
    .Endpoint(new Uri("..."))
    .TableName(evt => "...")
    .ClientOptions(...)
    .EntityBuilder(...));

var fallbackStorage = new DynamicDataProvider(config => config
    .OnInsert(auditEvent =>
    {
        Console.WriteLine(auditEvent.ToJson());
    }));

// var fallbackStorage = new FileDataProvider(config => config.Directory(@"C:\Logs"));

Audit.Core.Configuration.Setup()
    .JsonSystemAdapter(options)
    .UsePolly(polly => polly
        .DataProvider(azureTableStorage)
        .WithResilience(resilience => resilience
            .AddFallback(new()
            {
                ShouldHandle = new PredicateBuilder().Handle<Exception>(),
                FallbackAction = args => args.FallbackToDataProvider(fallbackStorage)
            })));

Key Points:

  1. Request Filtering: The FilterByRequest method ensures only specific requests (e.g., non-GET requests starting with /api) are logged.
  2. Custom Action: The OnEventSaving custom action processes audit events, truncating oversized headers and body content to maintain manageable log sizes.
  3. Fallback Mechanism: Configure a fallback mechanism to log failed audit events for debugging purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants