Cerbi.MEL.Governance
1.0.53
dotnet add package Cerbi.MEL.Governance --version 1.0.53
NuGet\Install-Package Cerbi.MEL.Governance -Version 1.0.53
<PackageReference Include="Cerbi.MEL.Governance" Version="1.0.53" />
<PackageVersion Include="Cerbi.MEL.Governance" Version="1.0.53" />
<PackageReference Include="Cerbi.MEL.Governance" />
paket add Cerbi.MEL.Governance --version 1.0.53
#r "nuget: Cerbi.MEL.Governance, 1.0.53"
#:package Cerbi.MEL.Governance@1.0.53
#addin nuget:?package=Cerbi.MEL.Governance&version=1.0.53
#tool nuget:?package=Cerbi.MEL.Governance&version=1.0.53
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 - Queue-first scoring ingestion (Azure Service Bus + HTTP fallback)
- 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.MinValidationLevel: only validate at/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
builder.Logging.AddCerbiGovernance(o =>
{
o.Profile = "Orders";
o.ConfigPath = "cerbi_governance.json";
o.Enabled = true;
o.EnforcementMode = GovernanceEnforcementMode.Strict;
o.MinValidationLevel = LogLevel.Information;
o.SamplingRate = 1.0;
o.AppName = "MyService";
o.Environment = "prod";
o.ScoreShipping = new ScoreShippingOptions
{
Enabled = true,
LicenseAllowsScoring = true,
Endpoint = "https://scores.cerbi.local/api/ship",
ApiKey = "secret-key"
};
o.ScoringIngestion = new ScoringIngestionOptions
{
Mode = ScoringIngestionMode.QueueFirst,
AzureServiceBus = new AzureServiceBusOptions
{
ConnectionString = "Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=...;",
QueueName = "cerbi-scoring"
}
};
});
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"
},
"ScoringIngestion": {
"Mode": "QueueFirst",
"AzureServiceBus": {
"ConnectionString": "Endpoint=sb://contoso.servicebus.windows.net/;SharedAccessKeyName=...;SharedAccessKey=...;",
"QueueName": "cerbi-scoring"
}
}
}
}
}
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
_logger.LogInformation("Email-only (relaxed): {email} {Relax}", "user@example.com", true);
Produces GovernanceRelaxed: true when profile allows relax.
Example Violations
Missing required field:
{"GovernanceProfileUsed":"Orders","GovernanceViolations":["MissingField:userId"],"GovernanceRelaxed":false}
Forbidden field:
{"GovernanceProfileUsed":"Orders","GovernanceViolations":["ForbiddenField:password"],"GovernanceRelaxed":false}
Governance Score Shipping
ScoreShippingcontrols batching/retries for HTTP fallback.ScoringIngestion.Modechooses transport:QueueFirst(default): send to Azure Service Bus when configured, then HTTP fallback.QueueOnly: send only to Service Bus.HttpOnly: skip queue entirely.
- Service Bus config keys (adapter only):
ScoringIngestion:AzureServiceBus:ConnectionStringScoringIngestion:AzureServiceBus:QueueName
- Optional:
ScoringIngestion:Mode.
Payload contract:
Cerbi.Contracts.ScoringQueueEnvelopeDto
{
"idempotencyKey": "...",
"correlationId": "...",
"tenantId": "...",
"appName": "...",
"environment": "...",
"payload": {
"topic": "Orders",
"category": "MyType",
"logId": "abc123",
"eventId": 42,
"scoreImpact": 2.5,
"governanceRelaxed": false,
"timestamp": "2024-05-10T18:25:43.511Z",
"violations": ["MissingField:userId"],
"fields": { "userId": "abc123", "GovernanceScoreImpact": 2.5 }
}
}
IdempotencyKeydefaults to a deterministic SHA256 ofTenantId|AppName|LogIdwhen not provided.MessageIdon Service Bus uses the IdempotencyKey;CorrelationIdflows when supplied.
Performance
Optimizations:
- Category + type attribute caching (minimal StackTrace usage)
- Manual dictionary construction (avoid LINQ / boxing)
- Single validator instance per provider
- Queue-first scoring ingestion keeps logging path non-blocking
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 envelope is enqueued unless GovernanceScoreImpact is present and numeric.
Q: Queue + HTTP? A: Queue-first will use Service Bus when configured, with HTTP fallback unless QueueOnly is chosen.
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 is compatible. 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. |
-
net10.0
- Azure.Messaging.ServiceBus (>= 7.18.0)
- Cerbi.CerbiShield.Contracts (>= 0.2.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)
-
net8.0
- Azure.Messaging.ServiceBus (>= 7.18.0)
- Cerbi.CerbiShield.Contracts (>= 0.2.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.53 | 97 | 2/26/2026 |
| 1.0.52 | 84 | 2/26/2026 |
| 1.0.51 | 86 | 2/24/2026 |
| 1.0.48 | 186 | 12/22/2025 |
| 1.0.47 | 205 | 12/22/2025 |
| 1.0.46 | 142 | 12/21/2025 |
| 1.0.45 | 210 | 12/19/2025 |
| 1.0.44 | 294 | 12/17/2025 |
| 1.0.43 | 289 | 12/16/2025 |
| 1.0.42 | 167 | 11/23/2025 |
| 1.0.41 | 179 | 11/22/2025 |
| 1.0.40 | 208 | 11/15/2025 |
| 1.0.39 | 204 | 11/15/2025 |
| 1.0.38 | 161 | 10/25/2025 |
| 1.0.37 | 230 | 6/5/2025 |
| 1.0.35 | 228 | 6/4/2025 |
| 1.0.34 | 210 | 6/4/2025 |
| 1.0.33 | 217 | 6/4/2025 |
| 1.0.32 | 225 | 6/4/2025 |
| 1.0.31 | 162 | 6/1/2025 |