Start logging in .NET with ILogger and providers

Use message templates and log levels with Microsoft.Extensions.Logging, select providers, and verify structured fields before collection.

Best practices
Start logging in .NET with ILogger and providers

.NET's Microsoft.Extensions.Logging abstraction gives application code a common logging API while providers control where events go. You can use the built-in providers or integrate a framework such as Serilog, NLog, or log4net. Start with the event fields and destinations you need, then choose the configuration that supplies them.

Key points

  • Console.WriteLine can produce log output, but it does not provide levels, filtering, templates, or timestamp policy by itself.
  • ILogger<T> identifies a logging category and supports six emitted severity levels. Providers are replaceable.
  • Third-party backends add capabilities such as file rotation, specialized destinations, and routing rules. Built-in JSON console logging already supports structured output.
  • Inspect actual serialized events to confirm that template properties, exception details, time, and severity survive collection.

Why a bare console message is limited

Console.WriteLine("User signed in");

This message has no explicit severity, timestamp, or request fields. Console output can be redirected by the host, so its destination is not literally immutable, but WriteLine alone does not supply a configurable logging pipeline. Production analysis benefits from consistent filtering, routing, and parsing.

Use ILogger<T> and LoggerFactory

For a console application, install a compatible Microsoft.Extensions.Logging.Console package. This top-level C# example creates and disposes the logging factory:

using Microsoft.Extensions.Logging;

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole().SetMinimumLevel(LogLevel.Debug);
});

ILogger logger = loggerFactory.CreateLogger<Program>();

logger.LogTrace("Trace message");
logger.LogDebug("Debug message");
logger.LogInformation("Application started");
logger.LogWarning("Configuration missing; using the default");
logger.LogError("Database connection failed");
logger.LogCritical("System-level failure");

The emitted levels are Trace, Debug, Information, Warning, Error, and Critical. None is a filtering value, not an emitted severity. In this example, the Debug threshold filters out the Trace event. Configuration can override thresholds by category and provider.

ASP.NET Core normally obtains loggers through dependency injection:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

public class OrderController : ControllerBase
{
    private readonly ILogger<OrderController> _logger;

    public OrderController(ILogger<OrderController> logger) => _logger = logger;

    public IActionResult Create(int userId)
    {
        _logger.LogInformation("Creating order user={UserId}", userId);
        return Ok();
    }
}

This illustrates logging in an action; the application's route and authentication setup are separate. {UserId} is a message-template property, not string interpolation. It supplies a structured value to the provider. Whether that value appears as a searchable field depends on the provider's formatter and the downstream parser.

Built-in providers include Console, Debug, EventSource, and Windows EventLog. Registering multiple providers, for example builder.AddConsole().AddDebug(), sends events to each enabled provider; the relevant packages must be available.

Compare third-party frameworks

Framework Useful characteristics
Serilog Message templates, object destructuring, JSON formatters, and a wide choice of sinks
NLog XML or code configuration, targets, routing rules, and configurable reload behavior
log4net Logger/appender/layout model, rolling files, contextual properties, and an established ecosystem

Integration packages can route ILogger calls to these frameworks. Switching backends still requires checking package compatibility, levels, formatting, and provider registration; avoid accidentally sending duplicate events through both old and new configurations.

Built-in JSON console output can be sufficient for a service whose platform collects stdout. A third-party file sink or provider is useful when you actually need file rotation or a specialized destination.

Validate structured output and collection

Select a JSON formatter or layout and inspect one event. Confirm that {UserId} is stored as a property rather than only rendered into the message. Configure DataKit file collection with the appropriate path, source, and service when using files.

Use Pipeline parsing to extract JSON fields, parse event time, and map severity to the expected status. Generate an ordinary event and an exception event. Compare time, severity, parameters, and stack trace with the originals before creating error queries or alerts. For trace correlation, verify that the log contains the correct trace identifier as well.

Frequently asked questions

Do console and ASP.NET Core applications use different logging APIs?

They can use the same ILogger abstraction. ASP.NET Core's host configures providers and dependency injection. A console application can create a LoggerFactory directly or use the generic host for similar setup.

What minimum level should I choose?

Information is a common starting point for production, with temporary Debug logging for diagnosis. Decide by category and volume; Trace can be useful selectively but expensive when enabled broadly.

Why avoid interpolation in a message template?

LogInformation("user={id}", id) supplies a property named id, not user. Its searchable path depends on the output schema. $"user={id}" supplies only the rendered string and performs interpolation before the logger filters the event.

Should a new service use built-in logging or Serilog?

Start with the required destinations and event format. ILogger plus JSON console output can be enough. Add Serilog or another backend when its rolling files, sinks, enrichment, or routing solve an actual requirement; keep the application-facing abstraction if that suits the project.

Related reading

See Microsoft's logging overview.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting