Dreamine.Logging 1.0.1

dotnet add package Dreamine.Logging --version 1.0.1
                    
NuGet\Install-Package Dreamine.Logging -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Dreamine.Logging" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Dreamine.Logging" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Dreamine.Logging" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Dreamine.Logging --version 1.0.1
                    
#r "nuget: Dreamine.Logging, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Dreamine.Logging@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Dreamine.Logging&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Dreamine.Logging&version=1.0.1
                    
Install as a Cake Tool

Dreamine.Logging

Dreamine.Logging provides the core logging infrastructure for Dreamine applications. It defines logger abstractions, structured log entries, in-memory diagnostics storage, text formatting, composite sinks, daily text file output, and an async queue sink for high-frequency multi-threaded logging.

➡️ 한국어 문서 보기

Purpose

This package is the UI-independent logging core for Dreamine-based applications. It is designed to keep caller threads free from direct file I/O and UI update costs by separating log creation from log output.

Dreamine.Logging must not depend on WPF or any other presentation framework. WPF-specific log panels are provided by Dreamine.Logging.Wpf.

Features

  • IDreamineLogger abstraction
  • DreamineLogger default logger implementation
  • Log levels: Trace, Debug, Info, Warning, Error, Fatal
  • DreamineLogEntry structured log model
  • IDreamineLogSink for pluggable output targets
  • CompositeLogSink for writing to multiple sinks
  • AsyncQueueSink for bounded, background, non-blocking log dispatch
  • InMemoryLogStore: bounded ring buffer (default capacity 1000, O(1) eviction) for runtime diagnostics and UI integration
  • DreamineTextLogFormatter for plain text formatting
  • TextFileLogSink for daily text log files with buffered writes and controlled flush
  • Graceful shutdown support through AsyncQueueSink.ShutdownAsync(...)

For normal applications, place AsyncQueueSink between the logger and the actual sink chain. This keeps worker threads from blocking on file I/O or UI-bound storage updates.

Application threads
  -> IDreamineLogger
     -> DreamineLogger
        -> AsyncQueueSink
           -> CompositeLogSink
              ├─► InMemoryLogStore   (raises LogAdded events)
              └─► TextFileLogSink

DreamineLogPanelViewModel is not part of this chain. The view model is a separate observer that subscribes to InMemoryLogStore.LogAdded. See the Dreamine.Logging.Wpf document for the WPF presentation flow.

Why AsyncQueueSink Exists

A logging system is often called from thread loops, background workers, communication handlers, motion/IO polling jobs, and UI commands. If every log call writes directly to file or updates UI-bound storage, the caller thread can be delayed. Under sustained logging, the application can also accumulate pending dispatcher operations or unbounded visible log entries.

AsyncQueueSink solves the caller-thread delay problem:

  • producers enqueue log entries quickly;
  • one background worker drains the queue;
  • the queue is bounded by capacity;
  • when the queue is full, the oldest pending entry is dropped instead of blocking the caller (BoundedChannelFullMode.DropOldest);
  • the cumulative drop count is observable via the AsyncQueueSink.DroppedCount property;
  • shutdown can drain pending logs before process exit.

The WPF-side display bound is handled by Dreamine.Logging.Wpf.

Example Registration

The following registration keeps the logger simple and moves asynchronous behavior into the sink chain.

private static AsyncQueueSink? _asyncLogSink;

private static void RegisterLogging()
{
    // --- 1. Synchronous sinks -----------------------------------------
    var logStore = new InMemoryLogStore(capacity: 1000);
    var formatter = new DreamineTextLogFormatter();

    var textFileSink = new TextFileLogSink(
        Path.Combine(AppContext.BaseDirectory, "Logs"),
        formatter,
        flushEveryWriteCount: 20);

    var compositeSink = new CompositeLogSink(new IDreamineLogSink[]
    {
        logStore,
        textFileSink
    });

    // --- 2. Async decorator -------------------------------------------
    _asyncLogSink = new AsyncQueueSink(
        compositeSink,
        capacity: 8192,
        drainBatchSize: 256);

    // --- 3. Logger ----------------------------------------------------
    // Note: DreamineLogger currently has no (single sink, level, category)
    // overload, so even a single sink is wrapped as IEnumerable<IDreamineLogSink>.
    var logger = new DreamineLogger(
        new IDreamineLogSink[] { _asyncLogSink },
        DreamineLogLevel.Trace,
        category: "SampleSmart");

    // --- 4. DI registration -------------------------------------------
    DMContainer.RegisterSingleton(logStore);
    DMContainer.RegisterSingleton<IDreamineLogStore>(logStore);
    DMContainer.RegisterSingleton<IDreamineLogFormatter>(formatter);

    // Expose the async sink so external consumers also pass through the queue.
    DMContainer.RegisterSingleton<IDreamineLogSink>(_asyncLogSink);
    DMContainer.RegisterSingleton<IDreamineLogger>(logger);
}

