SPLog is a lightweight logging DLL focused on performance, simplicity, and practical file logging for .NET applications.
GitHub repository: https://github.com/cku3987/SPLog
Targets:
net8.0netstandard2.0
Usable from.NET Framework 4.7.2projects and newer compatible runtimes.
- Simple API
- Fast enough for high-volume application logging
- File logging and console logging out of the box
- External JSON configuration support
- Exception logging support
- Shared error file support
- Daily and hourly rolling
AppendandCreateNewfile conflict handling
using SPLog;
using var logger = SPLogFactory.Create(options =>
{
options.Name = "Core";
options.EnableConsole = true;
options.EnableFile = true;
options.FilePath = "logs";
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff";
});
logger.Information("application started");
logger.Warning("response delay detected");
try
{
RunProcess();
}
catch (Exception ex)
{
logger.Error(ex, "process failed");
}Each logger can keep its own main file while Error and Critical messages are also written to one shared error file:
var sharedErrorFile = new SPLogErrorFileOptions
{
FilePath = "logs/error.log",
MinimumLevel = LogLevel.Error,
FileRollingMode = FileRollingMode.Daily
};
using var moduleALog = SPLogFactory.Create(options =>
{
options.Name = "ModuleA";
options.EnableFile = true;
options.FilePath = "logs/module-a";
options.ErrorFile = sharedErrorFile;
});
using var moduleBLog = SPLogFactory.Create(options =>
{
options.Name = "ModuleB";
options.EnableFile = true;
options.FilePath = "logs/module-b";
options.ErrorFile = sharedErrorFile;
});
moduleALog.Information("module A started");
moduleALog.Error("module A failed");
moduleBLog.Error("module B failed");Result:
module-a/ModuleA_yyyyMMdd.logcontains ModuleA normal logs and errorsmodule-b/ModuleB_yyyyMMdd.logcontains ModuleB normal logs and errorslogs/error_yyyyMMdd.logcontains the ModuleA and ModuleB error lines together
If you want one global logger but still want subsystem names inside the log, create categories from the root logger:
using var appLog = SPLogFactory.Create(options =>
{
options.Name = "App";
options.EnableFile = true;
options.FilePath = "logs";
});
var coreLog = appLog.CreateCategory("Core");
var networkLog = appLog.CreateCategory("Network");
var socketLog = networkLog.CreateCategory("Socket");
coreLog.Information("core started");
networkLog.Warning("network delay detected");
socketLog.Error("socket closed");This keeps one shared queue and one shared writer, while log lines are identified as App.Core, App.Network, and App.Network.Socket.
using var logger = SPLogFactory.CreateFromJsonFile("config/splog.core.json");Example JSON:
{
"Name": "Core",
"MinimumLevel": "Information",
"TimestampFormat": "yyyy-MM-dd HH:mm:ss.fff",
"EnableConsole": false,
"EnableFile": true,
"FilePath": "logs",
"ErrorFile": {
"FilePath": "logs/error.log",
"MinimumLevel": "Error",
"UseUtcTimestamp": false,
"FileConflictMode": "Append",
"FileRollingMode": "Daily",
"MaxFileSizeBytes": 10485760,
"MaxRollingFiles": 14,
"FileBufferSize": 65536
},
"FileConflictMode": "Append",
"FileRollingMode": "Hourly",
"MaxFileSizeBytes": 10485760,
"MaxRollingFiles": 100,
"QueueCapacity": 8192,
"BatchSize": 10,
"FlushIntervalMs": 100,
"FileBufferSize": 65536
}FilePath = "logs"creates<Name>.logautomatically when the first log entry is written- Relative paths are resolved from
AppContext.BaseDirectory - Absolute paths are used as-is
Examples:
Daily + Append->Core_20260331.logDaily + CreateNew->Core_20260331.log, thenCore_20260331_001.logHourly + CreateNew->Core_20260331_13.log, thenCore_20260331_13_001.log
This repository also includes validation helpers:
SPLog.TestsDeterministic correctness checksSPLog.StressRunnerStress, smoke, and long-run validation for one or many loggers at the same timeSPLog.Net472.VerifyReal.NET Framework 4.7.2reference/build/run verification
Recommended commands:
dotnet build SPLog.sln -c Release -m:1
dotnet run --project SPLog.Tests\SPLog.Tests.csproj -c Release --no-build
dotnet run --project SPLog.StressRunner\SPLog.StressRunner.csproj -c Release -- --config codex\SPLog-StressRunner.sample.json
dotnet run --project SPLog.Net472.Verify\SPLog.Net472.Verify.csproj -c ReleaseThe default stress sample includes:
- multiple logger scenarios running at the same time
- one root logger used directly and shared by multiple category scenarios
- additional independent loggers using separate file paths
- a 5-digit stress-run timestamp format for easier timing inspection
- a configuration that is safe to auto-load when launching from Visual Studio
- English guide:
docs/SPLog-Guide-EN.html - Korean guide:
docs/SPLog-Guide-KO.html - Validation guide:
codex/SPLog-Validation-Guide-EN.md
- GitHub: https://github.com/cku3987/SPLog