Skip to content
CAI
Software that uses CAICheck a score

serilog/serilog

64.3

Adequate · 23 September 2026

12.5k

lines of production code

C#

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Serilog is a structured logging library for .NET that provides a flexible pipeline for capturing, filtering, and formatting log events. It supports dynamic log level control, conditional enrichment, and robust sink management with batching, auditing, and failure notification capabilities. The system handles structured data serialization via JSON and text formatters, integrates with distributed tracing contexts, and ensures compatibility with modern .NET features including AOT and trimming.

How it got here

2013 — Core modernization and observability

29 changes.

The project underwent a comprehensive modernization of its core logging infrastructure, introducing dynamic log level control, distributed tracing support, and robust failure notification pipelines. This period also focused on enhancing developer experience and code quality through extensive API refactoring, new formatting abstractions, and a significant expansion of test coverage across parsing, filtering, and sink behaviors.

2015–2017 — Configuration expansion and performance optimization

14 changes.

This period focused on expanding the key-value settings system to support sinks, enrichers, and filters, while introducing a visitor pattern for log event data manipulation. Significant refactoring was applied to the capturing and rendering pipelines to reduce memory allocations and improve performance, accompanied by comprehensive unit tests and performance benchmarks.

2019–2024 — Robustness and test coverage expansion

5 changes.

This period focused on enhancing the reliability of the batching sink by introducing failure listeners, retry time limits, and exponential backoff strategies. Significant effort was also dedicated to expanding test coverage, including API approval tests to prevent unintended public changes, AOT compatibility checks, and comprehensive unit tests for message template rendering and sink configuration.

Features

Dynamic log level control and failure notification pipeline

The core logging pipeline now supports dynamically changing the minimum log level at runtime via the new \LoggingLevelSwitch\ class, which exposes a \MinimumLevel\ property and a \MinimumLevelChanged\ event for reacting to level adjustments. Additionally, a new failure notification system has been introduced, allowing sinks to report errors through the \ILoggingFailureListener\ interface; this includes a fallback mechanism that can re-emit failed log events to an inner sink when a failure is permanent or final, ensuring better resilience and observability of logging issues.

src/Serilog/Core · high confidence

Expanded configuration directives for sinks, enrichers, filters, and destructuring

The key-value settings system now supports configuring \WriteTo.Sink()\, \Audit.Sink()\, \Enrich.With()\, \Destructure.With()\, \Destructure.AsScalar()\, and \Filter.With()\ via configuration keys. This change allows users to attach specific sinks, enrichers, filters, and destructuring policies directly through settings files, including support for static member accessors and interface types where a fully-qualified type name is supplied.

src/Serilog/Settings · high confidence

Introduction of DelegateFilter for custom log event filtering

A new DelegateFilter class has been added to the core filtering pipeline, allowing users to apply custom filtering logic to log events via a delegate. This component implements the ILogEventFilter interface and includes null-checking for both the filter delegate and the log event itself, ensuring robust behavior when integrating custom filtering rules into the logging configuration.

src/Serilog/Core/Filters · high confidence

Introduction of ITextFormatter interface for log formatting

A new ITextFormatter interface has been added to the Serilog.Formatting namespace, defining a contract for formatting log events into textual output via a Format method that accepts a LogEvent and a TextWriter. This establishes the foundational abstraction for text-based log formatting within the library.

src/Serilog/Formatting · high confidence

Message template parsing now supports property alignment

The message template parser in \src/Serilog/Parsing\ has been updated to recognize and parse alignment specifications (e.g., \{Property,-10}\ for left-alignment or \{Property,10}\ for right-alignment) within property tokens. This change introduces new \Alignment\ and \AlignmentDirection\ structures and modifies \PropertyToken\ to store alignment data, allowing log output to pad or truncate property values to a fixed width for better readability in console or file sinks.

src/Serilog/Parsing · high confidence

New core enricher implementations for conditional, safe, and property-based logging

The \src/Serilog/Core/Enrichers\ directory now includes several new internal and public classes that expand how log events are enriched. \ConditionalEnricher\ allows wrapping another enricher with a condition, enabling logic like \Enrich.When()\ and \Enrich.AtLevel()\. \SafeAggregateEnricher\ aggregates multiple enrichers while catching and logging exceptions via \SelfLog\ to prevent individual failures from breaking the pipeline. \PropertyEnricher\ is now a public class that adds named properties to log events, supporting optional object destructuring. Additionally, \FixedPropertyEnricher\ and \EmptyEnricher\ provide specialized behaviors for adding fixed properties and no-op enrichment respectively.

src/Serilog/Core/Enrichers · high confidence

New fluent filtering API for matching log events

A new \Matching\ class has been added to the \Serilog.Filters\ namespace, providing a set of static helper methods to create predicates for filtering log events. Users can now easily filter logs by source type or namespace using \FromSource\<T\>()\ and \FromSource(string)\, which support hierarchical matching for dotted namespace paths. Additionally, the API includes \WithProperty\ overloads to match events based on the presence of a specific property, an exact scalar value, or a custom predicate function applied to the property's value.

src/Serilog/Filters · high confidence

New internal diagnostics and failure handling infrastructure

Serilog introduces a new \LoggingFailedException\ type for sinks to signal internal errors, a \SelfLog\ class that now supports action-based callbacks and flushes output, and a \SelfMetrics\ component that exposes internal counters (such as pipeline creation and self-log writes) via \System.Diagnostics.Metrics\ for observability.

src/Serilog/Debugging · high confidence

New visitor and rewriter base classes for LogEventPropertyValue

Added \LogEventPropertyValueVisitor\ and \LogEventPropertyValueRewriter\ base classes in the \Serilog.Data\ namespace to provide a structured way to traverse and modify log event data. The visitor allows implementations to search, transform, or print value structures (scalars, sequences, structures, and dictionaries) while supporting state passing and allocation-free reuse. The rewriter extends this to enable modifications, such as removing properties or applying limits, with an optimization that returns the original unchanged tree if no rewrites occur.

src/Serilog/Data · high confidence

Support for dictionary property values and distributed logging trace context

Log events can now include properties with dictionary values via the new DictionaryValue type, allowing structured data to be logged as key-value mappings. Additionally, LogEvent now captures and exposes the current ActivityTraceId and ActivitySpanId, enabling distributed tracing correlation to be propagated through log entries.

src/Serilog/Events · high confidence

Architecture

Repository infrastructure and build configuration overhaul

The repository has been restructured with a new solution layout (Serilog.sln) and centralized build properties (Directory.Build.props, Directory.Version.props) that enforce modern C\# features like nullable reference types and implicit usings. A new PowerShell-based build script (Build.ps1) automates restore, build, test, and NuGet packaging, while GitHub Actions workflows (ci.yml) and issue templates standardize the CI/CD pipeline. Developer experience is improved with a .editorconfig for consistent code formatting, a .gitattributes file for line-ending normalization, and an updated .gitignore. Additionally, the project now includes a Code of Conduct, contributing guidelines, and a security policy to formalize community interaction.

(repo-wide) · high confidence

Behavioural changes

Assembly metadata and test access configuration

The Serilog assembly is now explicitly marked as CLS-compliant, ensuring stricter adherence to the Common Language Specification for interoperability. Additionally, the assembly manifest has been updated to grant internal visibility to the 'Serilog.Tests' and 'Serilog.PerformanceTests' assemblies, enabling these test suites to access internal members for comprehensive verification.

src/Serilog/Properties · high confidence

Batching sink now supports failure listeners and retry time limits

