Table of Contents
Last updated: 10/9/2024

Extension Log


Nuget package


With each release package of the ShareAspace platform there is a Nuget package Eurostep.SAS.Logging.ShareAspace.1.8.0.xyz.nupkg.

The package can be used by .NET 7 based custom extension implementations.

The package adds the ability to include a ShareAspace logger (ShareAspaceLogger), implemented on the ILogger interface, to a custom extension. For ShareAspace Nova based extensions the logger will pickup the id of the request sent to an external extension and use that as the X-correlation-id when reporting back logging information from the extension to ShareAspace. For extensions based on the external endpoint and trusted external endpoint ShareAspace web will provide the X-correlation-id header. The X-correlation-id is picked up by the ShareAspace logger.

Using ShareAspace logger


Middleware

Add a middleware to the custom extension. For Nova extensions the logging framework will automatically pick up the envelope id which is the correlation id required for the logging. For external endpoint and trusted external endpoint the correlation id required for the logging is sent as a X-Correlation-id request header.

In order for the middleware to work it must know its hosting root path. In this example the extension is hosted at <web root>/log-test. The GetExtensionId method must be updated with this information.

Example:

using Eurostep.SAS.External.LoggingExtensions;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace ExternalExtensionTest.Middleware
{
    public class LoggingScopeMiddleware : IMiddleware
    {
        readonly CorrelationIdContext _correlationIdContext;
        readonly ILogger<LoggingScopeMiddleware> _logger;

        public LoggingScopeMiddleware(CorrelationIdContext correlationIdContext, IConfiguration configuration, ILogger<LoggingScopeMiddleware> logger)
        {
            this._correlationIdContext = correlationIdContext;
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            string correlationId = _correlationIdContext.CorrelationId;
            string extensionId = GetExtensionId(context);          
            var envelope = context.Items["ExtensionEnvelope"] as BaseExtensionEnvelope;
            _correlationIdContext.BaseAddress = envelope?.BaseAddress;

            using (_logger.MaybeBeginScope(correlationId, extensionId, envelope?.BaseAddress))
            {
                await next(context);
            }
        }

        string GetExtensionId(HttpContext context)
        {
            return context.Request.Path.StartsWithSegments($"/log-test")
                ? $"{context.Request.Scheme}://{context.Request.Host}/log-test"
                : $"{context.Request.Scheme}://{context.Request.Host}";
        }
    }
}

Startup

Register the logger and the middleware in the Startup.cs of the custom extension implementation.

...
using Eurostep.SAS.External.LoggingExtensions;
...

var builder = WebApplication.CreateBuilder(args);

builder.AddShareAspaceLogging();

...

builder.Services.AddShareAspaceHttpClient();
...
builder.Services.AddTransient<LoggingScopeMiddleware>();

...

var app = builder.Build();

...

app.UseShareAspaceLogging();
app.UseMiddleware<LoggingScopeMiddleware>();

...

Logging implementation

Extensions are expected to use Compile-time logging source generation when defining the logger messages within the extension.

Definition:

public static partial class ExtensionLog
{
    [LoggerMessage(
        EventId = 0,
        Level = LogLevel.Warning,
        Message = "Demo log message from extension")]
    public static partial void DemoLog(this ILogger logger);
}

Usage:

...
private readonly ILogger _logger;
...

_logger.DemoLog();

Extension configuration

The Nuget library requires that the extension register its symmetric key at NovaConfig.SymmetricKey.

//appsettings.json
{
  ...
  "NovaConfig": {
    "SymmetricKey": "PNPpeRwe7XBlegk...FterYJRlMzV1Kzt8/LHA=="
  },
  ...
}

ShareAspace configuration

The logger messages sent to ShareAspace will use the name space of the source extension. To enable the logs in the ShareAspace host log the extension must be defined together with the expected log level. The ShareAspace Host reads the log level configuration from the appsettings.json file. ShareAspace will read the configuration each time that the appsettings.json file is updated. There is no need to restart the ShareAspace Host.

// appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      // Add namespaces as needed
      "ExternalExtensionTest": "Warning",
      ...
    }
  }
}