Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved Performance Counters to its own Telemetry Consumer #2122

Merged
merged 7 commits into from
Sep 12, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ The idea is to track end-user facing changes as they occur.*
- Updated Azure Storage dependency to 7.0.0 #1968
- A new ADO.NET storage provider that is significantly easier to setup, which replaces the the previous one. This change is not backwards compatible and does not support sharding
(likely be replaced later with Orleans sharding provider). The most straightforward migration plan is likely to persist the state classes from Orleans application code.
More information in [#1682](https://github.com/dotnet/orleans/pull/1682) and in [#1682 (comment)](https://github.com/dotnet/orleans/pull/1682#issuecomment-234371701).
More information in [#1682](https://github.com/dotnet/orleans/pull/1682) and in [#1682 (comment)](https://github.com/dotnet/orleans/pull/1682#issuecomment-234371701).
- Added new Amazon AWS basic Orleans providers [#2006](https://github.com/dotnet/orleans/issues/2006)
- Moved Orleans Performance Counters into its own Telemetry Consumer. Now you need to explicitly register the `OrleansPerfCounterTelemetryConsumer` either by code or XML. More information in [#2122](https://github.com/dotnet/orleans/pull/2122) and docs will come later
- `Microsoft.Orleans.CounterControl` Nuget package is deprecated. When installing the new `Microsoft.Orleans.OrleansTelemetryConsumers.Counters` which contains the telemetry consumer, you can find `OrleansCounterControl.exe` under the `tools\` directory at the packages folder.
- `OrleansCounterControl.exe` usage remain the same


### [v1.2.3]
- Ability to force creation of Orleans serializers for types not marked with [Serializable] by using GenerateSerializer, KnownType or KnownAssembly.TreatTypesAsSerializable #1888 #1864 #1855
Expand Down
10 changes: 5 additions & 5 deletions src/OrleansCounterControl/CounterControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ internal class CounterControl
public bool IsRunningAsAdministrator { get; private set; }
public bool PauseAtEnd { get; private set; }

private static PerfCounterTelemetryConsumer perfCounterConsumer;
private static OrleansPerfCounterTelemetryConsumer perfCounterConsumer;

public CounterControl()
{
// Check user is Administrator and has granted UAC elevation permission to run this app
var userIdent = WindowsIdentity.GetCurrent();
var userPrincipal = new WindowsPrincipal(userIdent);
IsRunningAsAdministrator = userPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
perfCounterConsumer = new PerfCounterTelemetryConsumer(true);
perfCounterConsumer = new OrleansPerfCounterTelemetryConsumer();
}

public void PrintUsage()
Expand Down Expand Up @@ -162,7 +162,7 @@ private static void RegisterWindowsPerfCounters(bool useBruteForce)
{
try
{
if (PerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
if (OrleansPerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
{
if (!useBruteForce)
{
Expand All @@ -183,7 +183,7 @@ private static void RegisterWindowsPerfCounters(bool useBruteForce)
// Register perf counters
perfCounterConsumer.InstallCounters();

if (PerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
if (OrleansPerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
ConsoleText.WriteStatus("Orleans counters registered successfully");
else
ConsoleText.WriteError("Orleans counters are NOT registered");
Expand All @@ -202,7 +202,7 @@ private static void RegisterWindowsPerfCounters(bool useBruteForce)
/// <remarks>Note: Program needs to be running as Administrator to be able to unregister Windows perf counters.</remarks>
private static void UnregisterWindowsPerfCounters(bool useBruteForce)
{
if (!PerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
if (!OrleansPerfCounterTelemetryConsumer.AreWindowsPerfCountersAvailable())
{
ConsoleText.WriteStatus("Orleans counters are already unregistered");
return;
Expand Down
61 changes: 4 additions & 57 deletions src/OrleansRuntime/Counters/OrleansCounterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,11 @@ namespace Orleans.Runtime.Counters
{
internal static class OrleansCounterManager
{
private static readonly Logger logger = LogManager.GetLogger("OrleansPerfCounterManager", LoggerType.Runtime);
//private static readonly List<Tuple<StatisticName, bool>> counterNames = new List<Tuple<StatisticName, bool>>();

//public static void PrecreateCounters()
//{
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_COLLECTION_NUMBER_OF_COLLECTIONS, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_COLLECTION, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_DEACTIVATE_ON_IDLE, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_DIRECT_SHUTDOWN, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.DIRECTORY_CACHE_SIZE, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.DIRECTORY_LOOKUPS_FULL_ISSUED, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_ISSUED, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_SUCCESSES, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.DIRECTORY_PARTITION_SIZE, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.GATEWAY_CONNECTED_CLIENTS, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.GATEWAY_LOAD_SHEDDING, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.GATEWAY_RECEIVED, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MEMBERSHIP_ACTIVE_CLUSTER_SIZE, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MESSAGING_SENT_BYTES_TOTAL, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MESSAGING_SENT_MESSAGES_TOTAL, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MESSAGING_SENT_LOCALMESSAGES, true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_OK_PER_DIRECTION,
// Message.Directions.OneWay.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_OK_PER_DIRECTION,
// Message.Directions.Request.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_OK_PER_DIRECTION,
// Message.Directions.Response.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_ERRORS_PER_DIRECTION,
// Message.Directions.OneWay.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_ERRORS_PER_DIRECTION,
// Message.Directions.Request.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_PROCESSED_ERRORS_PER_DIRECTION,
// Message.Directions.Response.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_RECEIVED_PER_DIRECTION,
// Message.Directions.OneWay.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_RECEIVED_PER_DIRECTION,
// Message.Directions.Request.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(new StatisticName(StatisticNames.MESSAGING_DISPATCHER_RECEIVED_PER_DIRECTION,
// Message.Directions.Response.ToString()), true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MESSAGE_CENTER_RECEIVE_QUEUE_LENGTH, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.MESSAGE_CENTER_SEND_QUEUE_LENGTH, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.SCHEDULER_PENDINGWORKITEMS, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_COUNT, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.CATALOG_ACTIVATION_DUPLICATE_ACTIVATIONS, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.RUNTIME_GC_TOTALMEMORYKB, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_WORKERTHREADS, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_COMPLETIONPORTTHREADS, false));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.STORAGE_READ_TOTAL, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.STORAGE_WRITE_TOTAL, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.STORAGE_ACTIVATE_TOTAL, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.STORAGE_READ_ERRORS, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.STORAGE_WRITE_ERRORS, true));
// counterNames.Add(new Tuple<StatisticName, bool>(StatisticNames.AZURE_SERVER_BUSY, true));
//}
private static readonly Logger logger = LogManager.GetLogger("OrleansCounterManager", LoggerType.Runtime);

public static int WriteCounters()
{
if (logger.IsVerbose) logger.Verbose("Writing Windows perf counters.");
if (logger.IsVerbose) logger.Verbose("Writing counters.");

int numWriteErrors = 0;

Expand All @@ -73,7 +20,7 @@ public static int WriteCounters()

try
{
if (logger.IsVerbose3) logger.Verbose3(ErrorCode.PerfCounterWriting, "Writing perf counter {0}", perfCounterName);
if (logger.IsVerbose3) logger.Verbose3(ErrorCode.PerfCounterWriting, "Writing counter {0}", perfCounterName);

if (cd.CounterStat == null)
{
Expand All @@ -88,7 +35,7 @@ public static int WriteCounters()
catch (Exception ex)
{
numWriteErrors++;
logger.Error(ErrorCode.PerfCounterUnableToWrite, string.Format("Unable to write to Windows perf counter '{0}'", name), ex);
logger.Error(ErrorCode.PerfCounterUnableToWrite, string.Format("Unable to write to counter '{0}'", name), ex);
}
}
return numWriteErrors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,67 @@

namespace OrleansTelemetryConsumers.Counters
{
public class PerfCounterTelemetryConsumer : IMetricTelemetryConsumer
public class OrleansPerfCounterTelemetryConsumer : IMetricTelemetryConsumer
{
internal const string CATEGORY_NAME = "OrleansRuntime";
internal const string CATEGORY_DESCRIPTION = "Orleans Runtime Counters";
private const string CounterControlProgName = "OrleansCounterControl.exe";
private const string ExplainHowToCreateOrleansPerfCounters = "Run " + CounterControlProgName + " as Administrator to create perf counters for Orleans.";

private static readonly Logger logger = LogManager.GetLogger("OrleansPerfCounterManager", LoggerType.Runtime);
private readonly List<PerfCounterConfigData> perfCounterData = new List<PerfCounterConfigData>();

public PerfCounterTelemetryConsumer(bool installMode = false)
private static readonly List<PerfCounterConfigData> perfCounterData = new List<PerfCounterConfigData>();
private static bool isInstalling = false;
private readonly Lazy<bool> isInitialized = new Lazy<bool>(() =>
{
if (!AreWindowsPerfCountersAvailable())
{
logger.Warn(ErrorCode.PerfCounterNotFound, "Windows perf counters not found -- defaulting to in-memory counters. " + ExplainHowToCreateOrleansPerfCounters);
return;
}

GetCounterData(installMode);

foreach (var cd in perfCounterData)
try
{
var perfCounterName = GetPerfCounterName(cd);
cd.PerfCounter = CreatePerfCounter(perfCounterName);
}
}
perfCounterData.Clear();

#region Counter Management methods

private void GetCounterData(bool installMode)
{
perfCounterData.Clear();
// (1) Start with list of static counters
perfCounterData.AddRange(PerfCounterConfigData.StaticPerfCounters);

// (1) Start with list of static counters
perfCounterData.AddRange(PerfCounterConfigData.StaticPerfCounters);
if (GrainTypeManager.Instance != null && GrainTypeManager.Instance.GrainClassTypeData != null)
{
// (2) Then search for grain DLLs and pre-create activation counters for any grain types found
var loadedGrainClasses = GrainTypeManager.Instance.GrainClassTypeData;
foreach (var grainClass in loadedGrainClasses)
{
var counterName = new StatisticName(StatisticNames.GRAIN_COUNTS_PER_GRAIN, grainClass.Key);
perfCounterData.Add(new PerfCounterConfigData
{
Name = counterName,
UseDeltaValue = false
});
}
}

if (!installMode)
{
// (2) Then search for grain DLLs and pre-create activation counters for any grain types found
var loadedGrainClasses = GrainTypeManager.Instance.GrainClassTypeData;
foreach (var grainClass in loadedGrainClasses)
if (!isInstalling)
{
var counterName = new StatisticName(StatisticNames.GRAIN_COUNTS_PER_GRAIN, grainClass.Key);
perfCounterData.Add(new PerfCounterConfigData
foreach (var cd in perfCounterData)
{
Name = counterName,
UseDeltaValue = false
});
var perfCounterName = GetPerfCounterName(cd);
cd.PerfCounter = CreatePerfCounter(perfCounterName);
}
}

return true;
}
catch
{
return false;
}
}, true);

public OrleansPerfCounterTelemetryConsumer()
{
if (!AreWindowsPerfCountersAvailable())
{
logger.Warn(ErrorCode.PerfCounterNotFound, "Windows perf counters not found -- defaulting to in-memory counters. " + ExplainHowToCreateOrleansPerfCounters);
}
}

#region Counter Management methods

public static bool AreWindowsPerfCountersAvailable()
{
try
Expand All @@ -79,20 +88,19 @@ public static bool AreWindowsPerfCountersAvailable()
return false;
}

private PerformanceCounter CreatePerfCounter(string perfCounterName)
private static PerformanceCounter CreatePerfCounter(string perfCounterName)
{
logger.Verbose(ErrorCode.PerfCounterRegistering, "Creating perf counter {0}", perfCounterName);
return new PerformanceCounter(CATEGORY_NAME, perfCounterName, false);
}

private string GetPerfCounterName(PerfCounterConfigData cd)
private static string GetPerfCounterName(PerfCounterConfigData cd)
{
return cd.Name.Name + "." + (cd.UseDeltaValue ? "Delta" : "Current");
}

internal CounterCreationData[] GetCounterCreationData()
{
GetCounterData(false);
var ctrCreationData = new List<CounterCreationData>();
foreach (PerfCounterConfigData cd in perfCounterData)
{
Expand All @@ -113,6 +121,14 @@ internal CounterCreationData[] GetCounterCreationData()
/// <remarks>Note: Program needs to be running as Administrator to be able to delete Windows perf counters.</remarks>
public void InstallCounters()
{
isInstalling = true;
if (!isInitialized.Value)
{
var msg = "Unable to install Windows Performance counters";
logger.Warn(ErrorCode.PerfCounterNotFound, msg);
throw new InvalidOperationException(msg);
}

var collection = new CounterCreationDataCollection();
collection.AddRange(GetCounterCreationData());

Expand Down Expand Up @@ -159,23 +175,18 @@ public void Close() { }

private void WriteMetric(string name, UpdateMode mode = UpdateMode.Increment, double? value = null)
{
if (!isInitialized.Value)
return;

PerfCounterConfigData cd = GetCounter(name);
if (cd == null)
{
if (logger.IsVerbose) logger.Verbose(ErrorCode.PerfCounterNotFound, "No perf counter found for {0}", name);
return;
}

StatisticName statsName = cd.Name;
string perfCounterName = GetPerfCounterName(cd);

try
{
if (cd.PerfCounter == null)
{
if (logger.IsVerbose) logger.Verbose(ErrorCode.PerfCounterUnableToConnect, "No perf counter found for {0}", name);
cd.PerfCounter = CreatePerfCounter(perfCounterName);
}

if (logger.IsVerbose3) logger.Verbose3(ErrorCode.PerfCounterWriting, "Writing perf counter {0}", perfCounterName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public OrleansPerformanceCounterInstaller()
{
using (var myPerformanceCounterInstaller = new PerformanceCounterInstaller())
{
myPerformanceCounterInstaller.CategoryName = PerfCounterTelemetryConsumer.CATEGORY_NAME;
myPerformanceCounterInstaller.CategoryName = OrleansPerfCounterTelemetryConsumer.CATEGORY_NAME;
myPerformanceCounterInstaller.CategoryType = PerformanceCounterCategoryType.MultiInstance;
var consumer = new PerfCounterTelemetryConsumer();
var consumer = new OrleansPerfCounterTelemetryConsumer();
myPerformanceCounterInstaller.Counters.AddRange(consumer.GetCounterCreationData());
Installers.Add(myPerformanceCounterInstaller);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="PerfCounterConfigData.cs" />
<Compile Include="PerfCounterTelemetryConsumer.cs" />
<Compile Include="OrleansPerfCounterTelemetryConsumer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
Loading