Serilog — .NET 6 / 7 / 8 / 9 / 10

The LogInformant.Serilog.DotNetCore NuGet package adds a Serilog sink that batches and ships your logs to LogInformant automatically. Works with ASP.NET Core and any .NET 6+ console or worker app.

1 Install
bash
dotnet add package Serilog.AspNetCore
dotnet add package LogInformant.Serilog.DotNetCore
2 Configure in Program.cs

Replace the default logging with Serilog and point it at LogInformant:

csharp
using Serilog;

var builder = WebApplication.CreateBuilder(args);

// Set up Serilog
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console()
    .WriteTo.LogInformant(
        apiUrl: "https://app.loginformant.com",
        apiKey: builder.Configuration["LogInformant:ApiKey"]!)
    .Enrich.FromLogContext()
    .CreateLogger();

builder.Host.UseSerilog();

var app = builder.Build();
// ... rest of your middleware
app.Run();
3 Store the API key safely

Add to appsettings.json (or use environment variables / secrets):

json
{
  "LogInformant": {
    "ApiKey": "YOUR-API-KEY-HERE"
  }
}
In production, set the key via an environment variable: LogInformant__ApiKey=your-key-here (double underscore maps to the nested JSON path).
4 Log messages in your code

Inject ILogger<T> as normal — nothing changes in how you write logs:

csharp
public class OrderService
{
    private readonly ILogger<OrderService> _logger;

    public OrderService(ILogger<OrderService> logger)
    {
        _logger = logger;
    }

    public void PlaceOrder(int orderId)
    {
        _logger.LogInformation("Order {OrderId} placed", orderId);

        try
        {
            // ... your order logic
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to place order {OrderId}", orderId);
        }
    }
}
5 Verify in the dashboard

Start your app and make a request. Open the dashboard, filter to your application, and confirm the new events appear. If your subscription includes real-time streaming, you can also verify them in the live stream view.

Advanced options

Minimum level per sink

Only send Warning and above to LogInformant (keep verbose logs local):

csharp
.WriteTo.LogInformant(
    apiUrl: "https://app.loginformant.com",
    apiKey: config["LogInformant:ApiKey"]!,
    restrictedToMinimumLevel: LogEventLevel.Warning)

Configure via appsettings.json

Install Serilog.Settings.Configuration then add:

json
{
  "Serilog": {
    "Using": ["LogInformant.Serilog.DotNetCore"],
    "MinimumLevel": "Information",
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "LogInformant",
        "Args": {
          "apiUrl": "https://app.loginformant.com",
          "apiKey": "YOUR-API-KEY"
        }
      }
    ],
    "Enrich": ["FromLogContext"]
  }
}

Batching behaviour

Logs are batched automatically (up to 50 per batch, flushed every 2 seconds). The batch period and size are controlled by the underlying Serilog PeriodicBatching sink. You can customise them:

csharp
.WriteTo.LogInformant(
    apiUrl:  "https://app.loginformant.com",
    apiKey:  "YOUR-API-KEY",
    batchSizeLimit: 100,
    period: TimeSpan.FromSeconds(5))

Optional enrichers & sinks

These community packages slot right into your LoggerConfiguration and make every log event that reaches LogInformant significantly richer — with zero changes to your application code.

Serilog.Enrichers.Environment

Adds the machine name and environment name to every log event. Especially useful when you run multiple instances of an app (containers, load-balanced servers) and need to know which node generated a log.

bash
dotnet add package Serilog.Enrichers.Environment
csharp
Log.Logger = new LoggerConfiguration()
    .Enrich.WithMachineName()          // adds MachineName property
    .Enrich.WithEnvironmentName()      // adds EnvironmentName property (e.g. "Production")
    .Enrich.FromLogContext()
    .WriteTo.LogInformant(apiUrl: "...", apiKey: "...")
    .CreateLogger();
In LogInformant, filter by MachineName to isolate one node's logs during a production incident, or chart error rates by EnvironmentName across environments.