The batching sink implementation has been updated to handle transient failures more robustly. It now accepts a failure listener to notify applications when log events are dropped or fail to emit, and introduces a \RetryTimeLimit\ option that controls how long the sink will attempt to retry sending batches before permanently dropping them to prevent memory exhaustion. Additionally, the sink employs an exponential backoff strategy for reconnection attempts, increasing the interval between retries up to a maximum cap.

src/Serilog/Core/Sinks/Batching · high confidence

Core sink infrastructure refactored with conditional, restricted, and async-disposable support

The sink implementation in \src/Serilog/Core/Sinks\ has been rewritten to introduce new internal sink types that enhance logging flexibility and resource management. \RestrictedSink\ now enforces log level filtering via a \LoggingLevelSwitch\, allowing dynamic control over minimum log severity. \ConditionalSink\ enables event forwarding based on custom predicates, while \FilteringSink\ applies multiple filters with optional exception propagation. \DisposingAggregateSink\ and \SecondaryLoggerSink\ now support \IAsyncDisposable\ (when available), ensuring proper asynchronous cleanup of wrapped sinks and sub-loggers. \OptionalInterfaceForwardingSink\ forwards optional interfaces like \ISetLoggingFailureListener\ to underlying sinks, and \SafeAggregateSink\/\AggregateSink\ handle multi-sink emission with robust exception handling. These changes provide a more modular and robust foundation for sink composition.

src/Serilog/Core/Sinks · high confidence

LogContext API refactoring and new control methods

The LogContext API has been refactored to improve performance and usability. The previous \PushProperties()\ method has been removed and replaced with \Push()\, which accepts a single \ILogEventEnricher\ or multiple enrichers via params arrays (including \IEnumerable\ and \ReadOnlySpan\ overloads) to reduce allocations. Additionally, new methods \Suspend()\ and \Reset()\ have been added to \LogContext\, allowing users to clear enrichers from the current async scope and restore them later, which is particularly useful for managing context in asynchronous operations.

src/Serilog/Context · high confidence

Major configuration syntax revamp and new batching/audit capabilities

The logger configuration API has been redesigned to improve discoverability and consistency. A new \BatchingOptions\ class allows fine-grained control over batch sizes, buffering times, and retry limits for batched sinks. Audit logging is now supported via \LoggerAuditSinkConfiguration\, enabling sinks that propagate exceptions. Sink configuration methods now accept an optional \LoggingLevelSwitch\ to allow dynamic minimum-level changes at runtime. Enrichment configuration introduces \When()\ and \AtLevel()\ methods for conditional enrichment, and destructuring configuration adds \ToMaximumStringLength()\ and \ToMaximumCollectionCount()\ to limit payload size. The \ILoggerSettings\ interface provides a standardized way to apply external settings, and \LoggerMinimumLevelConfiguration.ControlledBy()\ allows dynamic level control via a switch.

src/Serilog/Configuration · high confidence

New display formatting with fixed-width log levels and trace context support

The display formatting pipeline has been refactored to introduce \LevelOutputFormat\, allowing log levels in output templates to be rendered with fixed widths and specific casing (e.g., \:u3\ for uppercase, \:w1\ for lowercase, \:t4\ for title case) via the \MessageTemplateTextFormatter\. This change also adds support for \{TraceId}\ and \{SpanId}\ tokens in output templates to propagate distributed tracing identifiers, and introduces a \{UtcTimestamp}\ token for UTC-specific time rendering. Additionally, the formatter now safely handles \Exception.ToString()\ failures by catching exceptions and reporting them in the output, and supports JSON formatting for the \{Properties}\ token using the \:j\ specifier.

src/Serilog/Formatting/Display · high confidence

New scalar conversion and destructuring policies for byte arrays, memory spans, and delegates

The logging system now includes dedicated policies to handle specific value types more safely and efficiently during destructuring. Byte arrays are converted to hexadecimal strings, with large arrays (over 1 KB) truncated to a descriptive summary to prevent excessive log output. New support for \Memory\<byte\>\ and \ReadOnlyMemory\<byte\>\ allows these types to be logged as hex strings without unnecessary allocations, provided the runtime supports spans. Delegates are now converted to their string representation instead of being destructured as objects. Additionally, reflection types like \Type\ and \MemberInfo\ are explicitly handled as scalars to prevent deep object graph traversal.

