CcAcca.LogDimensionCollection.AspNetCore 3.0.0

dotnet add package CcAcca.LogDimensionCollection.AspNetCore --version 3.0.0
NuGet\Install-Package CcAcca.LogDimensionCollection.AspNetCore -Version 3.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="CcAcca.LogDimensionCollection.AspNetCore" Version="3.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CcAcca.LogDimensionCollection.AspNetCore --version 3.0.0
#r "nuget: CcAcca.LogDimensionCollection.AspNetCore, 3.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 CcAcca.LogDimensionCollection.AspNetCore as a Cake Addin
#addin nuget:?package=CcAcca.LogDimensionCollection.AspNetCore&version=3.0.0

// Install CcAcca.LogDimensionCollection.AspNetCore as a Cake Tool
#tool nuget:?package=CcAcca.LogDimensionCollection.AspNetCore&version=3.0.0

LogDimensionCollection.AspNetCore

Overview

Collect dimensions from MVC Controller Actions in a log framework agnostic manner

Usage

  1. Install package

    Install-Package CcAcca.LogDimensionCollection.AspNetCore
    
  2. Register feature in Startup.cs / Program.cs

    services.AddMvcActionDimensionCollection();
    
  3. Apply built-in selectors to controller actions

    The library includes several selector implementations that will extract useful dimensions from MVC Controller Actions.

    You register these in Startup.cs:

    // apply selectors to both API and MVC Controllers
    services
       .AddMvcResultItemsCountDimensionSelector()
       .AddMvcActionArgDimensionSelector();
    

    Alternatively:

    // apply selectors to only API controllers
    services
       .AddApiResultItemsCountDimensionSelector()
       .AddApiActionArgDimensionSelector();
    

    Alternatively:

    // apply selectors to only Razor controllers
    services
       .AddRazorResultItemsCountDimensionSelector()
       .AddRazorActionArgDimensionSelector();
    
  4. Decorate the controller/controller actions whose action arguments you want to collect

    IMPORTANT: Be mindful of PII and GDPR concerns

    // collect args for all actions in this controller
    [Route("api/v1/[controller]")]
    [Authorize]
    [CollectActionArgs]
    public class CategoriesController : ControllerBase {
       // snip
    }
    
    [Route("api/v1/[controller]")]
    [Authorize]
    public class CategoriesController : ControllerBase {
       // collect args for this action only
       [HttpGet]
       [CollectActionArgs]
       public async Task<IEnumerable<CategoryViewModel>> Get() {
          // snip
       }
    }
    
  5. Optional: Make imperative calls in a controller action to collect specific dimensions

    // constructor
    public YourController(IActionDimensionCollector dimensionCollector)
    {
       _dimensionCollector = dimensionCollector;
    }
    
    HttpGet]
    public async Task<IEnumerable<ViewModel>> Get()
    {
       _dimensionCollector.TryWhenEnabled(c => c.CollectActionDimension("Interesting", 7));
       // snip
    }
    

The default collector will aggregate these dimensions under a single key in HttpContext.Items for the current request.

Other features can now do interesting things with these dimensions. For example:

Customize feature

Change the default options

services.AddMvcActionDimensionCollection(options =>
{
   // Default prefix is "Action."
   options.ActionDimensionPrefix = "Act:";
   // Use Newtonsoft library instead of the default System.Text.Json
   options.SerializeValue = value => Newtonsoft.Json.SerializeObject(value);

   // for list of all options see MvcDimensionCollectionOptions
});

// or if you've already registered the feature:
services.Configure<MvcDimensionCollectionOptions>(options =>
{
   // set options
});

Change the default options for the ActionArgDimensionSelector

services.ConfigureActionArgDimensionSelector(options =>
{
   // action arguments whose type should not be collected
   options.ExcludedArgTypes =
      ActionArgDimensionSelectorOptions.DefaultExcludedArgTypes.Union(new[] { typeof(UserProfile) }).ToList();
   // note: use with extreme caution and probably never for production workloads!
   options.AutoCollect = true;
});

Define your own selectors

Example: extract metadata for an action
// ActionMetadataSelector.cs:
public class ActionMetadataSelector: ControllerDimensionSelector
{
   public override IDictionary<string, object?>? GetActionExecutingDimensions(ActionExecutingContext context)
   {
      return new Dictionary<string, object?>
      {
         ["RouteData"] = context.ActionDescriptor.RouteValues,
         ["ActionName"] = context.ActionDescriptor.DisplayName,
         ["ActionId"] = context.ActionDescriptor.Id,
      };
   }
}

// Startup.cs:
// appy to all controllers
services.AddMvcActionDimensionSelector<ActionMetadataSelector>();
// OR, appy to API controllers only
services.AddApiActionDimensionSelector<ActionMetadataSelector>();
// OR, appy to Razor controllers only
services.AddRazorActionDimensionSelector<ActionMetadataSelector>();
Example: serialize a collection returned as an ObjectResult
// ResultItemsJsonDimensionSelector.cs
public class ResultItemsJsonDimensionSelector : ControllerDimensionSelector
{
   private IOptionsMonitor<MvcDimensionCollectionOptions> Options { get; }

   public ResultItemsJsonDimensionSelector(IOptionsMonitor<MvcDimensionCollectionOptions> options)
   {
      Options = options;
   }

   public override IDictionary<string, object?>? GetActionResultDimensions(ResultExecutedContext context)
   {
      if (context.Result is not ObjectResult { Value: ICollection collection }) return null;

      return new Dictionary<string, object?>
      {
         { "Json", Options.CurrentValue.SerializeValue(collection) }
      };
   }
}

// Startup.cs:
// all appy to controllers
services.AddMvcActionDimensionSelector<ResultItemsJsonDimensionSelector>();
// OR, appy to API controllers only
services.AddApiActionDimensionSelector<ResultItemsJsonDimensionSelector>();
// OR, appy to Razor controllers only
services.AddRazorActionDimensionSelector<ResultItemsJsonDimensionSelector>();

Replace the default collector

// CustomActionDimensionCollector.cs:
public class CustomActionDimensionCollector : ActionDimensionCollector
{
    public CustomActionDimensionCollector(IOptionsMonitor<MvcDimensionCollectionOptions> optionsMonitor) : base(
        optionsMonitor)
    {
    }

    protected override void DoCollectDimensions(IEnumerable<KeyValuePair<string, object?>>, string? dimensionPrefix)
    {
        foreach (var (key, value) in dimensions.HasKey().PrefixKey(dimensionPrefix))
        {
            // tell someone about this dimension
            // (maybe serializing the value first using Options.SerializeValue(value))
        }
    }
}

// Startup.cs:
services.AddActionDimensionCollector<CustomActionDimensionCollector>();
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 (1)

Showing the top 1 NuGet packages that depend on CcAcca.LogDimensionCollection.AspNetCore:

Package Downloads
CcAcca.LogDimensionCollection.Serilog

Enrich Serilog request logging with collected log dimensions

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0 849 11/18/2023
3.0.0-beta.2 108 9/12/2023
3.0.0-beta.1 67 9/12/2023
2.0.1 22,922 6/24/2021
2.0.0 385 6/20/2021
1.2.2 493 5/27/2021
1.2.1 381 5/20/2021
1.2.0 308 5/20/2021
1.1.0 285 5/17/2021
1.0.0 357 5/16/2021