Logging records what an application does so you can investigate problems later. An error message helps identify a failure; messages from earlier requests can reveal how the application reached it. Logs can also record events for auditing or analytics, such as a user signing in or an API method being called. For a production application, configure a durable destination: console output alone can disappear when the window closes or the server restarts. section 26.1 section 26.6
ASP.NET Core already logs parts of a request, including the requested URL and, where applicable, the Razor Page handler and EF Core database command. Add your own message when business context would make a problem clearer. If a requested recipe does not exist, for example, log both that fact and the requested ID rather than relying on request logs to reveal it. section 26.1.1
Each message has details that help you find and interpret it:
- A log level expresses importance. Use Information for normal activity and Warning for an unexpected condition you can handle; Error and Critical mark more serious failures. Debug and Trace provide finer detail, with Trace potentially exposing sensitive information. section 26.2.1
- A category identifies the component producing the message. Injecting ILogger<T> normally uses T as the category; inject ILoggerFactory when you need to create a logger with a custom category. section 26.2.2
- Named placeholders retain values as searchable data as well as rendering them in the message. In "Loaded {RecipeCount} recipes", the count is supplied separately and matched to the placeholder by position. section 26.2 section 26.6
Listing 26.2 Injecting ILogger into a class and writing a log message
public class IndexModel : PageModel
{
private readonly RecipeService _service;
private readonly ILogger<IndexModel> _log; #1
public ICollection<RecipeSummaryViewModel> Recipes { get; set; }
public IndexModel(
RecipeService service,
ILogger<IndexModel> log) #1
{
_service = service;
_log = log; #1
}
public void OnGet()
{
Recipes = _service.GetRecipes();
_log.LogInformation( #2
"Loaded {RecipeCount} recipes", Recipes.Count); #2
}
}
#1 Injects the generic ILogger<T> using DI, which implements ILogger
#2 Writes an Information-level log. The RecipeCount variable is substituted in the message.
This small Razor Page example injects ILogger<IndexModel> and writes an Information-level message after loading recipes. The named placeholder records the recipe count without putting logging setup inside the page handler. section 26.2
Write messages through ILogger rather than choosing an output location in application code. Logging providers determine where they go; a logger created by ILoggerFactory can send a message to every configured provider. The console and debug providers are added by WebApplicationBuilder, and additional providers can be configured. Filtering controls verbosity, typically retaining fewer low-importance messages in production than in development. section 26.1.2 section 26.6
Logs are useful only if someone notices them. For a medium-size or large application, a monitoring service such as Sentry or Datadog can notify you of problems instead of requiring you to inspect logs regularly. section 26.1







































