Make "abnormal thread terminations" into "ClientLogoutsDueToNoReceives" and add this to the StatsManager
This reflects the actual use of this stat - it hasn't recorded general exceptions for some time. Make the sim extra stats collector draw the data from the stats manager rather than maintaing this data itself.TeleportWork
parent
7eee9eb312
commit
8efe4bfc2e
OpenSim
Framework/Monitoring
Region/ClientStack/Linden/UDP
|
@ -27,6 +27,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
@ -39,8 +40,6 @@ namespace OpenSim.Framework.Monitoring
|
|||
/// </summary>
|
||||
public class SimExtraStatsCollector : BaseStatsCollector
|
||||
{
|
||||
private long abnormalClientThreadTerminations;
|
||||
|
||||
// private long assetsInCache;
|
||||
// private long texturesInCache;
|
||||
// private long assetCacheMemoryUsage;
|
||||
|
@ -73,11 +72,6 @@ namespace OpenSim.Framework.Monitoring
|
|||
private volatile float activeScripts;
|
||||
private volatile float scriptLinesPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// Number of times that a client thread terminated because of an exception
|
||||
/// </summary>
|
||||
public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } }
|
||||
|
||||
// /// <summary>
|
||||
// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
|
||||
// /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these
|
||||
|
@ -166,11 +160,6 @@ namespace OpenSim.Framework.Monitoring
|
|||
private IDictionary<UUID, PacketQueueStatsCollector> packetQueueStatsCollectors
|
||||
= new Dictionary<UUID, PacketQueueStatsCollector>();
|
||||
|
||||
public void AddAbnormalClientThreadTermination()
|
||||
{
|
||||
abnormalClientThreadTerminations++;
|
||||
}
|
||||
|
||||
// public void AddAsset(AssetBase asset)
|
||||
// {
|
||||
// assetsInCache++;
|
||||
|
@ -324,10 +313,12 @@ Asset service request failures: {3}" + Environment.NewLine,
|
|||
sb.Append(Environment.NewLine);
|
||||
sb.Append("CONNECTION STATISTICS");
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append(
|
||||
string.Format(
|
||||
"Abnormal client thread terminations: {0}" + Environment.NewLine,
|
||||
abnormalClientThreadTerminations));
|
||||
|
||||
List<Stat> stats = StatsManager.GetStatsFromEachContainer("clientstack", "ClientLogoutsDueToNoReceives");
|
||||
|
||||
sb.AppendFormat(
|
||||
"Client logouts due to no data receive timeout: {0}\n\n",
|
||||
stats != null ? stats.Sum(s => s.Value).ToString() : "unknown");
|
||||
|
||||
// sb.Append(Environment.NewLine);
|
||||
// sb.Append("INVENTORY STATISTICS");
|
||||
|
@ -338,7 +329,7 @@ Asset service request failures: {3}" + Environment.NewLine,
|
|||
// InventoryServiceRetrievalFailures));
|
||||
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append("FRAME STATISTICS");
|
||||
sb.Append("SAMPLE FRAME STATISTICS");
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS");
|
||||
sb.Append(Environment.NewLine);
|
||||
|
|
|
@ -271,7 +271,7 @@ namespace OpenSim.Framework.Monitoring
|
|||
// Stat name is not unique across category/container/shortname key.
|
||||
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
|
||||
// in a class are run in the same instance of the VM.
|
||||
if (TryGetStat(stat, out category, out container))
|
||||
if (TryGetStatParents(stat, out category, out container))
|
||||
return false;
|
||||
|
||||
// We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
|
||||
|
@ -307,7 +307,7 @@ namespace OpenSim.Framework.Monitoring
|
|||
|
||||
lock (RegisteredStats)
|
||||
{
|
||||
if (!TryGetStat(stat, out category, out container))
|
||||
if (!TryGetStatParents(stat, out category, out container))
|
||||
return false;
|
||||
|
||||
newContainer = new SortedDictionary<string, Stat>(container);
|
||||
|
@ -323,12 +323,67 @@ namespace OpenSim.Framework.Monitoring
|
|||
}
|
||||
}
|
||||
|
||||
public static bool TryGetStats(string category, out SortedDictionary<string, SortedDictionary<string, Stat>> stats)
|
||||
public static bool TryGetStat(string category, string container, string statShortName, out Stat stat)
|
||||
{
|
||||
stat = null;
|
||||
SortedDictionary<string, SortedDictionary<string, Stat>> categoryStats;
|
||||
|
||||
lock (RegisteredStats)
|
||||
{
|
||||
if (!TryGetStatsForCategory(category, out categoryStats))
|
||||
return false;
|
||||
|
||||
SortedDictionary<string, Stat> containerStats;
|
||||
|
||||
if (!categoryStats.TryGetValue(container, out containerStats))
|
||||
return false;
|
||||
|
||||
return containerStats.TryGetValue(statShortName, out stat);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetStatsForCategory(
|
||||
string category, out SortedDictionary<string, SortedDictionary<string, Stat>> stats)
|
||||
{
|
||||
lock (RegisteredStats)
|
||||
return RegisteredStats.TryGetValue(category, out stats);
|
||||
}
|
||||
|
||||
public static bool TryGetStat(
|
||||
/// <summary>
|
||||
/// Get the same stat for each container in a given category.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The stats if there were any to fetch. Otherwise null.
|
||||
/// </returns>
|
||||
/// <param name='category'></param>
|
||||
/// <param name='statShortName'></param>
|
||||
public static List<Stat> GetStatsFromEachContainer(string category, string statShortName)
|
||||
{
|
||||
SortedDictionary<string, SortedDictionary<string, Stat>> categoryStats;
|
||||
|
||||
lock (RegisteredStats)
|
||||
{
|
||||
if (!RegisteredStats.TryGetValue(category, out categoryStats))
|
||||
return null;
|
||||
|
||||
List<Stat> stats = null;
|
||||
|
||||
foreach (SortedDictionary<string, Stat> containerStats in categoryStats.Values)
|
||||
{
|
||||
if (containerStats.ContainsKey(statShortName))
|
||||
{
|
||||
if (stats == null)
|
||||
stats = new List<Stat>();
|
||||
|
||||
stats.Add(containerStats[statShortName]);
|
||||
}
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetStatParents(
|
||||
Stat stat,
|
||||
out SortedDictionary<string, SortedDictionary<string, Stat>> category,
|
||||
out SortedDictionary<string, Stat> container)
|
||||
|
|
|
@ -67,11 +67,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_udpServer.AddScene(scene);
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"ClientLogoutsDueToNoReceives",
|
||||
"Number of times a client has been logged out because no packets were received before the timeout.",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
scene.Name,
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.None,
|
||||
stat => stat.Value = m_udpServer.ClientLogoutsDueToNoReceives,
|
||||
StatVerbosity.Debug));
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"IncomingUDPReceivesCount",
|
||||
"Number of UDP receives performed",
|
||||
"Number of UDP receives performed",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
scene.Name,
|
||||
|
@ -84,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
new Stat(
|
||||
"IncomingPacketsProcessedCount",
|
||||
"Number of inbound LL protocol packets processed",
|
||||
"Number of inbound LL protocol packets processed",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
scene.Name,
|
||||
|
@ -97,7 +110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
new Stat(
|
||||
"OutgoingUDPSendsCount",
|
||||
"Number of UDP sends performed",
|
||||
"Number of UDP sends performed",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
scene.Name,
|
||||
|
@ -149,6 +162,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
|
||||
public const int MTU = 1400;
|
||||
|
||||
/// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
|
||||
public int ClientLogoutsDueToNoReceives { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default packet debug level given to new clients
|
||||
/// </summary>
|
||||
|
@ -1037,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
timeoutTicks = m_pausedAckTimeout;
|
||||
|
||||
if (client.IsActive &&
|
||||
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
|
||||
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > -1)
|
||||
{
|
||||
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
|
||||
// though it's set later on by LLClientView.Close()
|
||||
|
@ -1778,7 +1794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
|
||||
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||
ClientLogoutsDueToNoReceives++;
|
||||
|
||||
if (!client.SceneAgent.IsChildAgent)
|
||||
client.Kick("Simulator logged you out due to connection timeout");
|
||||
|
|
Loading…
Reference in New Issue