Shutdown

When AsyncQueueSink is used, drain the queue during application shutdown. This prevents recent logs from being lost and also disposes the inner sink chain, including file handles.

protected override void OnExit(ExitEventArgs e)
{
    try
    {
        _asyncLogSink?.ShutdownAsync(TimeSpan.FromSeconds(2))
                      .GetAwaiter()
                      .GetResult();
    }
    catch
    {
        // Shutdown errors must not prevent process exit.
    }
    finally
    {
        base.OnExit(e);
    }
}

OnExit is a synchronous method, so use GetAwaiter().GetResult() rather than async void to ensure the process does not exit before the queue is drained.

Text File Output

TextFileLogSink writes daily log files.

Logs/yyyy-MM-dd.log

Example:

[2026-05-09 18:30:22.718] [Info] [SampleSmart] [T1] Application initialized.

TextFileLogSink keeps the current daily file open instead of opening and closing the file for every entry. It flushes after a configured number of writes and flushes immediately for Error or higher entries.

Thread Safety

DreamineLogger, AsyncQueueSink, CompositeLogSink, InMemoryLogStore, and TextFileLogSink are designed for shared, application-wide singleton usage. The recommended registration is one logger instance, one async sink, and one sink chain for the application.

TextFileLogSink and InMemoryLogStore are guarded by internal locks, so they remain thread-safe even when called directly without AsyncQueueSink. Routing through the queue is still recommended to avoid blocking caller threads on file I/O.

For high-frequency loops, avoid writing logs on every cycle in production. Prefer logging only on:

  • state changes;
  • warnings or errors;
  • operation start/end;
  • diagnostic mode;
  • throttled intervals.

Important Notes

  • Register IDreamineLogger as a DreamineLogger whose sink chain includes AsyncQueueSink.
  • Register IDreamineLogSink as the AsyncQueueSink when external consumers may resolve a sink directly.
  • Do not include the same sink instance both in a logger's sink list and inside a CompositeLogSink registered to the same logger; the entry would be written twice.
  • Keep WPF UI components out of this package.
  • Use Dreamine.Logging.Wpf for visible log panels.

Relationship with Dreamine.Logging.Wpf

Dreamine.Logging.Wpf
  -> Dreamine.Logging

The dependency direction must stay one-way. Dreamine.Logging is the core layer; Dreamine.Logging.Wpf is the presentation adapter.

Future Roadmap

  • DreamineLoggerOptions (a single options object combining capacity, batch size, file directory, etc.)
  • DMContainer.UseDreamineLogging(...) (an extension method that collapses the registration boilerplate above into one line)
  • A DreamineLogger convenience constructor for (single sink, level, category)
  • File rolling policy (size- or count-based, in addition to daily)
  • Database sink
  • External logging service sink
  • Dropped-entry reporting hook for AsyncQueueSink (event-based notification)
  • Optional log throttling helper

License

MIT License

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Dreamine.Logging:

Package Downloads
Dreamine.MVVM.FullKit

All-in-one package for Dreamine MVVM on WPF. Includes core MVVM modules and automatic source generator integration.

Dreamine.Logging.Wpf

WPF logging UI components for Dreamine applications, including a log panel view, log panel view model, and WPF dispatcher integration.

Dreamine.Threading

Core threading abstractions and scheduling infrastructure for Dreamine applications.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 159 5/9/2026
1.0.0 103 5/6/2026