Cerbi.MEL.Governance
1.0.42
dotnet add package Cerbi.MEL.Governance --version 1.0.42
NuGet\Install-Package Cerbi.MEL.Governance -Version 1.0.42
<PackageReference Include="Cerbi.MEL.Governance" Version="1.0.42" />
<PackageVersion Include="Cerbi.MEL.Governance" Version="1.0.42" />
<PackageReference Include="Cerbi.MEL.Governance" />
paket add Cerbi.MEL.Governance --version 1.0.42
#r "nuget: Cerbi.MEL.Governance, 1.0.42"
#:package Cerbi.MEL.Governance@1.0.42
#addin nuget:?package=Cerbi.MEL.Governance&version=1.0.42
#tool nuget:?package=Cerbi.MEL.Governance&version=1.0.42
Cerbi.MEL.Governance
Real-time logging governance for Microsoft.Extensions.Logging (MEL). Validates structured state against Cerbi governance profiles, preserves the original log line, and emits a secondary JSON payload only on violations. Adds optional non-blocking governance score shipping.
Why
Standard loggers / collectors (Serilog, NLog, Log4Net, MEL console/file, OpenTelemetry / OTLP Collector, Seq, Loki / Promtail / Alloy, Fluentd / FluentBit, ELK / OpenSearch, Graylog, VictoriaLogs / VictoriaMetrics, journald / syslog) do not enforce enterprise governance (required / forbidden fields, PII/PHI protection, relaxation tagging, scoring metadata). Cerbi adds that governance layer without replacing existing sinks.
Key Features
- Required / forbidden field enforcement
- Structured logging + scope support
- Topic routing via
[CerbiTopic] - Original line always emitted; second JSON line only on violations
- Relaxed mode via
{Relax}property + profileAllowRelax - Non-blocking governance score shipping (batch, retry, license-gated)
- Hot-path optimizations (caching, low allocation field extraction)
Installation
dotnet add package Cerbi.MEL.Governance --version 1.0.36
Enforcement Modes and Controls
EnforcementMode:Strict(default),Audit, orOff.- Strict: validate and tag success/violations; emit violation JSON lines when violations occur.
- Audit: validate and tag but do not change behavior beyond emitting violation JSON on violations.
- Off: skip validation fast-path.
MinValidationLevel: only validate at or above this MELLogLevel.SamplingRate(0.0–1.0): fraction of events validated.
Configuration JSON (cerbi_governance.json)
{
"EnforcementMode": "Strict",
"LoggingProfiles": {
"Orders": {
"FieldSeverities": {
"userId": "Required",
"email": "Required",
"password": "Forbidden"
},
"AllowRelax": true,
"RequireTopic": true,
"AllowedTopics": ["Orders"]
}
}
}
Wiring (Host builder)
// Program.cs / host builder
builder.Logging.AddCerbiGovernance(builder.Configuration); // binds from "Cerbi:Governance" by default
// or minimal manual configuration
builder.Logging.AddCerbiGovernance(o =>
{
o.Profile = "Orders"; // fallback profile
o.ConfigPath = "cerbi_governance.json"; // profile file
o.Enabled = true; // toggle governance
o.EnforcementMode = GovernanceEnforcementMode.Strict; // Strict | Audit | Off
o.MinValidationLevel = LogLevel.Information; // validate at/above this level
o.SamplingRate = 1.0; // 0..1 sampling
o.AppName = "MyService"; // for score events
o.Environment = "prod"; // for score events
o.ScoreShipping = new ScoreShippingOptions
{
Enabled = true,
LicenseAllowsScoring = true,
Endpoint = "https://scores.cerbi.local/api/ship",
ApiKey = "secret-key"
};
});
Optional configuration binding
{
"Cerbi": {
"Governance": {
"Profile": "Orders",
"ConfigPath": "cerbi_governance.json",
"Enabled": true,
"EnforcementMode": "Strict",
"MinValidationLevel": "Information",
"SamplingRate": 1.0,
"AppName": "MyService",
"Environment": "prod",
"ScoreShipping": {
"Enabled": true,
"LicenseAllowsScoring": true,
"Endpoint": "https://scores.cerbi.local/api/ship",
"ApiKey": "secret-key"
}
}
}
}
Topic Routing
[CerbiTopic("Orders")]
public class OrderService
{
private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger) => _logger = logger;
public void Process(string userId, string email)
=> _logger.LogInformation("Order processed for {userId} {email}", userId, email);
}
Logs from OrderService use the Orders profile automatically.
Relaxed Mode (v1.0.36)
- Set
AllowRelax: truein profile and include a structured property{Relax}(bool true) in the log state. - Example:
_logger.LogInformation("Email-only (relaxed): {email} {Relax}", "user@example.com", true);
Produces second JSON line with GovernanceRelaxed: true.
Example Violations
Missing required field:
{"GovernanceProfileUsed":"Orders","GovernanceViolations":["MissingField:userId"],"GovernanceRelaxed":false}
Forbidden field:
{"GovernanceProfileUsed":"Orders","GovernanceViolations":["ForbiddenField:password"],"GovernanceRelaxed":false}
Relaxed:
{"email":"user@example.com","CerbiTopic":"Orders","GovernanceRelaxed":true,"GovernanceProfileUsed":"Orders"}
Governance Score Shipping
When ScoreShipping.Enabled and LicenseAllowsScoring are true and the structured state contains GovernanceScoreImpact (numeric), a GovernanceScoreEvent is enqueued (non-blocking):
Fields extracted:
GovernanceScoreImpact→ doubleGovernanceViolations→ array mapped to summariesGovernanceRelaxed→ bool
Shipper behavior:
- Queue size capped (
MaxQueueSize) - Batch flush (
BatchSize) everyFlushIntervalSeconds - Retries (
MaxRetries,RetryDelayMilliseconds) - Drops silently on errors; logging path unaffected
To trigger scoring:
_logger.LogInformation("Scored event {userId} {GovernanceScoreImpact}", "abc123", 2.5);
Performance
Optimizations:
- Category + type attribute caching (minimal StackTrace usage)
- Manual dictionary construction (avoid LINQ / boxing)
- Single validator instance per provider
- Score shipping done off-thread; enqueue O(1)
Interoperability
- Flows MEL scopes (ILogger.BeginScope) through provider and logger
- Coexists with other MEL providers (Serilog, NLog, OTel, Console)
FAQ
Q: Does it replace my logger? A: No, it wraps MEL and preserves existing providers.
Q: Can logs be dropped? A: Original line is always emitted; violations add a second JSON line.
Q: How to relax one log? A: Include {Relax} true and have AllowRelax: true in profile.
Q: Scoring without impact? A: No event shipped if GovernanceScoreImpact missing or non-numeric.
Q: License gating? A: LicenseAllowsScoring=false blocks shipping even if enabled.
Contributing
Issues and PRs with tests welcome. MIT licensed.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Cerbi.Governance.Core (>= 1.0.2)
- Cerbi.Governance.Runtime (>= 1.1.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.5)
- Microsoft.Extensions.Logging.Console (>= 9.0.5)
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 |
|---|---|---|
| 1.0.42 | 123 | 11/23/2025 |
| 1.0.41 | 141 | 11/22/2025 |
| 1.0.40 | 169 | 11/15/2025 |
| 1.0.39 | 165 | 11/15/2025 |
| 1.0.38 | 133 | 10/25/2025 |
| 1.0.37 | 201 | 6/5/2025 |
| 1.0.35 | 198 | 6/4/2025 |
| 1.0.34 | 182 | 6/4/2025 |
| 1.0.33 | 185 | 6/4/2025 |
| 1.0.32 | 197 | 6/4/2025 |
| 1.0.31 | 132 | 6/1/2025 |
| 1.0.30 | 152 | 6/1/2025 |
| 1.0.29 | 147 | 6/1/2025 |
| 1.0.28 | 167 | 5/31/2025 |
| 1.0.27 | 157 | 5/31/2025 |
| 1.0.26 | 166 | 5/31/2025 |
| 1.0.25 | 158 | 5/31/2025 |
| 1.0.24 | 147 | 5/31/2025 |
| 1.0.23 | 157 | 5/31/2025 |
| 1.0.22 | 122 | 5/31/2025 |
| 1.0.21 | 126 | 5/31/2025 |
| 1.0.20 | 121 | 5/31/2025 |
| 1.0.19 | 109 | 5/31/2025 |
| 1.0.18 | 104 | 5/31/2025 |
| 1.0.17 | 124 | 5/30/2025 |
| 1.0.16 | 122 | 5/30/2025 |
| 1.0.15 | 205 | 5/27/2025 |
| 1.0.14 | 191 | 5/27/2025 |
| 1.0.13 | 193 | 5/27/2025 |
| 1.0.12 | 200 | 5/26/2025 |
| 1.0.11 | 196 | 5/26/2025 |
| 1.0.10 | 205 | 5/26/2025 |
| 1.0.9 | 201 | 5/26/2025 |
| 1.0.8 | 211 | 5/26/2025 |
| 1.0.7 | 196 | 5/26/2025 |
| 1.0.6 | 194 | 5/26/2025 |
| 1.0.5 | 191 | 5/26/2025 |
| 1.0.4 | 197 | 5/26/2025 |
| 1.0.3 | 201 | 5/26/2025 |
| 1.0.2 | 192 | 5/26/2025 |
| 1.0.1 | 198 | 5/26/2025 |
| 1.0.0 | 180 | 5/26/2025 |