src/Serilog/Policies · high confidence

Optimized message template caching and silent logger behavior

The core pipeline now uses a by-reference string comparer for the message template cache, improving performance for repeated template strings, while enforcing that the SilentLogger is a singleton to reduce allocations and ensure consistent no-op behavior across the application.

src/Serilog/Core/Pipeline · high confidence

Refactored JSON formatting to use JsonValueFormatter and support structured properties

The \JsonFormatter\ class has been refactored to delegate property value serialization to a new \JsonValueFormatter\ component. This change enables proper formatting of structured property values, including dictionaries and complex objects, rather than just simple scalars. The formatter now also includes TraceId and SpanId fields in the output when present, and supports rendering message templates with specific format providers.

src/Serilog/Formatting/Json · high confidence

Refactored capturing pipeline with new DepthLimiter and PropertyBinder components

The \src/Serilog/Capturing\ module has been restructured to improve performance and maintainability. A new \DepthLimiter\ class now manages destructuring depth, returning \ScalarValue.Null\ when the maximum depth is reached to prevent stack overflows. \PropertyBinder\ and \MessageTemplateProcessor\ have been introduced to handle property construction and message template processing, separating concerns from the core \PropertyValueConverter\. Additionally, \TrimConfiguration\ was added to support AOT/trimming scenarios by allowing the disabling of structure value support for anonymous types via an AppContext switch.

src/Serilog/Capturing · high confidence

Refactored message template rendering with reusable string writers

The rendering logic in \src/Serilog/Rendering\ has been restructured to improve performance and reduce memory allocations. A new \ReusableStringWriter\ class pools \StringWriter\ instances to avoid repeated allocations during message formatting, while \MessageTemplateRenderer\ now handles literal and JSON formatting modes more efficiently. Supporting changes include a new \Casing\ utility for case conversion, a \Padding\ helper for alignment, and optimizations to span-based writes.

src/Serilog/Rendering · high confidence

Serilog core library modernization and .NET 8+ compatibility

The Serilog core library has been significantly refactored to support modern .NET features and improve performance. Key changes include the adoption of C\# 12 features such as collection expressions and file-scoped namespaces, the introduction of default interface methods in \ILogger\ to reduce allocations, and the addition of \IAsyncDisposable\ support for sinks and the \Log.CloseAndFlushAsync()\ method. The library now includes built-in support for trimming and Native AOT via \ILLink.Substitutions.xml\ and \Serilog.targets\, ensuring compatibility with trimmed applications. Additionally, the \LoggerConfiguration.CreateLogger()\ method now throws an exception if called more than once to prevent misuse, and the \Guard\ class provides centralized null-checking with caller argument expressions.

src/Serilog · high confidence

Updated Serilog logo asset

The project's branding asset has been replaced with a new SVG logo derived from a 'Sewing Needle' icon by Kenneth Appiah (CC0 license). This change updates the visual identity used in documentation and marketing materials, replacing the previous logo file.

assets · high confidence

Test coverage

Added AOT test application; Added API approval tests to prevent unintended public API changes; Added benchmarks for MessageTemplateCache performance; Added core test coverage for audit logging, batching, and child logger behavior; Added performance benchmarks for Serilog logging operations; Added test dummy implementations for console themes and sinks; Added test dummy implementations for sinks, enrichers, and policies; Added test support utilities for performance benchmarks; Added tests for API conventions, logging lifecycle, and assembly versioning; Added tests for JSON formatting of scalar types, structures, and dictionaries; Added tests for LogContext property pushing and cloning; Added tests for LogEvent trace propagation and DictionaryValue rendering; Added tests for LogEventPropertyValueRewriter; Added tests for MessageTemplateTextFormatter formatting capabilities; Added tests for PropertyValueConverter behavior; Added tests for SelfLog behavior; Added tests for log event filtering by source and predicate; Added tests for message template rendering and ReusableStringWriter behavior; Added tests for sink configuration and disposal behavior; Added unit tests for key-value settings configuration and value conversion; Added unit tests for message template parsing; Disable test parallelization in Serilog.Tests; Expanded test support infrastructure for Serilog.

