Changelog
This file tracks all notable changes to the OzaLog package (formerly Ozakboy.NLOG). Version numbers follow Semantic Versioning.
3.1.0 - 2026-05-14
Three new capabilities: customizable time/thread display, configurable output format (txt/log/json), and a dedicated Quote pipeline for high-frequency tick/quote data with Binance-aligned schema. All additions are backward compatible — defaults preserve v3.0 behavior.
Added
Customizable Time & Thread Display
LogOptions.TimeFormat(default"HH:mm:ss.fff") — free-form .NET DateTime format string for the message prefix. Falls back to default on parse failure.LogOptions.ShowThreadId(defaulttrue) andLogOptions.ShowThreadName(defaultfalse) — independently toggle thread ID / name in the prefix. WhenShowThreadName=truebut the calling thread has no name (Thread.Name == null), the entire thread segment is omitted.LogOptions.HighPrecisionTimestamp(defaultfalse) — opt-inStopwatch-hybrid mode that reconstructs µs-level precision from the 1ms cache; raises caller-side ticks read cost from ~5ns to ~30ns.
Multiple Output Formats
LogOptions.OutputFormat(defaultLogOutputFormat.Txt) — global format selector:Txt/Log(same content, different extension) /Json(NDJSON with fixed schema{ts, lv, nm, tid?, tn?, msg, data?}).- JSON timestamps emit as epoch_ms integers. Field names use short forms (
lv,nm,tid,tn) for compactness.
Quote (Tick/Ticker) Pipeline
LOG.Quote(...)andLOG.QuoteTicker(...)— public API for high-frequency quote/ticker data with field names aligned to Binance REST 24hr Ticker schema (Last,LastQty,Bid,BidQty,Ask,AskQty,Open,PrevClose,High,Low,Volume,QuoteVolume).QuoteRecord(publicreadonly struct) — A2 core API for zero-allocation enqueue. Convenience A1 overloads for the common cases (tick only / bid+ask / full ticker / ticker+extras).QuoteOptions(opt-in viaopt.ConfigureQuote(q => q.Enable = true), default off) — independent async pipeline with its own dispatcher, queue, andFileStreamPool. ConfigurableOutputFormat(Txt/Log/Json),MaxOpenStreams(default 500),MaxQueueSize(default 50000),MaxBatchSize,FlushIntervalMs,OnDropped(long)callback.QuoteRecord.Extras(IReadOnlyDictionary<string, object>) for flexible attributes andQuoteRecord.ExtrasJson(raw pre-serialized JSON string for the zero-overhead path) — mutually exclusive; setting both throwsArgumentExceptionat the call site.- File naming:
{baseDir}/{LogPath}/{yyyyMMdd}/{QuotePath}/{Bucket}_{Symbol}_Quote.{ext}— no nested subdirectories. - Symbol/bucket sanitization: file-system-invalid characters (
/ \ : * ? " < > |) are automatically replaced with-in filenames; the original symbol/bucket text is preserved in the file content.
Tests
- Four new xUnit test files covering custom time formats, NDJSON formatting, Quote schema/error scenarios, and filename sanitization (48 tests total, all passing).
OzaLog.Test/Program.csrewritten to a comprehensive v3.1 smoke-test covering every API surface and error path in a single linear run, with optional CLI args for format selection (txt/log/json).
Improved
LogItemcarriesThreadNameso the dispatcher thread can render the calling thread's name (previously unavailable post-enqueue).- All Quote API overloads funnel through
LOG.Quote(in QuoteRecord)for centralized validation. Errors (null/empty Symbol or Bucket,Extras/ExtrasJsonboth set,Extraskey colliding with a reserved field) throwArgumentExceptionsynchronously on the calling thread — not deferred to the dispatcher. LogFormatterretains a fast path for the defaultHH:mm:ss.fffformat (hand-written, zero-allocation); other formats route throughDateTime.ToStringwithFormatExceptionfallback to default.FileStreamPoolsupports per-output extension (.txt/.log/.json) with corresponding part-detection logic for size-based file splitting.
Technical
System.Text.Json: bumped from8.0.5→9.0.16fornetstandard2.0/netstandard2.1targets (net8.0/net9.0/net10.0still use the BCL built-in — zero NuGet dependencies).Microsoft.SourceLink.GitHub: bumped from8.0.0→10.0.300(build-only,PrivateAssets=all, no consumer impact).- New internal types:
JsonLogFormatter,QuoteFormatter,QuoteFileStreamPool,QuoteLogHandler. Quote pipeline runs entirely in parallel with the mainAsyncLogHandler— they share no locks or stream pools. - Build verified across all 5 TargetFrameworks (
netstandard2.0/netstandard2.1/net8.0/net9.0/net10.0) with 0 errors.
3.0.1 - 2026-05-09
Metadata + repository improvements release. No library code changes — the OzaLog assembly is byte-identical to v3.0.0 (Deterministic build).
Improved
- NuGet package metadata refreshed: cleaner
Description(highlightsLOG.Info_Log("...")API + HFT pipeline + zero dependencies + crypto tick stream use case), updatedPackageTags(addedozalog,hft,high-performance,zero-dependency; removed misleadingnlogtag), polishedTitle. PackageReleaseNotesnow uses absolute GitHub URLs for cross-references (NuGet doesn't render relative paths).
Technical
- New project website: Nuxt 4 + @nuxt/content + Tailwind CSS, deployed to GitHub Pages → https://ozakboy.github.io/OzaLog/
- Repository documentation restructured: all user-facing docs moved to
docs/{en,zh-TW}/bilingual tree (changelog.md,migration.md, plus templates forgetting-started.md,configuration.md,api.md,async-pipeline.md,benchmarks.md). - GitHub Actions auto-deploys the site on push to main.
- Sponsor page added with USDT (BEP20) wallet + Binance Pay QR.
uplogrelease flow extended: now also creates GitHub Release and pushes to NuGet.org automatically.
Notes
- For migration from v2.x see migration guide.
3.0.0 - 2026-05-09
Breaking Changes
- Package renamed:
Ozakboy.NLOG→OzaLog. The previous package on NuGet is deprecated and points here. See migration guide for the upgrade guide. - Namespace renamed:
ozakboy.LOG→OzaLog. Allusingstatements in consumer code must be updated. - Removed TargetFrameworks: dropped
.NET Framework 4.6.2,net6.0,net7.0(all EOL). Now supportsnetstandard2.0,netstandard2.1,net8.0,net9.0,net10.0. - Enum typo fixed:
LogLevel.CostomName→LogLevel.CustomName. The public methodLOG.CustomName_Log(...)was already correctly named — only the underlying enum value was renamed.
Added
- HFT-grade async pipeline:
ConcurrentQueue<struct LogItem>+ persistent FileStream pool + 1ms cached timestamp + drop-oldest backpressure. LogOptions.EnableGlobalExceptionCapture(defaultfalse) — opt-in subscription toAppDomain.UnhandledExceptionandTaskScheduler.UnobservedTaskException, auto-logs at Fatal level with synchronous immediate flush.LogOptions.MaxOpenFileStreams(default100) — LRU upper bound; exceeding closes the least recently written stream.LogOptions.DiskFlushIntervalMs(default100) — periodicFlush()interval for persistent FileStreams.LogOptions.OnDropped(defaultnull) — callback invoked when the async queue drops the oldest item under backpressure.OzaLog.Tests/— xUnit test project covering concurrency, LRU, day rollover, backpressure, GlobalExceptionCapture toggle, and format correctness.OzaLog.Benchmarks/— BenchmarkDotNet project comparing OzaLog with ZLogger, ZeroLog, and Serilog.MIGRATION.md— upgrade guide fromOzakboy.NLOGv2.x.
Improved
- Zero NuGet dependencies on
net8.0/net9.0/net10.0(System.Text.Json is built into the BCL on these targets). - Formatting work moved off the calling thread — callers only enqueue the raw tuple
(level, name, message, args, ticks, threadId); nostring.Formaton the hot path. - Persistent FileStreams eliminate per-batch open/close, reducing syscall cost to near-zero.
- Day rollover handled inline in the dispatcher (compares cached ticks date vs. stream date).
- Expired-log cleanup moved to a background timer (was on the hot path in v2.x).
Fixed
- Double-format bug in
LOG.cswhereConsole.WriteLine(formattedMessage, args)could throwFormatExceptionif the formatted message coincidentally contained{0}-style tokens. - Auto-flush level selection —
ErrorandFatalnow correctly trigger immediate flush regardless of the caller'simmediateFlushargument.
Technical
LogItemchanged from class toreadonly struct— zero GC on the hot path.- New
Core/TimestampCache.cs— background timer updatesvolatile long _currentTicksevery 1ms; callers only read. - New
Core/FileStreamPool.cs— persistent FileStreams keyed by(level, name)with LRU eviction. - New
Core/LogRetentionCleaner.cs— background expired-log cleanup, off the hot path. - New
Core/GlobalExceptionCapture.cs— opt-in global exception subscription. - Build verified across all 5 TargetFrameworks with 0 warnings / 0 errors.
2.1.0 - 2024
Added
- Added support for .NET 8.0
- Introduced async logging with configurable batch processing
- Added customizable directory structure for different log levels
- Added support for custom log types (
CustomName_Log) - Added console output support
Improved
- Enhanced file management with automatic log rotation
- Enhanced exception handling and serialization
- Improved configuration system with more options
- Better handling of file paths across operating systems
Technical
- Improved thread safety and performance
- Implemented intelligent file size management
History prior to 2.1.0 is not fully tracked here. See git history and the NuGet package page for details.