Herald.OSS
0.6.0
See the version list below for details.
dotnet add package Herald.OSS --version 0.6.0
NuGet\Install-Package Herald.OSS -Version 0.6.0
<PackageReference Include="Herald.OSS" Version="0.6.0" />
<PackageVersion Include="Herald.OSS" Version="0.6.0" />
<PackageReference Include="Herald.OSS" />
paket add Herald.OSS --version 0.6.0
#r "nuget: Herald.OSS, 0.6.0"
#:package Herald.OSS@0.6.0
#addin nuget:?package=Herald.OSS&version=0.6.0
#tool nuget:?package=Herald.OSS&version=0.6.0
Herald.OSS
Open-source structured logging core for .NET. Apache 2.0.
Herald.OSS is the upstream distribution of the Herald logging kernel.
The kernel passes a stack-allocated LogEventBuffer directly to sinks
through one contract — IKernelSink. Every built-in sink implements
it; the HeraldSinkBase abstract class is the one-line entry point
for custom sinks. The accept path stays zero-allocation across every
call shape — typed-args, params ReadOnlySpan<LogProperty>, the
interpolated handler, and the level-bound interpolated variant.
Targets .NET 8, .NET 9, and .NET 10. AOT-clean. Trim-safe.
Status — v0.4.0
Herald.OSS is the canonical Apache 2.0 upstream that the rest of the
Herald ecosystem absorbs from. v0.4.0 ships the multi-policy
interceptor: property names at every literal-template call site are
normalized through the active naming policy at the consumer's compile
time, so events with the same template produce the same downstream
schema regardless of caller variable names. Consumers committed to
the default Pascal policy can opt into a single-lane interceptor via
<HeraldNamingPolicyAssertion>Default</HeraldNamingPolicyAssertion>
for an additional ~4 ns per emit.
Each release lands here first; the commercial Herald.Core
distribution picks up the changes and layers edition-gated extensions
on top. See CHANGELOG.md for the per-version detail
and FORK_SCOPE.md for the authoritative inventory
of what does and does not ship in OSS.
What ships in Herald.OSS
src/— the kernel, pipeline, formatters, and addons. Multi-tenancy (HeraldTenant,HeraldRegistry) and plugin trust are structural OSS features and ship with no gate.native/dotnet/— the .NET implementation of the kernel, pipeline, and bootstrap (includesStructuredLoggerand the typed-args overload set emitted by the generator).generators/— source-generator project.[HeraldLog]forstatic partiallog methods plus the per-sink[ModuleInitializer]auto-registration generator. Packed intoanalyzers/dotnet/cs/inside the nupkg so downstream sinks pick it up without an extra analyzer reference.tests/— the workhorse test suite, organised across 14 subdirectories (AOT, Addons, Bootstrap, Configuration, Diagnostics, Failures, Generators, Helpers, Otlp, Output, Pipeline, Quick, Routing, Templating). 495+ passing on net8 / 496+ on net9 / 496+ on net10. Multi-TFM clean across all three.benchmarking/library/{net8,net9,net10}/— narrow Herald-only benches across TFMs.benchmarking/comparisons/net10/— head-to-head benches against Serilog, NLog, MEL, ZLogger, and log4net.docs/howtos/— task-oriented guides (quickstart, sinks, operations).docs/guides/— architectural and SDK references.docs/benchmarks/— benchmark methodology, per-bench records, and the consolidated rollup.LICENSE/NOTICE— Apache 2.0 license and attribution.
Notable surfaces in the public SDK:
- Quick builder —
QuickLogBuilder,QuickLogResult, theHeraldRegistrystatic façade, andHeraldHostfor hosts that need per-instance isolation. - Kernel + sinks —
IKernelSink,HeraldSinkBase,KernelBufferAdapter.MaterializeAndRender,LogEventBuffer,LogPropertyCompact. - Source generation + compile-time interceptor —
[HeraldLog]for explicitstatic partiallog methods, plus an automatic interceptor that bakes property names into every literal-templatelogger.Info(...)call site at the consumer's compile time. Three built-in policies (Pascal / Snake / Camel) all baked per call site; the active policy lane is selected at runtime via the publicBuiltinPolicyenum +StructuredLogger.CurrentPolicyKindproperty. Asserting consumers opt into a single-lane emit via<HeraldNamingPolicyAssertion>Default</HeraldNamingPolicyAssertion>for additional perf.[assembly: HeraldBuildAssertion]is auto-emitted into every consumer assembly so a host process can observe at runtime which compile-time shape the consumer chose. - Hot-reload —
IConfigReloadSource,FileConfigReloadSource,HotReloadableLoggingBootstrap.ExecuteReload, and the level-only fast path that recomputes theIsXxxAcceptableproperties. - Management API —
HeraldManagementApi,IManagementApiAuthorizer,AuthorizationDecision,OnAuthorizationDenied,DefaultAuthorizerFactory,LicenseStatusProvider,FileSinkPathResolver, and theRejectUnconfinedFileSinkPathsstrict-mode guard. Ships in OSS at the source level; the upstream Herald.Core gates it behind Pro. - Diagnostics channel —
HeraldRuntimeMessages/HeraldRuntimeMessagesInstance,RuntimeNotice,NoticeSeverity,BoundedNoticeBuffer<T>,DiagnosticLogFailureSink. Framework notices stay off user pipelines. - OTLP receivers — JSON and protobuf decoders under
Addons/OtlpSinks/. Destination OTLP sinks ship separately underHerald.Sinks.Otlp. - Flight recorder —
FlightRecorderLoggerandCrashSafeRingBufferfor trigger-level drain on crash. - MEL adapter —
HeraldLoggerProviderexposes Herald as aMicrosoft.Extensions.Logging.ILoggerProvider. - Multi-tenant routing —
HeraldTenant,HeraldTenantScope, per-tenantStructuredLogger. TheGenSourceGatedSinkprovenance decorator andHeraldEditioninformational badge stay visible to downstream wrappers; OSS enforces nothing against them. - Redaction fast path —
FastPathRedactorfor fixed-rule redaction at the kernel boundary. ~8 ns per event over the baseline. - Sink isolation — a throwing sink does not take down siblings;
failures route through
ILogFailureSinkon both the kernel and chain paths.
Benchmark headlines
4-property accept call, net10. Competitor rows regenerated 2026-05-16 against current package versions.
| Library | Latency | Allocation |
|---|---|---|
| Herald.OSS — asserted default | 27 ns | 0 B |
| Herald.OSS — multi-policy | 31 ns | 0 B |
| NLog | 59 ns | 248 B |
| MEL | 160 ns | 0 B |
| log4net | 192 ns | 336 B |
| Serilog | 210 ns | 720 B |
| ZLogger | 290 ns | 81 B |
Herald's two rows show the V1.1 trade. Consumers who commit at build
time to the default Pascal policy via
<HeraldNamingPolicyAssertion>Default</HeraldNamingPolicyAssertion>
get a single-lane interceptor with no runtime dispatch. Consumers who
want full Pascal / Snake / Camel coverage with runtime
WithNamingPolicy(...) switching get the multi-policy emit at every
call site. Both paths are allocation-free.
Real-sink benches confirm the delta is consumer-observable: file sink, counter sink, and null sink all land within 0.7 ns of each other. Herald's built-in sinks are async-buffered, so per-emit cost is dispatch + buffer-fill regardless of sink shape — the dispatch saving on the asserted path translates to real consumer throughput.
Full results, methodology, and reproduction commands live under
docs/benchmarks/. The consolidated rollup is
docs/benchmarks/consolidated-benchmarks.md.
Getting started
- New to Herald? Start at
docs/howtos/HOWTO-QUICKSTART.md. - Need a custom sink?
docs/howtos/HOWTO-SINKS.md. - Running in production?
docs/howtos/HOWTO-OPERATIONS.md.
Guides (conceptual + SDK):
docs/guides/architecture.md— the three-layer picture.docs/guides/building-sinks.md— how sinks plug in and what it costs at runtime.docs/guides/kernel-sink-pattern.md— zero-allocation custom sinks viaIKernelSink.docs/guides/aot-and-trimming.md— publishing native AOT against Herald.OSS.docs/guides/security-overview.md— what the pipeline defends and what it does not.
Quick example
using MMP.Herald.Events;
using MMP.Herald.Quick;
var result = QuickLogBuilder.Create()
.WithConsoleSink()
.WithMinimumLevel("info")
.BuildAndCommit();
result.Logger.Info(LogCategory.App,
"User {UserId} purchased {Sku} for {Price}", 42, "alpha", 9.99);
Relationship to the Herald Ecosystem
Herald.OSS is the spine — the structured-event engine every other Herald package attaches to. Ingestion shells, analytics overlays, compliance frameworks, commercial editions, sinks: each one builds on the same kernel and pipeline. None of them reimplements the data path.
Herald.OSS (Apache 2.0, this repo) ← the structured-logging spine
│
├──► Commercial editions (license-gated)
│ • Herald.Pro — resilience decorators
│ • Herald.Enterprise — WAL + audit chain
│ • Herald.Compliance — HIPAA / SOC 2 / EU AI Act overlays
│
├──► Host shells (Apache 2.0)
│ • Herald.Lean — headless, config-driven
│ • Herald.Server — HTTP collection + query
│ • Herald.Dashboard — operator UI
│ • Herald.ManagementApi
│
├──► Enrichers & addons (Apache 2.0)
│ • Herald.Sci — HPC + MPI
│ • Herald.ML — batch + epoch + GPU
│ • Herald.Embed — one-line drop-in (+ Game, Godot, MEL)
│
└──► Herald.Sinks (separate repo, 80+ destinations)
Feature work that doesn't depend on edition machinery lands in Herald.OSS first; the commercial layer absorbs it. Edition-gated work lands directly in the commercial layer. The OSS repo and the commercial repos move forward together — neither is a frozen snapshot of the other.
Contributing
Contributions welcome. See CONTRIBUTING.md for the
process. First-time contributors will be asked to sign the
CLA — the same CLA covers
every Herald repository.
Security vulnerabilities: see SECURITY.md. Do not file
public issues.
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 is compatible. 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
- Google.Protobuf (>= 3.34.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Superpower (>= 3.0.0)
-
net8.0
- Google.Protobuf (>= 3.34.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Superpower (>= 3.0.0)
-
net9.0
- Google.Protobuf (>= 3.34.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Superpower (>= 3.0.0)
NuGet packages (89)
Showing the top 5 NuGet packages that depend on Herald.OSS:
| Package | Downloads |
|---|---|
|
MMP.Licensing
Ed25519 license verification for MMPWorks paid packages. v2 wire format + v2.1 caps/cv claim expansion. Engine (pure verifier with EditionCapabilityPresets cap-set resolution) + platform (locator, cache, gate) layers. v2.2 adds license-lifecycle surface (LicenseStateMachine, DemoModeSource, LicenseNag), trusted-clock binding (ITrustedClock three-tier resolution), and hosted check-in client (CheckInClient with Polly v8 resilience) per ADR-211/214/216/219. v2.3 consumes Herald.OSS 0.8.0 cap surface: HeraldLicenseVerifierV2.Verify seeds HeraldVersion.CurrentCapabilities (first-write-wins); new ComponentLifecycleCoordinator drives Active ↔ Unsupported transitions per ADR-220 and owns HeraldVersion.ReplaceCurrentCapabilities for post-boot cap-set changes. Source-linked by consumer products per ADR-0001. |
|
|
MMP.Herald.Business
Herald observability metapackage for business and enterprise deployments. Pulls in every Herald.Sinks destination — HTTP, TCP, UDP, every Enterprise HTTP sink (Seq, Splunk, Honeycomb, Datadog, Loki, SignalFx, Sentry, PagerDuty), community transports (Elasticsearch, Slack, GenericWebhook), and the OTLP trio. Depend on this one package and pick destinations at registration time. |
|
|
MMP.Licensing.Contracts
Canonical contracts surface for Herald licensing: HeraldLicenseException, HeraldLicenseRevokedException, LicenseInfo, HeraldLicense static gate, and the v2.1 EditionCapabilityPresets catalog (generated from data/licensing/{capabilities,presets}/*.json by tools/catalog-gen/). Paid packages + Server/ManagementApi ProjectReference this package so the exception types have one runtime identity at the Server middleware boundary, regardless of which paid assembly throws. |
|
|
MMP.Herald.Sinks.Otlp
Herald sinks for the OpenTelemetry Logs Protocol. Ships three sinks (OTLP JSON, OTLP protobuf, length-delimited protobuf file) that share a hand-rolled protobuf writer so the package stays AOT-clean — no generated messages, no reflection, no IMessage codegen. |
|
|
MMP.Herald.Sinks.Loki
Posts Herald log events to Grafana Loki's push endpoint. Batches events by label set for minimum-stream delivery and keeps high-cardinality properties out of the label index. |
GitHub repositories
This package is not used by any popular GitHub repositories.