Dependencies

Update target frameworks to .NET 10 and modernize dependencies

The project now targets .NET 10.0 alongside .NET 9.0, .NET 8.0, .NET 6.0, .NET Framework 4.7.1, and .NET Standard 2.0, with .NET Framework builds frozen at 4.6.2 and 4.7.1. Test projects have been updated to target .NET 10.0, and dependencies such as xUnit (2.9.2), Microsoft.NET.Test.Sdk (17.11.1), and BenchmarkDotNet (0.15.2) have been upgraded. A new AOT test application has been added to verify compatibility with Ahead-of-Time compilation.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 65 → 64 (-0.8)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 94 → 93 (-0.5)
  • Architecture 94 → 94 (+0.0)
  • Maturity 58 → 59 (+1.1)
  • Readiness 54 → 51 (-2.7)
  • Security 93 → 98 (+5.7)
  • Performance 88 → 88 (+0.0)

Resolved (10)

  • BarePragmaDisable (src/Serilog/Core/Logger.cs)
  • BarePragmaDisable (test/Serilog.Tests/Core/LoggerTests.cs)
  • Bounded contexts not declared
  • Build did not complete in the analyzer
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • LLM evaluation failed
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • XML-doc coverage: Serilog (src/Serilog/Serilog.csproj)

New (23)

  • DeadPreprocessorBranch (test/Serilog.Tests/Context/LogContextTests.cs)
  • Documentation: no installation or build instructions (README.md)
  • Duplicated block (11 lines × 9) (src/Serilog/Formatting/Json/JsonValueFormatter.cs)
  • Duplicated block (14 lines × 2) (src/Serilog/Formatting/Json/JsonValueFormatter.cs)
  • Duplicated block (16 lines × 2) (src/Serilog/Formatting/Json/JsonValueFormatter.cs)
  • Duplicated block (19 lines × 2) (src/Serilog/Core/Sinks/AggregateSink.cs)
  • Duplicated block (24 lines × 2) (src/Serilog/Rendering/Padding.cs)
  • Duplicated block (8–11 lines × 2) (src/Serilog/Core/Logger.cs)
  • FileScopedPragmaDisable (src/Serilog/Core/Logger.cs)
  • FileScopedPragmaDisable (test/Serilog.Tests/Core/LoggerTests.cs)
  • High secret: WD-SECRET-0001 (assets/Serilog.snk)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • IL efficiency: 3 authored method(s) exceed the IL budget (src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs)
  • Leaked secret: private-key-blob (assets/Serilog.snk)
  • Members sharing a duplicated core (9 members, 50+ identical tokens) (src/Serilog/Formatting/Json/JsonValueFormatter.cs)
  • No assertions: ExceptionsThrownByPropertyAccessorsAreNotPropagated (test/Serilog.Tests/Core/AuditSinkTests.cs)
  • No assertions: NullMessageTemplateParametersDoNotBreakBinding (test/Serilog.Tests/Core/LoggerTests.cs)
  • No dependency advisory monitoring
  • Off-boarding risk: anonymized user #1
  • …and 3 more

Changes since last survey

  • 1 commits — 0 feature/other, 1 fixes

By area

  • src/Serilog — 1 commit

Notable commits

  • fix: fix: avoid OverflowException when alignment width is int.MinValue (#2247)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

serilog/serilog was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit bebc7719004f76187ae72e64ce138ec2540f2070 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.