Orleans Dashboard
The Orleans Dashboard provides live inspection of silos, grain activations, calls, reminders, runtime counters, logs, and grain state. It is an administrative surface, not a public application endpoint or a replacement for retained OpenTelemetry data.
Secure the dashboard before exposing it
Section titled “Secure the dashboard before exposing it”Use defense in depth:
- Authenticate operators. Integrate the ASP.NET Core host with your organization’s identity provider. Don’t rely on a hard-to-guess route.
- Authorize the entire route group. Apply a policy to the RouteGroupBuilder returned by
MapOrleansDashboard(). - Restrict the network path. Bind an administrative listener or put the route behind a private ingress, VPN, firewall, or zero-trust access proxy. A route prefix isn’t a security boundary.
- Use HTTPS. Protect credentials, cookies, dashboard responses, and streamed logs in transit.
- Limit sensitive data. Grain state and logs can contain secrets or personal data. Apply normal data classification, retention, and access-audit requirements.
- Disable features you don’t need. Set
HideTrace = truewhen live log streaming isn’t required. Avoid exposing grain-state inspection to operators who don’t need it.
The following example assumes the application has a cookie sign-in flow backed by its identity provider. It protects every dashboard asset and API endpoint with one policy:
builder.Services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie();
builder.Services.AddAuthorization(options =>{ options.AddPolicy("DashboardOperators", policy => { policy.RequireAuthenticatedUser(); policy.RequireRole("OrleansOperator"); });});
builder.UseOrleans(siloBuilder =>{ siloBuilder .UseLocalhostClustering() .AddDashboard(options => { options.HideTrace = true; options.CounterUpdateIntervalMs = 2_000; options.HistoryLength = 100; });});
var app = builder.Build();
app.UseHttpsRedirection();app.UseAuthentication();app.UseAuthorization();
app.MapOrleansDashboard("/dashboard") .RequireAuthorization("DashboardOperators");Validate the authorization behavior with an unauthenticated request and with users inside and outside the operator role. Also check proxy forwarding and route-prefix behavior in the deployed topology.
Install and map the dashboard
Section titled “Install and map the dashboard”Add Microsoft.Orleans.Dashboard to the web host. Microsoft.Orleans.Dashboard.Abstractions contains shared types such as NoProfilingAttribute and is brought in by the main package.
Call ServiceCollectionExtensions.AddDashboard on the silo builder and map the route after building the ASP.NET Core app. A route prefix is recommended to avoid claiming the web application’s root:
builder.UseOrleans(siloBuilder =>{ siloBuilder .UseLocalhostClustering() .AddDashboard();});
var app = builder.Build();
app.MapOrleansDashboard("/dashboard") .RequireAuthorization();The route group includes static dashboard assets and its backing APIs. Apply authentication, authorization, rate limits, headers, and other endpoint conventions to the returned group rather than protecting only the HTML page. Use the policy-based configuration in the preceding secure dashboard example when dashboard access is limited to an operator role.
Configure collection
Section titled “Configure collection”siloBuilder.AddDashboard(options =>{ options.HideTrace = true; options.CounterUpdateIntervalMs = 2_000; options.HistoryLength = 100;});| Option | Default | Operational effect |
|---|---|---|
| HideTrace | false | Disables the live log-streaming endpoint when true. |
| CounterUpdateIntervalMs | 1000 | Sets the counter sampling interval in milliseconds; the minimum is 1000. |
| HistoryLength | 100 | Controls retained in-memory dashboard history. Larger values consume more memory. |
The dashboard registers a logging provider and collects runtime metrics for display. Method profiling adds an incoming grain-call filter. By default, profiling becomes inactive after one minute without dashboard queries. Continuous profiling is available but has ongoing overhead:
builder.Services.Configure<GrainProfilerOptions>(options =>{ options.TraceAlways = true; options.DeactivationTime = TimeSpan.FromMinutes(5);});Leave TraceAlways disabled unless continuous method statistics justify the cost. Load test representative traffic with the dashboard configuration you plan to deploy. Use NoProfilingAttribute on a grain class or method only when omitting it from dashboard method statistics is acceptable.
Choose a deployment boundary
Section titled “Choose a deployment boundary”Co-host with a silo
Section titled “Co-host with a silo”Co-hosting is the simplest setup and gives the dashboard access to local silo services. Put its HTTP route on an administrative network boundary distinct from public application routes. Adding the dashboard to a silo doesn’t itself open an HTTP listener; MapOrleansDashboard() maps endpoints on the ASP.NET Core host.
Use a separate Orleans client host
Section titled “Use a separate Orleans client host”An Orleans client can host the web UI:
dashboardBuilder.UseOrleansClient(clientBuilder =>{ clientBuilder .UseStaticClustering(options => options.Gateways.Add(gatewayAddress)) .AddDashboard();});Every silo must still call AddDashboard() so cluster data and profiling are available. Protect the client host’s route and its network access to gateways. A separate host reduces direct HTTP exposure on silos, but it doesn’t make the dashboard data non-sensitive.
Operate it in production
Section titled “Operate it in production”- Use the dashboard for short-lived interactive diagnosis and OpenTelemetry for durable metrics, traces, logs, alerts, and retention.
- Monitor dashboard request volume, process CPU/memory, and grain-call latency after enabling profiling.
- Keep dashboard and Orleans package versions aligned.
- Audit operator access using the surrounding authentication/proxy platform.
- Don’t paste grain state or live logs into tickets or chats without redaction.
- Disable or remove dashboard mapping in environments where no operational access path is approved.
Troubleshooting
Section titled “Troubleshooting”The dashboard reports lost connectivity
Section titled “The dashboard reports lost connectivity”Confirm the dashboard host has an active Orleans client connection, can resolve/reach advertised gateways, and uses the same cluster/service identifiers and clustering provider as the silos. For a separate host, verify AddDashboard() is also configured on every silo. Follow the client connection runbook.
Profiling data is empty
Section titled “Profiling data is empty”Generate calls to the grain method, keep the page active, and confirm neither the class nor method has NoProfilingAttribute. If TraceAlways is false, profiling stops after DeactivationTime without dashboard queries.
Live logs return 403
Section titled “Live logs return 403”HideTrace = true intentionally disables the trace endpoint. If it is false, check the dashboard authorization policy and the authenticated user’s claims before changing the option.
