Microsoft Orleans — Dashboard Update — CPU/Memory Stats

February 23rd 2019
Orleans Logo

Quick update to a post I did a while back regarding Orleans Dashboard — additional reporting metrics for your cluster!

As a refresher, Orleans is a virtual actor model framework — a framework that can be used to build new, distributed “primitives”. These primitives’ work can be farmed out to a cluster of nodes as a means of getting “work” done faster than what would be possible if working constrained to a single piece of hardware.

In a previous post:

I had pointed out:

Currently CPU/Memory usage is not visible from the .net core implementation of Orleans. Hopefully something will be done to remedy that in the future? Perhaps it’s a limitation of the API available in netstandard?

This ***seems*** to have been true at a point in time, but it is no longer! (At least if you’re running in a windows runtime.)

The additional CPU and memory metrics are completely dependant on a registered IHostEnvironmentStatistics implementation. By default, a “NoImplementation” implementation is registered, and you would see something like this in your Orleans log:

Orleans log showing an issue that prevents LoadShedding from working

And this on your dashboard:

Sad Orleans Dashboard w/o CPU/Memory metrics :(

The whole reason I stumbled across getting these CPU/Memory metrics working on the dashboard, was I was pursuing getting the feature LoadShedding to work — which was apparently dependant on these metrics.

Through some back and forth on the Orleans Gitter I found out about the needed registered implementation of an IHostEnvironmentStatistics class. One of these classes does exist in the Orleans code, though it’s in a separate package, and an internal only class to that package:

Luckily, there is a SiloHost extension method that registers this implementation of IHostEnvironmentStatistics for use — albeit from a Windows only runtime environment (at least at the time of writing).

To get the CPU/Memory metrics work on our dashboard (and putting us in a position to work in LoadShedding) we need to do a few things:

  • Install a new NuGet package
  • Register an implementation of IHostEnvironmentStatistics — like the one provided in the NuGet package itself.

Install the NuGet Package

The IHostEnvironmentStatistics implementation exists within the Microsoft.Orleans.OrleansTelemetryConsumers.Counters package, install it via the GUI, CLI, etc. The csproj file from the SiloHost project should look something like this when done:

csproj after installing the NuGet package Microsoft.Orleans.OrleansTelemetryConsumers.Counters

Registering the implementation of IHostEnvironmentStatistics

As previously mentioned, the new NuGet package has a Windows specific implementation of IHostEnvironmentStatistics contained within it, although it is an internal class. There is however, an extension method that can be used to register that internal class.

Let’s update our SiloHostBuilder:

Original

var builder = new SiloHostBuilder()
.ConfigureClustering(
ServiceProvider.GetService<IOptions<OrleansConfig>>(),
Startup.HostingEnvironment.EnvironmentName
)
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
})
.Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
.AddMemoryGrainStorage(Constants.OrleansMemoryProvider)
.ConfigureApplicationParts(parts =>
{
parts.AddApplicationPart(typeof(IGrainMarker).Assembly).WithReferences();
})
.ConfigureServices(DependencyInjectionHelper.IocContainerRegistration)
.UseDashboard(options => { })
.UseInMemoryReminderService()
.ConfigureLogging(logging => logging.AddConsole());

And we just need to add .UsePerfCounterEnvironmentStatistics().

Updated

var builder = new SiloHostBuilder()
.ConfigureClustering(
ServiceProvider.GetService<IOptions<OrleansConfig>>(),
Startup.HostingEnvironment.EnvironmentName
)
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "HelloWorldApp";
})
.Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
.AddMemoryGrainStorage(Constants.OrleansMemoryProvider)
.ConfigureApplicationParts(parts =>
{
parts.AddApplicationPart(typeof(IGrainMarker).Assembly).WithReferences();
})
.ConfigureServices(DependencyInjectionHelper.IocContainerRegistration)
.UsePerfCounterEnvironmentStatistics() // <- this guy
.UseDashboard(options => { })
.UseInMemoryReminderService()
.ConfigureLogging(logging => logging.AddConsole());

That’s all there is to it! Now, we should get our CPU/Memory utilization reported on the Orleans Dashboard, and be in a better position to work in LoadShedding — perhaps for the next post!

Now, looking at our dashboard, we can see:

CPU/Memory utilization!

More by Russell Hammett Jr. (Kritner)

More Related Stories