Section 6 of 6

Logging Best Practices

🎯 What You'll Learn

  • What to log
  • What not to log
  • Log level guidelines
  • Performance considerations
  • Security considerations

What to Log

✅ Do Log:

  • Application start/stop: When the app starts and stops
  • Authentication events: Login, logout, failed attempts
  • Authorization failures: Access denied events
  • Business events: Orders created, payments processed
  • Errors and exceptions: All errors with context
  • Performance issues: Slow queries, timeouts
  • External API calls: Requests and responses
Good Logging Examples C#
_logger.LogInformation("User {UserId} logged in", userId);
_logger.LogWarning("Failed login attempt for {Email}", email);
_logger.LogInformation("Order {OrderId} created for {TotalAmount:C}", orderId, total);
_logger.LogError(ex, "Payment failed for order {OrderId}", orderId);

What NOT to Log

❌ Don't Log:

  • Passwords: Never log passwords or secrets
  • Credit card numbers: PCI compliance violation
  • Personal data: GDPR/privacy concerns
  • API keys/tokens: Security risk
  • Full request/response bodies: May contain sensitive data
Bad Logging Examples (DON'T DO THIS!) C#
// NEVER DO THIS!
_logger.LogInformation("User logged in with password {Password}", password);
_logger.LogInformation("Processing card {CardNumber}", cardNumber);
_logger.LogInformation("API key: {ApiKey}", apiKey);

Log Level Guidelines

Level Use For Example
Trace Detailed debugging Method entry/exit
Debug Development debugging Variable values, query results
Information Normal flow User login, order created
Warning Unexpected but recoverable Low stock, slow query
Error Operation failures Failed to save, API error
Critical Application crashes Database down, out of memory

Performance Considerations

1. Use Structured Logging

Don't use string interpolation - it's evaluated even if logging is disabled.

Performance C#
// ❌ Bad - string interpolation always executes
_logger.LogDebug($"Processing {items.Count} items");

// ✅ Good - only evaluated if Debug is enabled
_logger.LogDebug("Processing {ItemCount} items", items.Count);

2. Avoid Expensive Operations

Guard Expensive Logging C#
if (_logger.IsEnabled(LogLevel.Debug))
{
    var expensiveData = CalculateExpensiveData();
    _logger.LogDebug("Data: {Data}", expensiveData);
}

Security Considerations

  • Sanitize user input: Before logging
  • Mask sensitive data: Credit cards, SSNs
  • Secure log storage: Encrypt logs at rest
  • Limit access: Only authorized users can view logs
  • Log retention: Delete old logs per policy

InvenTrack Best Practices Example

Well-Logged Controller C#
public class OrdersController : Controller
{
    private readonly ILogger<OrdersController> _logger;

    [HttpPost]
    public async Task<IActionResult> Create(Order order)
    {
        _logger.LogInformation(
            "Creating order for customer {CustomerId} with {ItemCount} items",
            order.CustomerId,
            order.Items.Count
        );

        try
        {
            await _orderService.CreateAsync(order);

            _logger.LogInformation(
                "Order {OrderId} created successfully for {TotalAmount:C}",
                order.Id,
                order.TotalAmount
            );

            return Ok(order);
        }
        catch (InsufficientStockException ex)
        {
            _logger.LogWarning(
                "Insufficient stock for product {ProductId} in order {OrderId}",
                ex.ProductId,
                order.Id
            );
            return BadRequest("Insufficient stock");
        }
        catch (Exception ex)
        {
            _logger.LogError(
                ex,
                "Failed to create order for customer {CustomerId}",
                order.CustomerId
            );
            return StatusCode(500);
        }
    }
}

Key Takeaways

  • Log business events: Authentication, orders, payments
  • Never log secrets: Passwords, API keys, credit cards
  • Use structured logging: Better performance
  • Choose appropriate levels: Information for normal flow, Error for failures
  • Guard expensive operations: Use IsEnabled()
  • Secure logs: Encrypt, limit access, retention policy
🎉 Part XV Complete!

Congratulations! You've completed Part XV: Logging. You now understand:

  • ✅ ILogger interface and dependency injection
  • ✅ Six log levels (Trace to Critical)
  • ✅ Built-in providers (Console, Debug, EventSource, EventLog)
  • ✅ Structured logging with message templates
  • ✅ Serilog integration and sinks
  • ✅ Logging best practices (what to log, security, performance)

You can now implement comprehensive logging in your ASP.NET Core applications! 📝