Serilog.Enrichers.ClientInfo

Adds the client IP address and browser User-Agent to every log event generated during an HTTP request. Useful for tracing which user or system triggered an error.

bash
dotnet add package Serilog.Enrichers.ClientInfo
csharp
Log.Logger = new LoggerConfiguration()
    .Enrich.WithClientIp()             // adds ClientIp property
    .Enrich.WithClientAgent()          // adds ClientAgent (User-Agent) property
    .Enrich.FromLogContext()
    .WriteTo.LogInformant(apiUrl: "...", apiKey: "...")
    .CreateLogger();

Note: ClientInfo requires access to IHttpContextAccessor. Register it in DI before configuring Serilog:

csharp — Program.cs
builder.Services.AddHttpContextAccessor(); // add this line
builder.Host.UseSerilog();

Serilog.Enrichers.HttpContext

The most comprehensive HTTP enricher — adds request path, method, query string, response status code, elapsed time, and the authenticated username to every log event. Excellent for correlating logs with specific requests.

bash
dotnet add package Serilog.Enrichers.HttpContext
csharp
Log.Logger = new LoggerConfiguration()
    .Enrich.WithHttpRequestId()        // adds a unique ID per request
    .Enrich.WithHttpRequestPath()      // adds RequestPath (e.g. /api/orders/42)
    .Enrich.WithHttpRequestMethod()    // adds RequestMethod (GET, POST, etc.)
    .Enrich.WithHttpRequestQuery()     // adds RequestQuery string
    .Enrich.WithUserName()             // adds UserName (authenticated identity)
    .Enrich.FromLogContext()
    .WriteTo.LogInformant(apiUrl: "...", apiKey: "...")
    .CreateLogger();
Combine WithHttpRequestId() with LogInformant's search to pull up every log line from a single request in one click — even across multiple services.

Serilog.Sinks.Http

A general-purpose Serilog sink that POSTs batched log events to any HTTP endpoint as JSON. If you already use Serilog.Sinks.Http and prefer to configure sinks via appsettings.json rather than a dedicated package, you can point it directly at the LogInformant ingest endpoint:

bash
dotnet add package Serilog.Sinks.Http
json — appsettings.json
{
  "Serilog": {
    "Using": ["Serilog.Sinks.Http"],
    "WriteTo": [
      {
        "Name": "Http",
        "Args": {
          "requestUri": "https://app.loginformant.com/api/ingest/batch",
          "httpClient": "Serilog.Sinks.Http.HttpClients.JsonHttpClient",
          "batchFormatter": "Serilog.Sinks.Http.BatchFormatters.ArrayBatchFormatter"
        }
      }
    ]
  }
}
Tip: LogInformant.Serilog.DotNetCore (our dedicated package) is the recommended approach — it handles the API key header, correct JSON field names, and level mapping automatically. Use Serilog.Sinks.Http only if you have a specific reason to prefer a config-file-only setup.

Putting it all together

A full Program.cs using all four packages:

csharp — Program.cs
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpContextAccessor(); // required for ClientInfo + HttpContext enrichers

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    // Enrichers — bolt-on context for every log event
    .Enrich.FromLogContext()
    .Enrich.WithMachineName()
    .Enrich.WithEnvironmentName()
    .Enrich.WithClientIp()
    .Enrich.WithClientAgent()
    .Enrich.WithHttpRequestId()
    .Enrich.WithHttpRequestPath()
    .Enrich.WithHttpRequestMethod()
    .Enrich.WithUserName()
    // Sinks
    .WriteTo.Console()
    .WriteTo.LogInformant(
        apiUrl: "https://app.loginformant.com",
        apiKey: builder.Configuration["LogInformant:ApiKey"]!)
    .CreateLogger();

builder.Host.UseSerilog();

var app = builder.Build();
app.Run();

Log level mapping

SerilogLogInformant
VerboseDebug
DebugDebug
InformationInformation
WarningWarning
ErrorError
FatalFatal