Cerbi.MEL.Governance
1.0.40
See the version list below for details.
dotnet add package Cerbi.MEL.Governance --version 1.0.40
NuGet\Install-Package Cerbi.MEL.Governance -Version 1.0.40
<PackageReference Include="Cerbi.MEL.Governance" Version="1.0.40" />
<PackageVersion Include="Cerbi.MEL.Governance" Version="1.0.40" />
<PackageReference Include="Cerbi.MEL.Governance" />
paket add Cerbi.MEL.Governance --version 1.0.40
#r "nuget: Cerbi.MEL.Governance, 1.0.40"
#:package Cerbi.MEL.Governance@1.0.40
#addin nuget:?package=Cerbi.MEL.Governance&version=1.0.40
#tool nuget:?package=Cerbi.MEL.Governance&version=1.0.40
Got it, you want the README to be explicit about Relax() not existing and how Relax actually works in this repo.
Here’s the fully updated README for Cerbi.MEL.Governance with your new Relax details integrated cleanly into the docs.
You can drop this directly into README.md.
Cerbi.MEL.Governance
Real-time logging governance enforcement for Microsoft.Extensions.Logging (MEL) using the Cerbi validation engine.
Cerbi.MEL.Governance wires Cerbi’s runtime governance engine directly into the MEL pipeline used by ASP.NET Core, Worker Services, Azure Functions, and any .NET app built on Microsoft.Extensions.Logging.
It validates structured logs against Cerbi governance profiles and emits a secondary JSON payload only when violations occur, while always preserving your original log line.
Part of the Cerbi Suite for governed logging, telemetry, and analytics.
Why This Exists
MEL + sinks like Console, File, Serilog, NLog, Log4Net, OpenTelemetry Logging / OTLP, Seq, Grafana Loki / Promtail / Alloy, Fluentd / FluentBit, ELK / OpenSearch, Graylog, VictoriaLogs / VictoriaMetrics, or even Journald / syslog can ship a huge volume of logs.
What they don’t do:
- Enforce Required or Forbidden fields (e.g.,
userId,SSN,password). - Enforce field types or enum sets.
- Tag events as Relaxed vs Strictly governed.
- Emit explicit governance violation metadata for downstream scoring and compliance.
Cerbi.MEL.Governance adds that governance layer on top of MEL, without replacing your existing sinks or observability stack.
Demo & Examples
Full examples and demo projects live here:
👉 Cerbi.MEL.Governance Demo & Examples
Features (Current Scope)
- ✅ Enforce required and forbidden fields via governance profiles
- ✅ Secondary JSON payload only when violations occur (original log always appears)
- ✅ Supports structured logging and
BeginScope - ✅ Supports
[CerbiTopic("…")]profile routing (injects aCerbiTopicfield at runtime) - ✅ Compatible with any MEL-compatible sink (Console, File, Seq, Serilog, NLog, OTEL exporters, etc.)
⚠️ Relaxed mode (v1.0.36 details)
- In this repo (v1.0.36), there is no fluent
Relax()helper.- No
Relax()method or extension exists in the codebase.CerbiGovernanceMELSettingshas noRelaxflag.- Relaxed behavior can only be signaled via a structured state property named
Relax(Boolean) and enabled by"AllowRelax": truein your profile JSON.- When both conditions are met, the second JSON line will include
GovernanceRelaxed: true.
Installation
dotnet add package Cerbi.MEL.Governance --version 1.0.36
Setup
1. Add a governance config file
Create cerbi_governance.json in your project root (or point ConfigPath elsewhere):
{
"EnforcementMode": "Strict",
"LoggingProfiles": {
"Orders": {
"FieldSeverities": {
"userId": "Required",
"email": "Required",
"password": "Forbidden"
},
"AllowRelax": true,
"RequireTopic": true,
"AllowedTopics": [ "Orders" ]
}
}
}
Governance profiles are defined using the shared schema from Cerbi.Governance.Core and can also be managed via CerbiShield.
2. Configure MEL to use Cerbi governance
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Cerbi; // AddCerbiGovernance lives in the Cerbi namespace
var builder = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
options.SingleLine = true;
options.TimestampFormat = "HH:mm:ss ";
});
logging.AddCerbiGovernance(options =>
{
options.Profile = "Orders"; // default fallback profile name
options.ConfigPath = "cerbi_governance.json"; // governance JSON path
options.Enabled = true; // enable/disable at runtime
});
})
.ConfigureServices(services =>
{
services.AddTransient<OrderService>();
});
For minimal APIs / ASP.NET Core:
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddCerbiGovernance(options =>
{
options.Profile = "Orders";
options.ConfigPath = "cerbi_governance.json";
options.Enabled = true;
});
var app = builder.Build();
Optional: [CerbiTopic("…")] to route logs
Use [CerbiTopic] to scope logs to a specific governance profile:
using Cerbi; // CerbiTopicAttribute
[CerbiTopic("Orders")]
public class OrderService
{
private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger)
{
_logger = logger;
}
public void Process()
{
_logger.LogInformation("Order processed for {userId}", "abc123");
}
}
✅ Any log calls from a class tagged with [CerbiTopic("Orders")] will be validated under the "Orders" profile, subject to your JSON config.
Example Logging
// Valid log (has both userId and email)
_logger.LogInformation("User info: {userId} {email}", "abc123", "test@example.com");
// Missing userId → governance violation under "Orders" profile
_logger.LogInformation("Only email provided: {email}", "test@example.com");
// Forbidden field (“password”) → governance violation under "Orders"
_logger.LogInformation(
"Password in log: {userId} {email} {password}",
"abc123",
"test@example.com",
"secret"
);
// Relaxed example (AllowRelax = true in JSON config; {Relax} = true in structured state)
_logger.LogInformation(
"Email-only (relaxed): {email} {Relax}",
"user@example.com",
true
);
Governance Output
When governance is enabled:
- Your original log line is written exactly as you called it.
- If a violation occurs, a second JSON payload is emitted describing the violation(s) and governance metadata.
1. Missing required field (userId)
{
"GovernanceProfileUsed": "Orders",
"GovernanceViolations": [ "MissingField:userId" ],
"GovernanceRelaxed": false
}
2. Forbidden field (password)
{
"GovernanceProfileUsed": "Orders",
"GovernanceViolations": [ "ForbiddenField:password" ],
"GovernanceRelaxed": false
}
3. Relaxed example (AllowRelax = true, Relax = true)
{
"email": "user@example.com",
"CerbiTopic": "Orders",
"GovernanceRelaxed": true,
"GovernanceProfileUsed": "Orders"
}
🔎 Guarantee: The original message is never dropped. The second line is additive and only appears when there’s something to flag.
Environment & Context Enrichment
Cerbi.MEL.Governance can add environment metadata for downstream systems (Loki, Seq, Elastic/OpenSearch, Graylog, VictoriaLogs, OTEL Collector, etc.):
ApplicationId- From
CERBI_APP_ID - Default:
"MyApp"
- From
InstanceId- Machine name / host
Region- From
CLOUD_REGION - Default:
"unknown-region"
- From
CloudProvider- Inferred from environment (e.g., Azure, AWS, GCP, OnPrem) when possible
This makes it easier to slice governance violations by app, instance, region, or cloud provider.
Performance & Benchmarks
A BenchmarkDotNet project is included to test hot-path performance.
From the repo root:
dotnet restore
dotnet build -c Release BenchmarkSuite1/BenchmarkSuite1.csproj
dotnet run -c Release --project BenchmarkSuite1 -- --list tree
# Run a specific benchmark
dotnet run -c Release --project BenchmarkSuite1 -- --filter "*AttributeTopic*"
Notes:
CPUUsageDiagnoseris stubbed; benchmarks will run with or without a real diagnoser.- On real console/file sinks, logging becomes I/O-bound; CPU optimizations still help with spikes but raw throughput is dictated by sinks.
Hot-path Optimizations
Current optimizations include:
Attribute-topic caching
- Cache topic by logger category name and declaring type.
- Prefer category-based resolution; only fall back to a one-time
StackTracescan per logger instance when needed.
Lower-allocation field extraction
- Manual copy to a pre-sized
Dictionary<string, object>(ordinal comparer). - Avoids LINQ and unnecessary allocations on the hot path.
- Manual copy to a pre-sized
Expected Ballpark Throughput (no-op / in-process scenarios)
These are guidance, not hard guarantees, assuming a no-op sink on .NET 8:
- Default-topic fast path: ~3–10M logs/sec is strong.
- Attribute-topic path with caching + small structured state: ~2–6M logs/sec is strong.
- With
StackTraceon every log (pre-optimization): sub-0.5M logs/sec is common.
With actual console/file sinks, 50–200k logs/sec is normal; the sink dominates.
How It Plays with Other Stacks
Cerbi.MEL.Governance runs in the MEL pipeline and is compatible with:
- Serilog / NLog / Log4Net via MEL integration
- Seq (Datalust)
- Grafana Loki / Promtail / Alloy
- Fluentd / FluentBit
- Elastic / OpenSearch / Graylog / VictoriaLogs / VictoriaMetrics
- OpenTelemetry Logging / OTLP / OTEL Collector
- Journald / syslog
You keep your existing sinks/exporters. Cerbi:
- Validates structured state against governance profiles.
- Emits your original log + optional governance JSON line.
- Lets your sinks or OTEL exporters handle the rest.
SBOM & Compliance
- License: MIT
- No outbound network calls.
- All enforcement is in-process against your governance JSON file.
- Safe for secure and regulated pipelines (subject to your own review).
FAQ
Does this replace Serilog/NLog/OTEL? No. It sits in the MEL pipeline and adds governance before logs flow into Serilog, NLog, OTEL exporters, Loki, Seq, ELK, or any other sink.
Does it ever drop logs? In this release:
- The original log is never dropped.
- Violations are surfaced via a second JSON line.
Is there a Relax() helper?
No. In this repo (v1.0.36):
- There is no fluent
Relax()helper. - No
Relax()method or extension exists in the codebase. CerbiGovernanceMELSettingshas noRelaxflag.- Relaxed behavior can only be signaled via a structured state property named
Relax(Boolean), and only when"AllowRelax": trueis enabled in your governance profile JSON.
How do I relax governance for specific logs?
Given "AllowRelax": true in the profile:
_logger.LogInformation(
"Email-only (relaxed): {email} {Relax}",
"user@example.com",
true
);
The governance JSON line will include GovernanceRelaxed: true and GovernanceProfileUsed.
Can I define required/forbidden fields?
Yes, via FieldSeverities in your governance JSON (e.g., Required, Forbidden, Info).
Can I load profiles dynamically? Profiles are read from JSON. You can combine this with config transforms, environment-specific files, or future CerbiShield-based deployment flows.
How does this work with OpenTelemetry Collector? Use Cerbi in the MEL pipeline, then attach OTLP exporters. Logs will reach the OTEL Collector already governed and tagged.
Contributing & Links
- Website: https://cerbi.io
- Repo: https://github.com/Zeroshi/Cerbi.MEL.Governance
- Related projects: CerbiStream, Cerbi.Governance.Core, Cerbi.Governance.Runtime, Cerbi.GovernanceAnalyzer, CerbiShield, CerbIQ, CerbiSense
If this helps keep your logs compliant and non-chaotic, star the repo and open issues/PRs with tests.
License
MIT — see LICENSE.
| 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 | 130 | 11/23/2025 |
| 1.0.41 | 145 | 11/22/2025 |
| 1.0.40 | 171 | 11/15/2025 |
| 1.0.39 | 166 | 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 | 192 | 5/27/2025 |
| 1.0.13 | 194 | 5/27/2025 |
| 1.0.12 | 201 | 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 | 181 | 5/26/2025 |