Reporting & Monitoring

The OpenSleigh.Reporting package provides ready-to-use ASP.NET Core Minimal API endpoints for querying saga state at runtime. This is useful for building dashboards, debugging distributed workflows, and monitoring saga progress.

Installation

Install the NuGet package:

dotnet add package OpenSleigh.Reporting

Setup

Register the reporting services and map the endpoints in your ASP.NET Core application:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenSleigh(cfg =>
{
    // your transport and persistence configuration
});

builder.Services.AddOpenSleighReporting();

var app = builder.Build();

app.MapOpenSleighReporting(); // default prefix: /opensleigh

app.Run();

You can customize the endpoint prefix:

app.MapOpenSleighReporting("/api/sagas");

REST Endpoints

All endpoints are grouped under the configured prefix (default /opensleigh):

Method Path Description
GET /sagas List saga instances (paginated, with optional filters)
GET /sagas/{instanceId} Get a saga instance by its unique ID
GET /sagas/correlation/{correlationId}?sagaType=... Get a saga instance by correlation ID and saga type
GET /sagas/types List all registered message types with saga handlers

Query Parameters

The list sagas endpoint (GET /sagas) supports the following query parameters:

Parameter Type Default Description
sagaType string? null Filter by saga type name
isCompleted bool? null Filter by completion status
page int 1 Page number (must be ≥ 1)
pageSize int 20 Results per page (1–100)

The get by correlation ID endpoint (GET /sagas/correlation/{correlationId}) requires a sagaType query parameter.

Response Format

The list endpoint returns a PagedResult<SagaInstanceInfo>:

{
  "items": [
    {
      "instanceId": "0193a7e2-...",
      "correlationId": "0193a7e2-...",
      "triggerMessageId": "0193a7e2-...",
      "sagaType": "OrderSaga",
      "sagaStateType": "OrderState",
      "isCompleted": false,
      "isLocked": false,
      "processedMessages": [
        { "messageId": "0193a7e2-...", "when": "2025-01-10T12:00:00Z" }
      ],
      "stateData": { ... }
    }
  ],
  "totalCount": 42,
  "page": 1,
  "pageSize": 20
}

OpenAPI Support

On .NET 9+, AddOpenSleighReporting() automatically registers OpenAPI services, and MapOpenSleighReporting() maps the OpenAPI document endpoint. The generated document is available at /openapi/v1.json.

Security

The reporting endpoints expose saga state data, which may contain sensitive information. Always configure appropriate authentication and authorization middleware before calling MapOpenSleighReporting() in production environments.

For example:

app.UseAuthentication();
app.UseAuthorization();

app.MapOpenSleighReporting()
   .RequireAuthorization();

Example: PizzaTracker Sample

The PizzaTracker sample demonstrates a complete setup with reporting endpoints. It uses in-memory transport and persistence with a pizza order saga that progresses through multiple stages (Received → Preparing → Baking → Quality Check → Out for Delivery → Delivered).

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenSleigh(cfg =>
{
    cfg.UseInMemoryTransport()
       .UseInMemoryPersistence()
       .AddSaga<OrderSaga, OrderState>();
});

builder.Services.AddOpenSleighReporting();

var app = builder.Build();

app.MapOpenSleighReporting();

app.MapPost("/orders", async (PlaceOrderRequest request, IMessageBus bus) =>
{
    var message = new PlaceOrder(request.CustomerName, request.PizzaType);
    await bus.PublishAsync(message);
    return Results.Accepted();
});

app.Run();

After placing an order, use GET /opensleigh/sagas to track its progress through the workflow.