logfmt.net

Fast, structured logging for .NET in logfmt format

$ dotnet add package logfmt.net click to copy
ts=2026-03-22T03:44:07Z level=info msg="User logged in" user_id=123 service=api
~110ns
per log call
0 alloc
when filtered
โšก

High Performance

Thread-static StringBuilder reuse, cached severity strings, zero-alloc filtered calls. Built for hot paths.

๐Ÿ”Œ

Microsoft.Extensions.Logging

Drop-in ILoggerProvider. One line to wire up with ASP.NET Core, Generic Host, or Minimal APIs.

๐Ÿ“ก

OpenTelemetry

Export OpenTelemetry log records in logfmt format with trace context, attributes, and exceptions.

๐ŸŽฏ

Modern .NET

Targets .NET 8.0 and .NET 10.0. Nullable reference types, file-scoped namespaces, implicit usings.

๐Ÿ”ง

Flexible Output

Console by default, or any Stream. WithData() builder pattern for default fields across log entries.

๐Ÿ›ก๏ธ

Thread Safe

Shared write locks across WithData-derived loggers. Safe for concurrent multi-threaded logging.

Get started in seconds

  Basic Usage
using Logfmt;

var log = new Logger();
log.Info("Server started", "port", "8080");

// Typed values โ€” int, bool, double, etc.
log.Info("Request handled", "status", 200, "ms", 42);

// Default fields on every entry
var svc = new Logger().WithData("service", "api");
svc.Info("Ready");
  ASP.NET Core
using Logfmt.ExtensionLogging;

builder.Logging.ClearProviders();
builder.Logging.AddLogfmt(config =>
{
    config.LogLevel["Default"] = LogLevel.Information;
});

// Then inject and use ILogger as usual
_logger.LogInformation("Processing {RequestId}", id);
  OpenTelemetry
using Logfmt.OpenTelemetryLogging;

builder.Logging.AddOpenTelemetry(options =>
{
    options.AddLogfmtConsoleExporter();
});
  Parsing
using Logfmt;

var pairs = LogfmtParser.Parse(
    "level=info msg=\"hello\" user_id=123");

// pairs[0] = { "level", "info" }
// pairs[1] = { "msg", "hello" }
// pairs[2] = { "user_id", "123" }