Configuration

All configuration is set once at process start via LOG.Configure(...). The call is not re-entrant — a second call throws InvalidOperationException. If you skip it entirely, defaults apply on first log write.

using OzaLog;

LOG.Configure(o =>
{
    o.KeepDays = -7;
    o.SetFileSizeInMB(50);
    o.OutputFormat = LogOutputFormat.Json;
    o.ConfigureQuote(q => q.Enable = true);
});

1. LogOptions — main logger

1.1 File output

OptionTypeDefaultDescription
KeepDaysint-3Must be negative. Number of days of logs to keep. Older dated subdirectories are deleted by LogRetentionCleaner running every 60 s in the background.
MaxFileSizelong50 * 1024 * 1024 (50 MB)File size threshold for size-based splitting. When a file exceeds this, the next write opens {name}_part2_Log.{ext}.
SetFileSizeInMB(int megabytes)methodConvenience setter for MaxFileSize.
LogPathstring"logs"Root directory under AppDomain.CurrentDomain.BaseDirectory. Full path becomes {baseDir}/{LogPath}/{yyyyMMdd}/{TypeDirectories.*}/{name}_Log.{ext}.
TypeDirectoriesLogTypeDirectoriessee §1.5Per-LogLevel subdirectory configuration.

1.2 Output format (v3.1+)

OptionTypeDefaultDescription
OutputFormatLogOutputFormatTxtGlobal selector: Txt / Log (same content, different extension) / Json (NDJSON). See API §4.
TimeFormatstring"HH:mm:ss.fff"Free-form .NET DateTime format string for the message prefix in Txt/Log modes. Not used in Json mode (which always emits epoch_ms). Invalid format strings fall back to default.
ShowThreadIdbooltrueToggle [T:tid] prefix in Txt/Log; toggle tid field in Json.
ShowThreadNameboolfalseToggle thread name display. When the calling thread has no Thread.Name, the entire thread segment is omitted regardless. In Txt/Log mode the output combines as [T:tid/Name] if both ShowThreadId and ShowThreadName are true.
HighPrecisionTimestampboolfalseOpt-in Stopwatch-hybrid mode for µs-level precision. Raises caller-side ticks read from ~5 ns to ~30 ns. Useful only if your TimeFormat uses precision finer than .fff.

1.3 Async pipeline behavior

OptionTypeDefaultDescription
EnableAsyncLoggingbooltrueIf false, calls write synchronously on the caller thread (no batching, no FileStream pool — slower for HFT but simpler to reason about).
EnableConsoleOutputbooltrueIf true, every log line is also written to Console.WriteLine on the caller thread.
MaxOpenFileStreamsint100 (range [4, 4096])LRU upper bound for the persistent FileStreamPool. When exceeded, the least-recently-written stream is closed.
DiskFlushIntervalMsint100 (range [10, 10000])Period for FileStreamPool.FlushAll() — buffered writes flushed to disk (but not fsync-ed; OS decides write-back).
OnDroppedActionnullCallback fired once per drop event when the queue is full and the oldest entry is dropped. Body must be light (called on dispatcher thread).

1.4 Global exception capture (opt-in)

OptionTypeDefaultDescription
EnableGlobalExceptionCaptureboolfalseIf true, subscribes to AppDomain.UnhandledException + TaskScheduler.UnobservedTaskException and logs them at Fatal level with synchronous immediate flush. Off by default to avoid clashing with the host app's existing handlers.

Does not intercept WPF DispatcherUnhandledException, WinForms ThreadException, or ASP.NET Core middleware exceptions — library can't reach those framework objects. Host app must hook those itself.

1.5 LogTypeDirectories — per-level subdirectories

o.TypeDirectories.DirectoryPath = "LogFiles";   // default if level-specific path is null
o.TypeDirectories.ErrorPath     = "ErrorLogs";  // route Error level to a separate folder
o.TypeDirectories.FatalPath     = "FatalLogs";
// TracePath / DebugPath / InfoPath / WarnPath / CustomPath also available

If a level-specific path is null, it falls back to DirectoryPath.

1.6 AsyncLogOptions — dispatcher tuning

Configured via o.ConfigureAsync(a => { ... }).

OptionTypeDefaultRangeDescription
MaxBatchSizeint100[1, 1000]Max items drained by the dispatcher per wake-up.
MaxQueueSizeint10000[1000, 100000]Queue capacity. When exceeded, drop oldest + OnDropped callback fires.
FlushIntervalMsint1000[10, 10000]Dispatcher wake-up interval. The semaphore wait times out at this interval if no signals arrive.

