SPLog 1.0.0
See the version list below for details.
dotnet add package SPLog --version 1.0.0
NuGet\Install-Package SPLog -Version 1.0.0
<PackageReference Include="SPLog" Version="1.0.0" />
<PackageVersion Include="SPLog" Version="1.0.0" />
<PackageReference Include="SPLog" />
paket add SPLog --version 1.0.0
#r "nuget: SPLog, 1.0.0"
#:package SPLog@1.0.0
#addin nuget:?package=SPLog&version=1.0.0
#tool nuget:?package=SPLog&version=1.0.0
SPLog Decision Notes
This file is a working record of the decisions made during SPLog development so future sessions can resume quickly.
Current recommended usage patterns
1. Application-lifetime global logger
This is the current primary pattern.
public static class AppLog
{
public static SPLogger Core { get; private set; } = null!;
public static void Initialize()
{
Core = SPLogFactory.Create(options =>
{
options.Name = "Core";
options.EnableFile = true;
options.FilePath = "logs";
});
}
public static void Shutdown()
{
Core.Dispose();
}
}
Summary:
- Create once at app startup
- Reuse globally
- Dispose once at app shutdown
2. Short-lived scoped logger
using var logger = SPLogFactory.Create(options =>
{
options.Name = "Core";
options.EnableFile = true;
options.FilePath = "logs";
});
Summary:
- Use inside a function or short work scope
- Automatically disposes when the scope ends
Dispose rules
Create()starts logging immediately.- There is no separate
Start(). - Always call
Dispose()when the logger will no longer be used. - If you do not dispose it, queued log entries may not be flushed to file.
- Global loggers should be disposed at application shutdown.
- Short-lived loggers should usually use
using var.
Relationship between options and logger instances
SPLogOptionsonly holds configuration values.SPLoggeris the actual runtime logging object.SPLogConfiguration.UpdateFromJsonFile(options, path)updates an existingSPLogOptionsinstance.- Updating an options object does not automatically reconfigure an already-created
SPLogger.
To apply updated settings:
- Dispose the current logger
- Update the options object
- Create a new logger from the updated options
External configuration direction
Currently available APIs:
SPLogFactory.CreateFromJsonFile(path)SPLogConfiguration.LoadFromJson(json)SPLogConfiguration.LoadFromJsonFile(path)SPLogConfiguration.SaveToJson(options)SPLogConfiguration.SaveToJsonFile(options, path)SPLogConfiguration.Update(options)SPLogConfiguration.UpdateFromJson(options, json)SPLogConfiguration.UpdateFromJsonFile(options, path)
Agreed save behavior:
- Saving first normalizes and validates the values
- The normalized values are written to JSON
- The same normalized values are copied back into the original
SPLogOptionsobject in memory
File path rules
- Relative paths are resolved from the executable folder
- The base path is
AppContext.BaseDirectory - Absolute paths are used as-is
- If
FilePath = "logs", SPLog automatically creates<Name>.log - If
FilePath = @"D:\Logs\custom.log", SPLog uses that filename directly
Examples:
Name = "Core",FilePath = "logs"→logs/Core_20260313.logFilePath = @"D:\Logs\custom.log"→D:\Logs\custom_20260313.log
Exception logging direction
Exceptions should use dedicated overloads.
try
{
RunProcess();
}
catch (Exception ex)
{
logger.Error(ex, "process failed");
}
Reasons:
- The format stays consistent
- Exception type, message, stack trace, and
InnerExceptionchain can be written cleanly - Exception logs go to the same targets as normal logs
Logging string usage
Common supported patterns:
logger.Information("application started");
var message = "network connected";
logger.Information(message);
var userId = 1201;
logger.Information($"user connected: {userId}");
logger.Error("request failed");
logger.Error(ex, "request failed");
The earlier interpolation-handler-related call friction was resolved by adding normal string overloads.
Rolling and file conflict handling
Current time-based rolling modes:
FileRollingMode.NoneFileRollingMode.DailyFileRollingMode.Hourly
Current file conflict modes:
FileConflictMode.AppendFileConflictMode.CreateNew
Behavior rules:
- The first file always uses the normal base name
CreateNewonly starts adding_001,_002, and so on when a file for the same period already exists- Size rolling and
CreateNewshare the same sequence numbering
Examples:
Daily + Append- First start:
Core_20260313.log - Next start on the same day: still
Core_20260313.log
- First start:
Daily + CreateNew- First start:
Core_20260313.log - Next start on the same day:
Core_20260313_001.log - Next start after that:
Core_20260313_002.log
- First start:
CreateNewplus size rolloverCore_20260313_001.logCore_20260313_002.logCore_20260313_003.log
Current defaults
Current code defaults:
Name = "SPLog"MinimumLevel = InformationUseUtcTimestamp = falseIncludeThreadId = trueIncludeLoggerName = trueEnableConsole = trueEnableFile = falseFilePath = "logs"FileConflictMode = AppendFileRollingMode = DailyMaxFileSizeBytes = 10485760MaxRollingFiles = 14QueueCapacity = 8192BatchSize = 10FlushIntervalMs = 100FileBufferSize = 65536BlockWhenQueueFull = true
Intent behind current defaults:
BlockWhenQueueFull = trueto prefer log retention over dropping entriesBatchSize = 10for better practical performanceBatchSizemeans maximum batch size, not minimum queued count
Removed or intentionally skipped options
MaxMessageLengthremovedIncludeScopesremovedSingleFilemode intentionally not added for the current project needs
Documentation decisions
Current formats:
- HTML guides
- Markdown guides
RTF decision:
- Removed because of Korean encoding/display issues
- HTML is the Word-friendly replacement
Documentation direction:
- Beginner-friendly explanations
- Default values included
- All choice-based options explained
- Clear distinction between load/save/update configuration APIs
- Exception logging explained
- String logging examples included
Main document paths
Current build output
Release build output:
| Product | Versions 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. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.