Migration from ILogger
Migration from ILogger
Section titled “Migration from ILogger”This guide covers converting hand-written ILogger usage to generated telemetry interfaces. For the fastest path, use the IDE refactorings — this page documents the manual fallback.
Before
Section titled “Before”using Microsoft.Extensions.Logging;
public class OrderService(ILogger<OrderService> logger){ public void PlaceOrder(int orderId, string customerName) { logger.LogInformation("Placing order {OrderId} for {CustomerName}", orderId, customerName); }
public void CancelOrder(int orderId, Exception ex) { logger.LogError(ex, "Order {OrderId} cancelled", orderId); }}using Purview.Telemetry;
[Logger]public interface IOrderServiceLogs{ [Info("Placing order {OrderId} for {CustomerName}")] void OrderPlaced(int orderId, string customerName);
[Error("Order {OrderId} cancelled")] void OrderCancelled(Exception ex, int orderId);}
public class OrderService(IOrderServiceLogs logger){ public void PlaceOrder(int orderId, string customerName) { logger.OrderPlaced(orderId, customerName); }
public void CancelOrder(int orderId, Exception ex) { logger.OrderCancelled(ex, orderId); }}Register the interface in DI:
services.AddOrderServiceLogs();Log-level mapping
Section titled “Log-level mapping”ILogger call | Generated attribute |
|---|---|
LogTrace(...) | [Trace] |
LogDebug(...) | [Debug] |
LogInformation(...) | [Info] |
LogWarning(...) | [Warning] |
LogError(...) | [Error] |
LogCritical(...) | [Critical] |
Log(LogLevel.X, ...) | [Log(LogLevel.X, ...)] |
Scoped logging
Section titled “Scoped logging”Return IDisposable? from the method to generate a scoped log entry:
[Logger]public interface IOrderServiceLogs{ [Info("Processing order {OrderId}")] IDisposable? ProcessingOrder(int orderId);}LoggerMessage.Define
Section titled “LoggerMessage.Define”Replace a LoggerMessage.Define static field with a generated method:
// Beforestatic readonly Action<ILogger<OrderService>, int, Exception?> _failed = LoggerMessage.Define<int>(LogLevel.Error, 0, "Order {OrderId} failed");
_failed(_logger, orderId, ex);// After[Error("Order {OrderId} failed")]void OrderFailed(int orderId, Exception ex);
logger.OrderFailed(orderId, ex);Structured data
Section titled “Structured data”For collections, use [ExpandEnumerable]; for objects, use [LogProperties] — see Logging Generation v2.
Naming
Section titled “Naming”v4+ converts parameter names to snake_case by default (OpenTelemetry convention). To revert to v3 naming, apply [assembly: TelemetryGeneration(NamingConvention = NamingConvention.Legacy)]. See Naming conventions.
Checklist
Section titled “Checklist”- Add the
Purview.Telemetry.SourceGeneratorpackage andMicrosoft.Extensions.Logging.Abstractions. - Create the
[Logger]interface (or run the ILogger refactoring). - Replace
ILoggermembers and calls with the interface. - Register with
services.Add{InterfaceNameWithoutI}(). - Rebuild and review the Diagnostics.
Next steps
Section titled “Next steps”- Refactorings — the shipped IDE conversions
- Logging — v1/v2 generation modes
- Multi-Targeting — combine with Activities and Metrics