FclEx.Serilog
2.4.8
dotnet add package FclEx.Serilog --version 2.4.8
NuGet\Install-Package FclEx.Serilog -Version 2.4.8
<PackageReference Include="FclEx.Serilog" Version="2.4.8" />
<PackageVersion Include="FclEx.Serilog" Version="2.4.8" />
<PackageReference Include="FclEx.Serilog" />
paket add FclEx.Serilog --version 2.4.8
#r "nuget: FclEx.Serilog, 2.4.8"
#:package FclEx.Serilog@2.4.8
#addin nuget:?package=FclEx.Serilog&version=2.4.8
#tool nuget:?package=FclEx.Serilog&version=2.4.8
FclEx.Serilog
Serilog configuration and container-owned logging helpers for FclEx.
What Is Included
- Serilog configuration helpers and lazy, container-owned service registration.
- Enrichers and structured-property helpers.
- Excluder/filter types for source, message, property, and exception filtering.
- JSON formatter and exception formatting options.
- Log event extensions and level helpers.
- Sinks for log mutation, exception formatting, Logstash, and New Relic.
Usage Notes
- This package bridges FclEx HTTP/logging helpers with Serilog.
- Slack-specific Serilog sinks live in
FclEx.Serilog.Slack. - Use the formatter options to keep exception output consistent across sinks.
- The Microsoft logger property helpers return
LoggerPropertyScope. Serilog'sdestructureObjectsoverloads prefix scope property names with@to request object destructuring; this convention is specific to the Serilog provider. ConfigureLoggingandConfigureLoggingBuilderappend Microsoft logging builder actions in registration order. Configure them on the options before callingAddSerilog. They run during service registration, before deferred logger creation.ApplyMicrosoftLoggingFilterreads provider-independent level rules from theLoggingsection. Category matching ignores case and supports one*wildcard. The longest matching category wins, with later rules winning ties. Configuration is read once when the filter is added.- New Relic batches succeed on HTTP 202 Accepted. Serialization, transport, timeout, and other HTTP response failures propagate to Serilog's batching infrastructure for diagnostics and retries.
- New Relic sinks own their default HTTP client and release it during disposal.
The
NewRelicSink(HttpClient, ...)overload keeps the caller's client settings and uses caller ownership by default. PassdisposeHttpClient: trueto transfer ownership to the sink. License keys are attached to individual requests. - Logstash endpoints use
tcp://host:portorudp://host:port, with an explicit destination port from 1 through 65535. The sink validates the URI during construction. - Empty JSON formatter field names omit those fields. Exception formatting failures produce a diagnostic string after the incomplete exception fragment is discarded.
- Default-constructed JSON formatters own independent options, including nested exception options. Passing the same options explicitly shares configuration; finish configuring it before concurrent use.
- Nonempty basic JSON field names must be distinct. Event properties and flattened
New Relic linking metadata cannot override them: colliding properties are omitted
after the naming policy and
@escaping are applied. A configured exception field remains reserved even for events without exceptions. JsonFormatterOptions.PropertyCollisionPolicycontrols other top-level property collisions after naming and escaping:KeepFirst(default),KeepLast, orThrow. Event properties and flattened linking metadata are considered in enumeration order.KeepLastreplaces the value at the first occurrence's output position.ThrowraisesInvalidOperationExceptionwithout appending a partial event. Nested value formatting is unaffected, and basic field names remain reserved.- Destructured scope property names use a thread-safe LRU cache of at most 1024 entries, allowing old dynamic names to be collected after eviction.
LogstashSinkOptions.TcpSendTimeoutdefaults to 30 seconds and covers connecting and sending one serialized TCP batch. On expiry the connection closes and aTimeoutExceptionreaches batching for retry. Formatting time is excluded; UDP is unaffected. Retries can duplicate events from a partially sent batch.ExceptionFormatOptions.IndexPolicyselects when exception indexes are included:None,Always,WhenMultiple, orWhenBranched. The default isWhenBranched.MaxMessageLengthlimits retained message content; an appended...is outside that limit. Duplicate-message omission is checked against the full message first.MessageExcludersearches raw template text, whilePropertyExcluderchecks a top-level property's presence or a string scalar substring. Neither searches recursively through structured values.LogEnricherfills missing properties and preserves values already on an event. Its static host metadata is shared across instances and should be configured before concurrent logging begins.SetSelfLogchanges the global diagnostic destination. Disposing its handle disables diagnostics, keeps the writer open, and does not restore a previous destination. Use a synchronized writer for concurrent diagnostic output.
API Migration
- Replace calls to
MatchMaxLeveOrNullwithMatchMaxLevelOrNull. - The
LogstashInputTypeenum has been removed. Select the transport using thetcporudpscheme inLogstashSinkOptions.Uri. CreateLogger()returnsSerilog.Core.Logger. The caller owns the returned logger and disposes it withusing, orawait usingon supported targets.- Replace the mixed
ConfigureActiondelegate and two-parameter configuration callbacks withConfigure(Action<LoggerConfiguration>). Set integration options and register Microsoft logging builder actions before callingAddSerilog.Configureis now an instance method, so useoptions.Configure(action)for former static calls toSerilogConfigurationExtensions.Configure. AddSerilogcreates a separate singleton logger for each root service provider when logging is first resolved. Applications choose when to assignLog.Logger.- Replace
ExceptionIndexOptionsandExceptionFormatOptions.IndexOptionswithExceptionIndexPolicyandIndexPolicy. These are mutually exclusive policies: oldNonebecomesNone,IncludebecomesAlways,Include | IncludeForMultiplebecomesWhenMultiple, and combinations containingIncludeForMultiBranchedtogether withInclude(including oldDefault) becomeWhenBranched. The old conditional flags alone never enabled indexes; choose the corresponding new policy to enable the intended condition directly. WriteTo.WrapandWrapSinkPipelinepass an owned aggregate sink to the wrapper factory and register the returned wrapper directly. Custom wrappers must forward disposal to that aggregate, implement asynchronous disposal when needed, and forward failure listeners for fallback support.LogEventMutateSinkalready fulfills these responsibilities.- Formatter subclasses should override
GetPropertyCandidatesto customize event/linking-metadata properties before naming and conflict resolution. This replaces theWriteLinkingMetadataPropertieswriting hook.WriteFormattedJsonDatanow receives the final JSON name and must not apply the naming policy again. FormatExceptionSinkandWriteTo.FormatException(...)have been removed. Configure all sinks, then useWrapSinkPipelinewithLogEventMutateSinkto normalize and format exceptions once before dispatching to the whole group.SerilogConfiguration.CreateLogger()already adds this stage automatically.
For example, prepare the configuration before registration.
var options = new SerilogConfiguration()
.Configure(logger => logger.MinimumLevel.Debug())
.ConfigureLogging(builder => builder.SetMinimumLevel(LogLevel.Warning));
services.AddSerilog(options);
Logger Ownership
CreateLogger() creates a caller-owned logger. AddSerilog() registers a factory
whose logger is owned by the root service provider. Disposing a child scope preserves
the root logger. Asynchronous root-provider disposal awaits asynchronous sink cleanup
on supported targets.
LogEventMutateSink owns its directly supplied inner sink. WrapSinkPipeline
transfers all current WriteTo sinks into one aggregate and passes ownership to
the wrapper factory. The ownership chain is wrapper → aggregate → actual sinks.
Each layer releases its directly owned resources and forwards failure notifications.
SerilogLoggerProviderWithoutExternalScope forwards asynchronous disposal on supported
targets; its dispose constructor argument determines whether it owns the destination
logger. Use dispose: false when another owner, such as the root container, disposes it.
With an owning wrapper such as LogEventMutateSink, WriteTo.Wrap and
WrapSinkPipeline preserve failure notifications for fallback chains, including
groups of multiple sinks. The aggregate releases its sinks once and attempts all
registered sink cleanups even if one fails. Cleanup failures propagate, with multiple
failures aggregated. A custom wrapper is responsible for releasing its aggregate
even when cleanup of the wrapper's own resources fails.
Call WrapSinkPipeline after registering all sinks and before CreateLogger.
It wraps the current WriteTo group once per event. AuditTo sinks and later sink
registrations are outside that group. Global filters run before the wrapper, and
per-sink level restrictions run after it. WrapAllSinks remains the separate API
for wrapping each currently registered sink individually.
For example, normalize and format exceptions for every configured WriteTo sink:
using var logger = new LoggerConfiguration()
.WriteTo.Console()
.WrapSinkPipeline(inner => new LogEventMutateSink(inner, e => e.FormatException()))
.CreateLogger();
This generic wrapping helper does not add exception-level filtering. Use
SerilogConfiguration for the minimum-level recheck described below.
Serilog configuration actions run once for each created root logger. Create per-container disposable sinks inside those actions when building multiple providers from the same service collection. Complete configuration before registration.
To use the container-owned logger globally, assign it explicitly after building the application or root provider.
Log.Logger = provider.GetRequiredService<Serilog.ILogger>();
The root provider retains ownership of that logger. If a configuration action fails,
registered sinks are released before the error is propagated. Failures in both
configuration and cleanup are reported together as an AggregateException.
Exception Log Levels
Loggers created by SerilogConfiguration.CreateLogger use LogException.Level as
the event level before applying event filters and sink restrictions. The resulting
level must also pass the logger's current minimum level, including source overrides
and dynamic level switches. LogLevel.None suppresses the event.
After event filters, exception unwrapping and optional formatting run once before
events are dispatched to WriteTo sinks. All sinks receive the same normalized
exception and level; nested LogException levels are not reapplied for later sinks.
The original log call must first pass Serilog's initial minimum-level check and any
upstream filters. For example, an Information call carrying an Error LogException
is discarded when the logger's minimum is Error. The exception level cannot restore
an event rejected earlier. Choose an original call level that passes those checks.
Microsoft ILoggerFactory filters evaluate the original call level.
An Error call carrying a Warning LogException is recorded as Warning only when
the final level passes the Serilog minimum level, event filters, and sink restrictions.
It is discarded when the applicable Serilog minimum is Error.
Inspecting sink registrations and runtime storage
LoggerConfiguration.GetSinks() returns the live mutable WriteTo list, including restriction wrappers;
AuditTo sinks are excluded. Finish changes before CreateLogger() and avoid concurrent access.
Removing sinks does not dispose them, and changing this list does not reconfigure an existing logger.
FieldInfos, MethodInfos, Types, and UnsafeAccessors expose Serilog implementation details and
require a compatible Serilog version. The message renderer uses direct access on .NET 10 and later
and reflection on older targets because .NET 8/9 do not support UnsafeAccessorType.
The public descriptor containers previously named Fields and Methods are now FieldInfos
and MethodInfos; update those type references and recompile consumers when upgrading.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. net11.0 is compatible. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 10.0.15 && < 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
-
.NETStandard 2.0
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 10.0.15 && < 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
-
net10.0
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 10.0.15 && < 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
-
net11.0
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
-
net8.0
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 10.0.15 && < 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
-
net9.0
- Destructurama.Attributed (>= 5.3.0)
- FclEx.Http (>= 2.4.8)
- FclEx.Logging (>= 2.4.8)
- Microsoft.Extensions.Logging.Configuration (>= 10.0.15 && < 11.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FclEx.Serilog:
| Package | Downloads |
|---|---|
|
FclEx.Serilog.Slack
Serilog sink support for sending batched log events to Slack. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.4.8 | 47 | 11/13/2026 |
| 2.4.7 | 54 | 11/12/2026 |
| 2.4.6 | 49 | 11/12/2026 |
| 2.4.5 | 49 | 11/12/2026 |
| 2.4.4 | 172 | 11/5/2026 |
| 2.4.3 | 158 | 11/1/2026 |
| 2.4.2 | 205 | 10/10/2026 |
| 2.4.1 | 148 | 10/8/2026 |
| 2.4.0 | 171 | 10/3/2026 |
| 2.3.9 | 160 | 9/27/2026 |
| 2.3.8 | 139 | 9/26/2026 |
| 2.3.7 | 151 | 9/24/2026 |
| 2.3.6 | 173 | 9/22/2026 |
| 2.3.5 | 140 | 9/22/2026 |
| 2.3.4 | 195 | 8/28/2026 |
| 2.3.3 | 200 | 8/22/2026 |
| 2.3.2 | 163 | 8/20/2026 |
| 2.3.1 | 201 | 8/19/2026 |
| 2.3.0 | 200 | 8/17/2026 |
| 2.2.9 | 204 | 7/18/2026 |