NeonLog.CSharp
0.1.0-ci.58
See the version list below for details.
dotnet add package NeonLog.CSharp --version 0.1.0-ci.58
NuGet\Install-Package NeonLog.CSharp -Version 0.1.0-ci.58
<PackageReference Include="NeonLog.CSharp" Version="0.1.0-ci.58" />
<PackageVersion Include="NeonLog.CSharp" Version="0.1.0-ci.58" />
<PackageReference Include="NeonLog.CSharp" />
paket add NeonLog.CSharp --version 0.1.0-ci.58
#r "nuget: NeonLog.CSharp, 0.1.0-ci.58"
#:package NeonLog.CSharp@0.1.0-ci.58
#addin nuget:?package=NeonLog.CSharp&version=0.1.0-ci.58&prerelease
#tool nuget:?package=NeonLog.CSharp&version=0.1.0-ci.58&prerelease
C# Wrapper for neonlog-c
This directory contains a thin C# P/Invoke wrapper for the native neonlog-c library
(see include/neonlog/neonlog.h). It exposes the full native ABI through managed types, supports structured message templates,
built-in enrichers, log scopes, HTTP request context, Redis and console sinks, and integrates with Microsoft.Extensions.Logging.
Projects
| Project | Target | Description |
|---|---|---|
NeonLog.CSharp |
netstandard2.0 |
Managed wrapper assembly — public API, P/Invoke interop, enrichers, scope, HTTP context. Packed as NuGet with bundled win-x64 and linux-x64 native assets. |
NeonLog.CSharp.Sample |
net8.0 |
Console app that reads appsettings.json and exercises the factory + Redis + ILogger integration. |
NeonLog.CSharp.PackageTests |
net8.0 |
xUnit consumer tests that reference the packed NuGet (not the source project). Run after packing. |
NeonLog.CSharp.Examples |
net8.0 |
Example tour demonstrating every API feature — see examples/ directory. |
Quick start
Build the native library and run the examples:
cmake -S . -B build
cmake --build build --config Debug
# Make neonlog.dll discoverable (add build/Debug/ to PATH, or copy next to the managed exe):
$env:PATH += ";$pwd\build\Debug"
dotnet run --project bindings/dotnet/examples/NeonLog.CSharp.Examples.csproj
API Reference
1. Core Types
NeonLogLevel — log severity (0–5)
| Value | Name | Meaning |
|---|---|---|
| 0 | Verbose |
Detailed diagnostic trace |
| 1 | Debug |
Debugging information |
| 2 | Information |
Normal application progress |
| 3 | Warning |
Potential issue |
| 4 | Error |
Recoverable failure |
| 5 | Fatal |
Unrecoverable / critical |
NeonLogValue — typed log value
Wraps the native neonlog_value_t union. Supports implicit conversions from common .NET types:
NeonLogValue v1 = "hello"; // String
NeonLogValue v2 = -42L; // Int64
NeonLogValue v3 = 42UL; // UInt64
NeonLogValue v4 = 3.14; // Double
NeonLogValue v5 = true; // Bool
NeonLogValue v6 = NeonLogValue.Null; // Null
// Smaller integer types widen automatically:
int i = 123; -> Int64
uint u = 456; -> UInt64
short s = 7; -> Int64
float f = 2.5f; -> Double
NeonLogProperty — named property
new NeonLogProperty("UserName", "Alice")
new NeonLogProperty("Count", 42L)
new NeonLogProperty("Enabled", true)
NeonLogStatus — native operation result
| Value | Meaning |
|---|---|
Ok |
Success |
InvalidArgument |
Null or out-of-range parameter |
OutOfMemory |
Allocation failure |
NotSupported |
Feature not yet implemented |
IoError |
Socket / file error |
NeonLogRedisMode — Redis data structure
| Value | Meaning |
|---|---|
Stream |
XADD (stream, default) |
List |
RPUSH (list) |
2. Runtime: NeonLogRuntime
uint abiVersion = NeonLogRuntime.GetAbiVersion(); // e.g. 3
NeonLogRuntime.EnsureCompatibleAbi(); // throws if mismatch
string statusName = NeonLogRuntime.GetStatusName(status); // "OK", "INVALID_ARGUMENT"...
string levelName = NeonLogRuntime.GetLevelName(level); // "INF", "ERR"...
3. Direct Logger: NeonLogger (simple API)
Create a standalone logger with NeonLogger.Create(NeonLogLoggerOptions):
var options = new NeonLogLoggerOptions
{
MinimumLevel = NeonLogLevel.Debug,
ConsoleEnabled = true,
};
options.Properties.Add(new NeonLogProperty("App", "my-app"));
options.Enrichers.Add(NeonLogBuiltInEnricher.Timestamp);
using var logger = NeonLogger.Create(options);
Log methods:
logger.Log(NeonLogLevel.Information, "Hello {Name}", "world");
logger.Verbose("Verbose {X}", 1);
logger.Debug("Debug {Flag}", true);
logger.Information("User {Name} logged in", "Alice");
logger.Warning("Warning {Value}", 0.95);
logger.Error("Error {Code}", 500, "TimeoutException: ...");
logger.Fatal("Fatal {Reason}", "out of memory");
// With errorMessage (exception detail):
logger.Log(NeonLogLevel.Error, "Query failed for {Id}", "qry-1", "Timeout after 30s");
Other members:
bool enabled = logger.IsEnabled(NeonLogLevel.Debug);
using var child = logger.ForContext(new NeonLogProperty("Scope", "handler"));
using IDisposable scope = logger.BeginScope(new NeonLogProperty("Tenant", "acme"));
logger.Flush();
logger.Dispose();
4. Factory Logger: NeonLoggerFactory (advanced API)
Manages a shared native pipeline (sinks + static properties). Creates multiple loggers from it:
var factoryOptions = new NeonLogLoggerFactoryOptions
{
MinimumLevel = NeonLogLevel.Debug,
};
factoryOptions.Properties.Add(new NeonLogProperty("Application", "my-app"));
factoryOptions.ConsoleSinks.Add(new NeonLogConsoleSinkOptions { Enabled = true, UseColors = true });
factoryOptions.RedisSinks.Add(new NeonLogRedisSinkOptions { Host = "127.0.0.1", Key = "neonlog:app", ... });
using var factory = NeonLoggerFactory.Create(factoryOptions);
using var logger = factory.CreateLogger();
using var child = logger.ForContext(new NeonLogProperty("Scope", "request"));
// Flush at the factory level drains all loggers.
factory.Flush();
NeonLogConsoleSinkOptions
| Property | Type | Default | Description |
|---|---|---|---|
Enabled |
bool |
true |
Enable this sink |
UseColors |
bool |
true |
ANSI color output |
StderrMinLevel |
NeonLogLevel |
Error |
Messages at or above this level go to stderr |
OutputTemplate |
string? |
null |
Custom format, e.g. "[{timestamp}] [{level}] {message}" |
NeonLogRedisSinkOptions
| Property | Type | Default | Description |
|---|---|---|---|
Enabled |
bool |
true |
Enable this sink |
Host |
string |
"127.0.0.1" |
Redis hostname |
Port |
ushort |
6379 |
Redis port |
Password |
string? |
null |
AUTH password |
Database |
int |
0 |
Redis DB index |
Key |
string |
"neonlog" |
List or stream key |
Mode |
NeonLogRedisMode |
Stream |
List (RPUSH) or Stream (XADD) |
StreamMaxLength |
uint |
0 |
Max stream length (0 = no trim) |
TtlSeconds |
uint |
0 |
TTL per entry (0 = no expiry) |
BatchSize |
uint |
1 |
Events per batch flush |
FlushIntervalMilliseconds |
uint |
1000 |
Periodic flush interval |
ConnectTimeoutMilliseconds |
uint |
0 |
Socket connect timeout |
FallbackToConsoleOnFailure |
bool |
false |
Emit to console if Redis unreachable |
MaxBufferedEvents |
uint |
0 |
Buffer cap before dropping (0 = unlimited) |
5. Built-in Enrichers: NeonLogBuiltInEnricher
Enrichers add properties automatically to every log event. There are 4 types:
| Enum Value | Config Name | Properties Added | When Resolved |
|---|---|---|---|
Timestamp |
"Timestamp" |
Timestamp (ISO 8601) |
Per event |
ProcessInfo |
"ProcessInfo" |
ProcessId, MachineName |
Once at plan creation |
Environment |
"Environment" |
Environment (from DOTNET_ENVIRONMENT / ASPNETCORE_ENVIRONMENT / NODE_ENV / "development") |
Once at plan creation |
LogScope |
"LogScope" |
All active scope properties | Per event |
HttpRequest |
"HttpRequest" |
RequestMethod, RequestPath, RequestId, UserAgent, ClientIp, ContentType, Host, Protocol, StatusCode |
Per event |
Usage:
options.Enrichers.Add(NeonLogBuiltInEnricher.Timestamp);
options.Enrichers.Add(NeonLogBuiltInEnricher.ProcessInfo);
options.Enrichers.Add(NeonLogBuiltInEnricher.Environment);
options.Enrichers.Add(NeonLogBuiltInEnricher.LogScope);
options.Enrichers.Add(NeonLogBuiltInEnricher.HttpRequest);
6. Scopes: NeonLogScope
Push ambient properties onto an AsyncLocal stack. Paired with the LogScope enricher.
using (logger.BeginScope(new NeonLogProperty("RequestId", "req-123")))
using (NeonLogScope.Push(new NeonLogProperty("Tenant", "acme")))
{
// Both properties are attached to every log event within this scope.
logger.Information("Processing order {OrderId}", 42);
}
// Run a callback within a scope:
NeonLogScope.Run(new[] { new NeonLogProperty("Scope", "test") }, () =>
{
logger.Information("Inside scope");
});
7. HTTP Request Context: NeonLogHttpRequestContext
Attach HTTP request data to the ambient AsyncLocal context. Requires the HttpRequest enricher.
var request = new NeonLogHttpRequestData
{
RequestMethod = "POST",
RequestPath = "/api/orders",
RequestId = "req-abc",
UserAgent = "MyClient/1.0",
ClientIp = "10.0.0.1",
Host = "example.com",
};
using (NeonLogHttpRequestContext.Enter(request))
{
logger.Information("Processing order");
NeonLogHttpRequestContext.SetStatusCode(200);
}
// Async variant:
await NeonLogHttpRequestContext.RunAsync(request, async () =>
{
logger.Information("Inside async context");
await Task.CompletedTask;
});
8. Configuration from IConfiguration: NeonLogConfigurationOptions
Parse the "NeonLog" config section (appsettings.json, env vars, etc.) into typed options:
var section = config.GetSection("NeonLog");
var options = NeonLogConfigurationOptions.FromConfiguration(section);
var factoryOptions = options.ToFactoryOptions();
Accepts both wrapper-native sections (ConsoleSinks, RedisSinks, Properties, Enrich) and
the original NeonLog compatibility shape (WriteTo, Properties object map, Enrich string array).
Example appsettings.json:
{
"NeonLog": {
"MinimumLevel": { "Default": "Debug" },
"Properties": { "Application": "my-app" },
"Enrich": ["Timestamp", "ProcessInfo", "Environment", "LogScope"],
"ConsoleSinks": [
{
"Enabled": true,
"UseColors": true,
"OutputTemplate": "[{timestamp}] [{level}] {message}"
}
],
"RedisSinks": [
{
"Enabled": false,
"Host": "127.0.0.1",
"Key": "neonlog:app",
"Mode": "Stream"
}
],
"WriteTo": [
{
"Name": "Console",
"Args": { "useColors": "true", "outputTemplate": "[{level}] {message}" }
}
]
}
}
9. Microsoft.Extensions.Logging Integration
Register NeonLog as the standard ILogger<T> provider:
// Option A: from config section
builder.Logging.AddNeonLog(builder.Configuration.GetSection("NeonLog"));
// Option B: from delegate
builder.Logging.AddNeonLog(options =>
{
options.MinimumLevel = NeonLogLevel.Debug;
options.Enrich.Add("Timestamp");
});
// Option C: from factory options directly
builder.Logging.AddNeonLog(factoryOptions);
Mapping from ILogger<T>:
| Microsoft.Extension | Native equivalent |
|---|---|
ILogger<T> category |
SourceContext property |
| Structured message template | Native neonlog_logger_log template + arguments |
BeginScope properties |
Per-event context properties (merged with LogScope enricher) |
EventId.Id |
EventId property |
EventId.Name |
EventName property |
LogLevel.Trace |
Verbose |
LogLevel.Debug |
Debug |
LogLevel.Information |
Information |
LogLevel.Warning |
Warning |
LogLevel.Error |
Error |
LogLevel.Critical |
Fatal |
10. Error Handling
All native operations throw NeonLogException on failure:
try
{
using var logger = NeonLogger.Create(options);
logger.Information("Hello");
}
catch (NeonLogException ex)
{
Console.WriteLine($"Operation failed: {ex.Message}");
Console.WriteLine($"Status code: {ex.Status}");
}
The runtime also validates ABI compatibility at the start of every creation method.
If the loaded native library reports a different ABI version than the wrapper
expects, EnsureCompatibleAbi() throws NotSupportedException.
11. NuGet Packaging
Stage native assets for both platforms, then pack:
# Windows:
./bindings/dotnet/scripts/build-and-stage-native.ps1 -Configuration Release
# Linux:
./bindings/dotnet/scripts/build-and-stage-native.sh Release
# Pack (requires both win-x64 and linux-x64 staged):
dotnet pack bindings/dotnet/NeonLog.CSharp/NeonLog.CSharp.csproj -c Release
The package version defaults to 0.1.0 (from Directory.Build.props). Override with:
dotnet pack ... /p:NeonLogPackageVersion=1.0.0
The pack target fails fast if either native asset is missing.
12. Running Tests
Package consumer tests validate against the packed NuGet (not source):
# After packing:
dotnet test bindings/dotnet/NeonLog.CSharp.PackageTests/NeonLog.CSharp.PackageTests.csproj -c Release
Examples
The examples/ project contains self-contained, runnable examples:
| File | Demonstrates |
|---|---|
Example01_DirectLogger.cs |
Direct logger creation, all level methods, IsEnabled, Flush |
Example02_FactoryLogger.cs |
Factory API, child loggers via ForContext, custom output template |
Example03_AllValueKinds.cs |
All NeonLogValue types and implicit conversions |
Example04_EnrichersAndScopes.cs |
4 built-in enrichers, BeginScope, nested scopes |
Example05_HttpRequestContext.cs |
HttpRequest enricher, Enter, SetStatusCode |
Example06_RedisSink.cs |
Redis List and Stream sink configuration |
Example07_ConfigurationFromJson.cs |
IConfiguration parsing, FromConfiguration, ToFactoryOptions |
Example08_MicrosoftLogging.cs |
Microsoft.Extensions.Logging integration with ILogger<T> |
Run:
dotnet run --project bindings/dotnet/examples/NeonLog.CSharp.Examples.csproj
Build from source
# 1. Build the native library
cmake -S . -B build
cmake --build build --config Debug
# 2. Make neonlog.dll discoverable
$env:PATH += ";$pwd\build\Debug"
# 3. Build and run the sample
dotnet run --project bindings/dotnet/NeonLog.CSharp.Sample/NeonLog.CSharp.Sample.csproj
# 4. Build and run the examples
dotnet run --project bindings/dotnet/examples/NeonLog.CSharp.Examples.csproj
# 5. Stage native assets + pack NuGet (requires .NET 8 SDK)
./bindings/dotnet/scripts/build-and-stage-native.ps1 -Configuration Release
dotnet pack bindings/dotnet/NeonLog.CSharp/NeonLog.CSharp.csproj -c Release
# 6. Run package consumer tests
dotnet test bindings/dotnet/NeonLog.CSharp.PackageTests/NeonLog.CSharp.PackageTests.csproj -c Release
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging (>= 8.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on NeonLog.CSharp:
| Package | Downloads |
|---|---|
|
NeonLog.CSharp.AspNetCore
ASP.NET Core request logging middleware for neonlog-c. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-ci.78 | 33 | 6/8/2026 |
| 0.1.0-ci.75 | 35 | 6/8/2026 |
| 0.1.0-ci.73 | 54 | 6/5/2026 |
| 0.1.0-ci.70 | 55 | 6/5/2026 |
| 0.1.0-ci.66 | 51 | 6/4/2026 |
| 0.1.0-ci.64 | 58 | 6/4/2026 |
| 0.1.0-ci.63 | 46 | 6/4/2026 |
| 0.1.0-ci.61 | 59 | 6/3/2026 |
| 0.1.0-ci.60 | 42 | 6/3/2026 |
| 0.1.0-ci.58 | 49 | 6/3/2026 |
| 0.1.0-ci.55 | 48 | 6/3/2026 |
| 0.1.0-ci.54 | 42 | 6/2/2026 |
| 0.1.0-ci.53 | 38 | 6/2/2026 |
| 0.1.0-ci.51 | 39 | 6/2/2026 |
| 0.1.0-ci.49 | 46 | 6/2/2026 |
| 0.1.0-ci.46 | 41 | 6/2/2026 |
| 0.1.0-ci.40 | 41 | 6/2/2026 |