Streamline stat registration code in ServerStats. Remove most of the
usage of ProcessCounters which tend to fail oddly and are not supported everywhere.0.7.4-extended
parent
663809479d
commit
5d187b9b28
|
@ -63,6 +63,7 @@ public class ServerStats : ISharedRegionModule
|
||||||
public readonly string ContainerNetwork = "network";
|
public readonly string ContainerNetwork = "network";
|
||||||
public readonly string ContainerProcess = "process";
|
public readonly string ContainerProcess = "process";
|
||||||
|
|
||||||
|
public string NetworkInterfaceTypes = "Ethernet";
|
||||||
|
|
||||||
readonly int performanceCounterSampleInterval = 500;
|
readonly int performanceCounterSampleInterval = 500;
|
||||||
int lastperformanceCounterSampleTime = 0;
|
int lastperformanceCounterSampleTime = 0;
|
||||||
|
@ -86,20 +87,6 @@ public class ServerStats : ISharedRegionModule
|
||||||
|
|
||||||
PerfCounterControl processorPercentPerfCounter = null;
|
PerfCounterControl processorPercentPerfCounter = null;
|
||||||
|
|
||||||
PerfCounterControl processThreadCountPerfCounter = null;
|
|
||||||
PerfCounterControl processVirtualBytesPerfCounter = null;
|
|
||||||
PerfCounterControl processWorkingSetPerfCounter = null;
|
|
||||||
|
|
||||||
PerfCounterControl dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRMemoryGen0HeapSizePerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRMemoryGen1HeapSizePerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRMemoryGen2HeapSizePerfCounter = null;
|
|
||||||
|
|
||||||
PerfCounterControl dotNETCLRLaTTotalContentionsPerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRLaTContentionsPerSecPerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRLaTLogicalThreadsPerfCounter = null;
|
|
||||||
PerfCounterControl dotNETCLRLaTPhysicalThreadsPerfCounter = null;
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
#region ISharedRegionModule
|
||||||
// IRegionModuleBase.Name
|
// IRegionModuleBase.Name
|
||||||
public string Name { get { return "Server Stats"; } }
|
public string Name { get { return "Server Stats"; } }
|
||||||
|
@ -108,10 +95,15 @@ public class ServerStats : ISharedRegionModule
|
||||||
// IRegionModuleBase.Initialize
|
// IRegionModuleBase.Initialize
|
||||||
public void Initialise(IConfigSource source)
|
public void Initialise(IConfigSource source)
|
||||||
{
|
{
|
||||||
IConfig cnfg = source.Configs["Statistics"];
|
IConfig cfg = source.Configs["Monitoring"];
|
||||||
|
|
||||||
if (cnfg != null)
|
if (cfg != null)
|
||||||
Enabled = cnfg.GetBoolean("Enabled", true);
|
Enabled = cfg.GetBoolean("ServerStatsEnabled", true);
|
||||||
|
|
||||||
|
if (Enabled)
|
||||||
|
{
|
||||||
|
NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// IRegionModuleBase.Close
|
// IRegionModuleBase.Close
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -148,6 +140,13 @@ public class ServerStats : ISharedRegionModule
|
||||||
}
|
}
|
||||||
#endregion ISharedRegionModule
|
#endregion ISharedRegionModule
|
||||||
|
|
||||||
|
private void MakeStat(string pName, string pUnit, string pContainer, Action<Stat> act)
|
||||||
|
{
|
||||||
|
Stat stat = new Stat(pName, pName, "", pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
|
||||||
|
StatsManager.RegisterStat(stat);
|
||||||
|
RegisteredStats.Add(pName, stat);
|
||||||
|
}
|
||||||
|
|
||||||
public void RegisterServerStats()
|
public void RegisterServerStats()
|
||||||
{
|
{
|
||||||
lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
|
lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
|
||||||
|
@ -157,7 +156,7 @@ public class ServerStats : ISharedRegionModule
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tempName = "CPU_Percent";
|
tempName = "CPUPercent";
|
||||||
tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
|
tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
|
||||||
processorPercentPerfCounter = new PerfCounterControl(tempPC);
|
processorPercentPerfCounter = new PerfCounterControl(tempPC);
|
||||||
// A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
|
// A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
|
||||||
|
@ -167,31 +166,17 @@ public class ServerStats : ISharedRegionModule
|
||||||
StatsManager.RegisterStat(tempStat);
|
StatsManager.RegisterStat(tempStat);
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
RegisteredStats.Add(tempName, tempStat);
|
||||||
|
|
||||||
/* Performance counters are not the way to go. Ick. Find another way.
|
MakeStat("TotalProcessorTime", "sec", ContainerProcessor,
|
||||||
tempName = "Thread_Count";
|
(s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
|
||||||
tempPC = new PerformanceCounter("Process", "Thread Count", AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
processThreadCountPerfCounter = new PerfCounterControl(tempPC);
|
|
||||||
tempStat = new Stat("Thread_Count", "Thread_Count", "", "threads", CategoryServer, ContainerProcess,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, processThreadCountPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Virtual_Bytes";
|
MakeStat("UserProcessorTime", "sec", ContainerProcessor,
|
||||||
tempPC = new PerformanceCounter("Process", "Virtual Bytes", AppDomain.CurrentDomain.FriendlyName);
|
(s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
|
||||||
processVirtualBytesPerfCounter = new PerfCounterControl(tempPC);
|
|
||||||
tempStat = new Stat("Virtual_Bytes", "Virtual_Bytes", "", "MB", CategoryServer, ContainerProcess,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, processVirtualBytesPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Working_Set";
|
MakeStat("PrivilegedProcessorTime", "sec", ContainerProcessor,
|
||||||
tempPC = new PerformanceCounter("Process", "Working Set", AppDomain.CurrentDomain.FriendlyName);
|
(s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
|
||||||
processWorkingSetPerfCounter = new PerfCounterControl(tempPC);
|
|
||||||
tempStat = new Stat("Working_Set", "Working_Set", "", "MB", CategoryServer, ContainerProcess,
|
MakeStat("Threads", "threads", ContainerProcessor,
|
||||||
StatType.Pull, (s) => { GetNextValue(s, processWorkingSetPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info);
|
(s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -200,112 +185,33 @@ public class ServerStats : ISharedRegionModule
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* The ".NET CLR *" categories aren't working for me.
|
List<string> okInterfaceTypes = new List<string>(NetworkInterfaceTypes.Split(','));
|
||||||
tempName = ""Bytes_Allocated_Per_Sec";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR Memory", "Allocated Bytes/sec", AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat(tempName, tempName, "", "bytes/sec", ServerCategory, MemoryContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryAllocatedBytesPerSecPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Gen_0_Heap_Size";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 0 heap size", AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
dotNETCLRMemoryGen0HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Gen_0_Heap_Size", "Gen_0_Heap_Size", "", "bytes", ServerCategory, MemoryContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen0HeapSizePerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Gen_1_Heap_Size";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 1 heap size", AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
dotNETCLRMemoryGen1HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Gen_1_Heap_Size", "Gen_1_Heap_Size", "", "bytes", ServerCategory, MemoryContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen1HeapSizePerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Gen_2_Heap_Size";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 2 heap size", AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
dotNETCLRMemoryGen2HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Gen_2_Heap_Size", "Gen_2_Heap_Size", "", "bytes", ServerCategory, MemoryContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen2HeapSizePerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Total_Lock_Contentions";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Total # of Contentions");
|
|
||||||
dotNETCLRLaTTotalContentionsPerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Total_Lock_Contentions", "Total_Lock_Contentions", "", "contentions", ServerCategory, ProcessContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTTotalContentionsPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Lock_Contentions";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Contention Rate / sec");
|
|
||||||
dotNETCLRLaTContentionsPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Lock_Contentions", "Lock_Contentions", "", "contentions/sec", ServerCategory, ProcessContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTContentionsPerSecPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Logical_Threads";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current logical Threads");
|
|
||||||
dotNETCLRLaTLogicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Logicial_Threads", "Logicial_Threads", "", "threads", ServerCategory, ProcessContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTLogicalThreadsPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Physical_Threads";
|
|
||||||
tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current physical Threads");
|
|
||||||
dotNETCLRLaTPhysicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat);
|
|
||||||
tempStat = new Stat("Physical_Threads", "Physical_Threads", "", "threads", ServerCategory, ProcessContainer,
|
|
||||||
StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTPhysicalThreadsPerfCounter); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("{0} Exception creating '.NET CLR Memory': {1}", LogHeader, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces();
|
IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces();
|
||||||
// IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where(
|
|
||||||
// (network) => network.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
|
|
||||||
// IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where(
|
|
||||||
// (network) => network.OperationalStatus == OperationalStatus.Up);
|
|
||||||
|
|
||||||
foreach (NetworkInterface nic in nics)
|
foreach (NetworkInterface nic in nics)
|
||||||
{
|
{
|
||||||
if (nic.OperationalStatus != OperationalStatus.Up || nic.NetworkInterfaceType != NetworkInterfaceType.Ethernet)
|
if (nic.OperationalStatus != OperationalStatus.Up)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
string nicInterfaceType = nic.NetworkInterfaceType.ToString();
|
||||||
|
if (!okInterfaceTypes.Contains(nicInterfaceType))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'. To include, add to [Monitoring]NetworkInterfaceTypes='Ethernet,Loopback'",
|
||||||
|
LogHeader, nic.Name, nicInterfaceType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (nic.Supports(NetworkInterfaceComponent.IPv4))
|
if (nic.Supports(NetworkInterfaceComponent.IPv4))
|
||||||
{
|
{
|
||||||
IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
|
IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
|
||||||
if (nicStats != null)
|
if (nicStats != null)
|
||||||
{
|
{
|
||||||
tempName = "Bytes_Rcvd/" + nic.Name;
|
MakeStat("BytesRcvd/" + nic.Name, "KB", ContainerNetwork,
|
||||||
tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork,
|
(s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
|
||||||
StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info);
|
MakeStat("BytesSent/" + nic.Name, "KB", ContainerNetwork,
|
||||||
StatsManager.RegisterStat(tempStat);
|
(s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
MakeStat("TotalBytes/" + nic.Name, "KB", ContainerNetwork,
|
||||||
|
(s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
|
||||||
tempName = "Bytes_Sent/" + nic.Name;
|
|
||||||
tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork,
|
|
||||||
StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Total_Bytes/" + nic.Name;
|
|
||||||
tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork,
|
|
||||||
StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,30 +221,14 @@ public class ServerStats : ISharedRegionModule
|
||||||
m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
|
m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
tempName = "Process_Memory";
|
MakeStat("ProcessMemory", "MB", ContainerMemory,
|
||||||
tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory,
|
(s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
|
||||||
StatType.Pull, (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }, StatVerbosity.Info);
|
MakeStat("ObjectMemory", "MB", ContainerMemory,
|
||||||
StatsManager.RegisterStat(tempStat);
|
(s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
MakeStat("LastMemoryChurn", "MB/sec", ContainerMemory,
|
||||||
|
(s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
|
||||||
tempName = "Object_Memory";
|
MakeStat("AverageMemoryChurn", "MB/sec", ContainerMemory,
|
||||||
tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory,
|
(s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
|
||||||
StatType.Pull, (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Last_Memory_Churn";
|
|
||||||
tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory,
|
|
||||||
StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
tempName = "Average_Memory_Churn";
|
|
||||||
tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory,
|
|
||||||
StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info);
|
|
||||||
StatsManager.RegisterStat(tempStat);
|
|
||||||
RegisteredStats.Add(tempName, tempStat);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notes on performance counters:
|
// Notes on performance counters:
|
||||||
|
|
Loading…
Reference in New Issue