< Summary

Information
Class: Elsa.Diagnostics.StructuredLogs.ShellFeatures.StructuredLogsFeature
Assembly: Elsa.Diagnostics.StructuredLogs
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs
Line coverage
90%
Covered lines: 18
Uncovered lines: 2
Coverable lines: 20
Total lines: 106
Line coverage: 90%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
get_RecentLogCapacity()100%11100%
get_SubscriberChannelCapacity()100%11100%
get_MaxRecentLogQuerySize()100%11100%
get_SourceHeartbeatTimeout()100%11100%
get_IncludeStructuredLogsInternalLogs()100%11100%
get_SensitiveNames()100%11100%
get_SensitiveTextPatterns()100%11100%
ConfigureServices(...)100%11100%
MapEndpoints(...)100%210%
ConfigureOptions(...)100%44100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs

#LineLine coverage
 1using CShells.AspNetCore.Features;
 2using CShells.FastEndpoints.Features;
 3using CShells.Features;
 4using Elsa.Diagnostics.StructuredLogs.Extensions;
 5using Elsa.Diagnostics.StructuredLogs.Options;
 6using Elsa.PackageManifest.Generator.Hints;
 7using JetBrains.Annotations;
 8using Microsoft.AspNetCore.Routing;
 9using Microsoft.Extensions.DependencyInjection;
 10using Microsoft.Extensions.Hosting;
 11
 12namespace Elsa.Diagnostics.StructuredLogs.ShellFeatures;
 13
 14/// <summary>
 15/// Provides live structured log streaming over REST and SignalR.
 16/// </summary>
 17[ShellFeature(
 18    DisplayName = "Structured Logs",
 19    Description = "Provides live structured log streaming over REST and SignalR",
 20    DependsOn = ["ElsaFastEndpoints"])]
 21[UsedImplicitly]
 22public class StructuredLogsFeature : IFastEndpointsShellFeature, IWebShellFeature
 23{
 24    private const string SensitiveNamesDefaultValue = "authorization, token, password, secret, api-key, apikey, cookie, 
 25    private const string SensitiveTextPatternsDefaultValue = "(?i)bearer\\s+[A-Za-z0-9._~+/=-]+; (?i)(password|secret|to
 126    private static readonly StructuredLogsOptions DefaultOptions = new();
 27
 28    [ManifestSetting(
 29        DisplayName = "Recent Log Capacity",
 30        Description = "Maximum number of recent log events retained in memory.",
 31        Category = "Diagnostics",
 32        DefaultValue = "5000",
 33        RestartRequired = true)]
 434    public int RecentLogCapacity { get; set; } = DefaultOptions.RecentLogCapacity;
 35
 36    [ManifestSetting(
 37        DisplayName = "Subscriber Channel Capacity",
 38        Description = "Maximum number of queued log events per streaming subscriber.",
 39        Category = "Diagnostics",
 40        DefaultValue = "1000",
 41        RestartRequired = true)]
 442    public int SubscriberChannelCapacity { get; set; } = DefaultOptions.SubscriberChannelCapacity;
 43
 44    [ManifestSetting(
 45        DisplayName = "Maximum Recent Log Query Size",
 46        Description = "Maximum number of recent log events returned by a query.",
 47        Category = "Diagnostics",
 48        DefaultValue = "1000",
 49        RestartRequired = true)]
 450    public int MaxRecentLogQuerySize { get; set; } = DefaultOptions.MaxRecentLogQuerySize;
 51
 52    [ManifestSetting(
 53        DisplayName = "Source Heartbeat Timeout",
 54        Description = "Time after which a structured log source is considered inactive.",
 55        Category = "Diagnostics",
 56        DefaultValue = "00:00:30",
 57        RestartRequired = true)]
 458    public TimeSpan SourceHeartbeatTimeout { get; set; } = DefaultOptions.SourceHeartbeatTimeout;
 59
 60    [ManifestSetting(
 61        DisplayName = "Include Internal Structured Logs",
 62        Description = "Include log events produced by the structured logs subsystem itself.",
 63        Category = "Diagnostics",
 64        DefaultValue = "false",
 65        Advanced = true,
 66        RestartRequired = true)]
 467    public bool IncludeStructuredLogsInternalLogs { get; set; } = DefaultOptions.IncludeStructuredLogsInternalLogs;
 68
 69    [ManifestSetting(
 70        DisplayName = "Sensitive Names",
 71        Description = "Property names whose values should be redacted from structured log events.",
 72        Category = "Redaction",
 73        DefaultValue = SensitiveNamesDefaultValue,
 74        RestartRequired = true)]
 475    public ICollection<string> SensitiveNames { get; set; } = [..DefaultOptions.SensitiveNames];
 76
 77    [ManifestSetting(
 78        DisplayName = "Sensitive Text Patterns",
 79        Description = "Text patterns whose values should be redacted from structured log events.",
 80        Category = "Redaction",
 81        DefaultValue = SensitiveTextPatternsDefaultValue,
 82        Advanced = true,
 83        RestartRequired = true)]
 484    public ICollection<string> SensitiveTextPatterns { get; set; } = [..DefaultOptions.SensitiveTextPatterns];
 85
 86    public void ConfigureServices(IServiceCollection services)
 87    {
 188        services.AddStructuredLogsServices(ConfigureOptions);
 189    }
 90
 91    public void MapEndpoints(IEndpointRouteBuilder endpoints, IHostEnvironment? environment)
 92    {
 093        endpoints.MapStructuredLogsHub();
 094    }
 95
 96    private void ConfigureOptions(StructuredLogsOptions options)
 97    {
 198        options.RecentLogCapacity = RecentLogCapacity;
 199        options.SubscriberChannelCapacity = SubscriberChannelCapacity;
 1100        options.MaxRecentLogQuerySize = MaxRecentLogQuerySize;
 1101        options.SourceHeartbeatTimeout = SourceHeartbeatTimeout;
 1102        options.IncludeStructuredLogsInternalLogs = IncludeStructuredLogsInternalLogs;
 1103        options.SensitiveNames = [..SensitiveNames];
 1104        options.SensitiveTextPatterns = [..SensitiveTextPatterns];
 1105    }
 106}