2. QuoteOptions — Quote pipeline (v3.1+)

Configured via o.ConfigureQuote(q => { ... }). Default is Enable = false — the Quote pipeline must be explicitly opted into.

LOG.Configure(o =>
{
    o.ConfigureQuote(q =>
    {
        q.Enable = true;
        q.OutputFormat = QuoteOutputFormat.Json;
        q.QuotePath = "Quotes";
        q.MaxOpenStreams = 500;
        q.MaxQueueSize = 50_000;
        q.MaxBatchSize = 500;
        q.FlushIntervalMs = 100;
        q.OnDropped = droppedCount => MyMetrics.RecordDrops(droppedCount);
    });
});
OptionTypeDefaultRangeDescription
EnableboolfalseRequired. When false, all LOG.Quote(...) calls are silent no-ops and no background thread is started.
OutputFormatQuoteOutputFormatTxtTxt / Log / Json. Independent from main logger's OutputFormat.
QuotePathstring"Quotes"Subdirectory under {LogPath}/{yyyyMMdd}/ for quote files.
MaxOpenStreamsint500[4, 4096]LRU upper bound for the independent QuoteFileStreamPool. Higher than main logger because crypto/equities symbol counts run to thousands.
MaxQueueSizeint50000[1000, 1_000_000]Quote queue capacity. Drop-oldest on overflow. Higher than main logger because quote throughput is typically 100×–1000× higher.
MaxBatchSizeint500[1, 10000]Max records drained per dispatcher wake-up.
FlushIntervalMsint100[10, 10000]Dispatcher wake-up interval.
OnDroppedAction<long>nullCallback invoked when drops happen. Parameter is the newly-dropped count since the last callback invocation (not cumulative).

The Quote pipeline reuses the main logger's KeepDays and MaxFileSize settings for retention and file splitting. Quote files are cleaned up by the same LogRetentionCleaner.


3. Read-back via LOG.GetCurrentOptions()

After Configure, you can inspect the live configuration via the read-only view:

var current = LOG.GetCurrentOptions();

// Main logger
Console.WriteLine(current.OutputFormat);                  // Json
Console.WriteLine(current.TimeFormat);                    // "HH:mm:ss.fff"
Console.WriteLine(current.ShowThreadId);                  // true
Console.WriteLine(current.ShowThreadName);                // false
Console.WriteLine(current.HighPrecisionTimestamp);        // false
Console.WriteLine(current.MaxOpenFileStreams);            // 100
Console.WriteLine(current.AsyncOptions.MaxQueueSize);     // 10000

// Quote pipeline
Console.WriteLine(current.QuoteOptions.Enable);           // true
Console.WriteLine(current.QuoteOptions.OutputFormat);     // Json
Console.WriteLine(current.QuoteOptions.QuotePath);        // "Quotes"
Console.WriteLine(current.QuoteOptions.MaxOpenStreams);   // 500

All read-back values are wrapped in ReadOnlyLogOptions / ReadOnlyQuoteOptions — consumers cannot mutate the live config through this view.


4. Defaults summary (when LOG.Configure(...) is not called)

GroupSettingDefault
FileKeepDays-3
FileMaxFileSize50 MB
FileLogPath"logs"
FileTypeDirectories.DirectoryPath"LogFiles"
FormatOutputFormatTxt
FormatTimeFormat"HH:mm:ss.fff"
FormatShowThreadIdtrue
FormatShowThreadNamefalse
FormatHighPrecisionTimestampfalse
AsyncEnableAsyncLoggingtrue
AsyncEnableConsoleOutputtrue
AsyncMaxOpenFileStreams100
AsyncDiskFlushIntervalMs100
AsyncAsyncOptions.MaxBatchSize100
AsyncAsyncOptions.MaxQueueSize10000
AsyncAsyncOptions.FlushIntervalMs1000
QuoteQuoteOptions.Enablefalse (opt-in)
QuoteQuoteOptions.OutputFormatTxt
QuoteQuoteOptions.QuotePath"Quotes"
QuoteQuoteOptions.MaxOpenStreams500
QuoteQuoteOptions.MaxQueueSize50000
MiscEnableGlobalExceptionCapturefalse

→ For a one-page API summary see API Reference.