3.14.0.5
3.14.0.5
Two releases in one. 3.14.0.4 was tagged but never published — its release run failed on
infrastructure and was superseded before a rerun — so for anyone on 3.14.0.3 everything below
is new, including the whole 3.14.0.4 section at the end. The binding pins are unchanged from
3.14.0.3's: DatadogNet.iOS 3.14.0.3, DatadogNet.Android 3.12.1.3, DatadogNet.Mac
3.14.0.2 (dd-sdk-ios 3.14.0, dd-sdk-android 3.12.1). Binding releases carrying their own
round of improvements ship separately; a later façade release re-pins.
A logger created early now comes alive
The one real behaviour bug in this release's line: both native SDKs answer "create a logger"
with a permanently dead no-op until Logs is enabled, and loggers are exactly what apps create
early and cache forever — Datadog.Logger, the DI singleton, one ILogger per category. Any of
those created before Datadog.Initialize silently dropped every entry for the life of the
app, even after the SDK came up.
Now a logger created too early holds the recipe instead of the corpse: entries written while the
SDK is down are dropped (the documented pre-initialise contract, unchanged), but the logger
starts delivering at the first write after Initialize, and AddAttribute/AddTag
configuration applied while it waited is kept and replayed in order. Datadog.Stop() also
resets Datadog.Logger, so a re-initialised app gets a logger of the new epoch.
The ILogger bridge carries structure, not just text
logger.LogInformation("Order {OrderId} placed", id) used to reach Datadog as flat text. The
provider now implements ISupportExternalScope and forwards what Microsoft.Extensions.Logging
already carries:
- message-template values become attributes (
OrderId: 42) — the things the Logs UI facets on; - the template itself lands as
logger.template, one value per call site however many ids
flow through it; - structured scope values become attributes (the entry shadows its scopes, inner scopes shadow
outer); unstructured scopes collect underlogger.scope; EventIdkeeps itslogger.event_id/logger.event_nameshape.
New: IDatadogSdk
The feature surfaces were injectable all along; the lifecycle was not. IDatadogSdk mirrors the
static façade — Initialize, SetUser, SetAccount, SetTrackingConsent, ClearAllData,
Stop, and the feature properties — with DatadogSdk.Instance delegating to the static.
AddDatadog (and therefore UseDatadog) registers it, so "we call SetUser on sign-in" and
"accepting the consent banner flips consent" are now unit tests against a fake.
New: AddDatadog(IConfiguration) — the appsettings path
builder.Services.AddDatadog(builder.Configuration.GetSection("Datadog"));Bound by a hand-rolled DatadogConfigurationBinder (the required/init configuration shape is
exactly what the reflection binder cannot construct): keys are property names, features enable by
their section being present, defaults come from the option types themselves, and a malformed
section throws at startup naming the full configuration path. The ConfigureNative hooks cannot
come from configuration; use the object overload when you need them.
New package: DatadogNet.Extensions.Diagnostics
The System.Diagnostics.Activity bridge. Name the ActivitySources you mean and their
activities become Datadog spans — tags, DisplayName (as resource.name), error status and
parentage carried across:
using var bridge = DatadogActivityBridge.Start(new DatadogActivityBridgeOptions {
Sources = ["MyCompany.Checkout", "MyCompany.Sync"],
});Forwarding is opt-in per source, because a modern .NET process emits activities from everywhere
and every forwarded span is an event Datadog ingests. Spans go through the same IDatadogTracer
as hand-written ones — TraceOptions.SampleRate and RUM correlation apply once, rather than
through a parallel exporter pipeline with its own configuration to reconcile.
Unhandled-exception reporting is now public, and not MAUI-only
UnhandledExceptionReporting moved into the core package with a public Enable(). A plain .NET
Android or iOS app, a background service, or a generic host — the DI package's own audience —
can now opt into the AppDomain/TaskScheduler/platform-boundary hooks that previously only
UseDatadog could reach. MAUI apps change nothing: TrackUnhandledExceptions delegates to the
same class.
Smaller, but real
GetCurrentSessionIdAsync(CancellationToken)— a default interface implementation, so
existing fakes keep compiling; a support screen can stop waiting on an SDK queue.- Trim and AOT analyzers now run on every head with warnings as errors.
IsTrimmableis
deliberately not claimed; the README states the trimming stance. - The XML docs stop calling Mac Catalyst an unsupported head (the Catalyst TFMs have compiled
the real SDK over the DatadogNet.Mac bindings since3.14.0.3),TraceOptionssheds its 2.x
OpenTracing paragraph, andCrashReporting's docs credit KSCrash rather than PLCrashReporter
for the 3.x line. - The README gains a Version map — façade × dd-sdk-ios × dd-sdk-android × binding pins ×
.NET bands × minimum OS in one CI-checked row — and a Running ahead of the pins section
stating what the>=binding floor does and does not keep working. - The generated GitHub release notes now read their target-frameworks table out of the packed
.nupkgs themselves; the old hardcoded lists omitted every maccatalyst head on the very
release that introduced them. - CI now compiles a windows-headed consumer against the packed
DatadogNet.Maui— the stub
head's whole pitch, previously never consumer-compiled. (A XAML-free MAUI class library rather
than a sample TFM: WinUI's XAML compiler is a Windows-only executable, so a windows-headed MAUI
app cannot build on this repository's macOS runners.)
Everything 3.14.0.4 contained (never published)
DatadogNet.Extensions.DependencyInjection is its own package. Everything UseDatadog
wired into the container, with no MAUI in it: AddDatadog registers the feature interfaces as
TryAdd singletons (a test host's fake wins), an overload registers without initialising,
builder.Logging.AddDatadog() adds the ILogger provider, AddDatadogTracking instruments an
HttpClient. DatadogNet.Maui depends on it and delegates. Moves to be aware of
(source-compatible for a typical app): AddDatadogTracking and
DatadogHttpMessageHandlerOptions moved from the DatadogNet.Maui namespace/assembly into
DatadogNet in the new package; the ILoggingBuilder.AddDatadog(DatadogMauiOptions?) overload
became AddDatadog(LoggerOptions?, LogLevel).
DatadogNet.Maui restores on a Windows head. Stub heads per band: UseDatadog compiles and
runs there, every call lands in the documented no-ops, and the platform-conditional
PackageReference earlier releases required is no longer needed.
Unhandled-exception coverage reaches the platform boundaries. Android's
UnhandledExceptionRaiser and Apple's managed-exception marshalling, beyond the AppDomain and
TaskScheduler hooks; a weak reported-set keeps a failure seen twice to one RUM error.
Verified harder. Device tests exercise DatadogNet.WebView on a real platform web view; the
sample demonstrates ConfigureNative, the consent cycle, and gated Session Replay recording;
the façade's WebView/CrashReporting packages ship their own Android R8 keep-rules under
buildTransitive/; six DI unit tests.
Release pipeline. These notes reach nuget.org (PackageReleaseNotes); CI fails when the
README's versions drift from Directory.Build.props; the net8 sunset is stated policy — dropped
in the first release after .NET 8 leaves support on 10 November 2026.
Upgrading from 3.14.0.3
For a MAUI app: update the version, optionally delete any windows-head guard around the
DatadogNet.Maui reference. Direct callers of the moved HttpClient/logging extensions: see the
moves note above. The ILogger provider now attaches template/scope attributes to log events —
new data on existing events, nothing removed.
Full changelog: v3.14.0.4...v3.14.0.5
Packages
Built against DatadogNet.iOS 3.14.0.3, DatadogNet.Android 3.12.1.3 and DatadogNet.Mac 3.14.0.2 — dd-sdk-ios 3.14.0 (iOS and, built from source, Mac Catalyst) and dd-sdk-android 3.12.1.
The version names the iOS line, because the native SDKs are released on
separate cadences and never share a version number. The fourth component is this
repository's own revision.
| Package | Target frameworks | NuGet |
|---|---|---|
DatadogNet |
net8.0, net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net9.0, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net10.0, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0 |
3.14.0.5 |
DatadogNet.Extensions.DependencyInjection |
net8.0, net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net9.0, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net10.0, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0 |
3.14.0.5 |
DatadogNet.Extensions.Diagnostics |
net8.0, net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net9.0, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net10.0, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0 |
3.14.0.5 |
DatadogNet.CrashReporting |
net8.0, net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net9.0, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net10.0, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0 |
3.14.0.5 |
DatadogNet.WebView |
net8.0, net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net9.0, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net10.0, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0 |
3.14.0.5 |
DatadogNet.Maui |
net8.0-android34.0, net8.0-ios18.0, net8.0-maccatalyst18.0, net8.0-windows10.0.19041, net9.0-android35.0, net9.0-ios18.0, net9.0-maccatalyst18.0, net9.0-windows10.0.19041, net10.0-android36.0, net10.0-ios26.0, net10.0-maccatalyst26.0, net10.0-windows10.0.19041 |
3.14.0.5 |
dotnet add package DatadogNet.Maui --version 3.14.0.5
Licensing
The code in this repository is MIT. It depends on DatadogNet.iOS,
DatadogNet.Android and DatadogNet.Mac, whose packages ship native binaries built
from Datadog's Apache-2.0 sources. Each package declares MIT AND Apache-2.0
and ships both texts under licenses/.