Saltar al contenido principal

Observadores de Solicitudes

IRequestObserver se conecta al ciclo de vida de la solicitud — iniciado, completado y fallido — sin modificar el código del handler.

Interfaz

public interface IRequestObserver
{
Task OnStarted(ObservabilityContext context, CancellationToken ct);
Task OnCompleted(ObservabilityContext context, CancellationToken ct);
Task OnFailed(ObservabilityContext context, CancellationToken ct);
}

Implementar un Observador

Observador de Logging

public class LoggingObserver : IRequestObserver
{
private readonly ILogger<LoggingObserver> _logger;

public LoggingObserver(ILogger<LoggingObserver> logger)
{
_logger = logger;
}

public Task OnStarted(ObservabilityContext context, CancellationToken ct)
{
_logger.LogDebug("Iniciando {Request} [{OperationId}]",
context.RequestName, context.OperationId);
return Task.CompletedTask;
}

public Task OnCompleted(ObservabilityContext context, CancellationToken ct)
{
_logger.LogInformation(
"Completado {Request} en {Duration}ms [{OperationId}]",
context.RequestName,
context.Duration.TotalMilliseconds,
context.OperationId);
return Task.CompletedTask;
}

public Task OnFailed(ObservabilityContext context, CancellationToken ct)
{
_logger.LogError(context.Exception,
"Falló {Request} después de {Duration}ms [{OperationId}]",
context.RequestName,
context.Duration.TotalMilliseconds,
context.OperationId);
return Task.CompletedTask;
}
}

Registro

Múltiples observadores pueden registrarse — todos se ejecutan para cada solicitud:

builder.Services.AddObservability();
builder.Services.AddTransient<IRequestObserver, LoggingObserver>();
builder.Services.AddTransient<IRequestObserver, SlowRequestAlertObserver>();
nota

Si un observador lanza una excepción, los demás igualmente se ejecutan. Todas las excepciones se recopilan en un AggregateException. Diseña los observadores para ser resilientes — envuelve su lógica en try/catch si llaman a sistemas externos.