diff options
author | Justin Clark-Casey (justincc) | 2013-07-29 23:18:29 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-07-29 23:18:29 +0100 |
commit | 8efe4bfc2ed7086e9fdf4812297e6525f955f6ac (patch) | |
tree | 4899da4147d32f79654aab32f33e7f0754b6144f | |
parent | Groups: Better warning messages to the user. (diff) | |
download | opensim-SC-8efe4bfc2ed7086e9fdf4812297e6525f955f6ac.zip opensim-SC-8efe4bfc2ed7086e9fdf4812297e6525f955f6ac.tar.gz opensim-SC-8efe4bfc2ed7086e9fdf4812297e6525f955f6ac.tar.bz2 opensim-SC-8efe4bfc2ed7086e9fdf4812297e6525f955f6ac.tar.xz |
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.
-rw-r--r-- | OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs | 25 | ||||
-rw-r--r-- | OpenSim/Framework/Monitoring/StatsManager.cs | 65 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 26 |
3 files changed, 89 insertions, 27 deletions
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index 6a68322..f6f458d 100644 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
30 | using System.Text; | 31 | using System.Text; |
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using OpenMetaverse.StructuredData; | 33 | using OpenMetaverse.StructuredData; |
@@ -39,8 +40,6 @@ namespace OpenSim.Framework.Monitoring | |||
39 | /// </summary> | 40 | /// </summary> |
40 | public class SimExtraStatsCollector : BaseStatsCollector | 41 | public class SimExtraStatsCollector : BaseStatsCollector |
41 | { | 42 | { |
42 | private long abnormalClientThreadTerminations; | ||
43 | |||
44 | // private long assetsInCache; | 43 | // private long assetsInCache; |
45 | // private long texturesInCache; | 44 | // private long texturesInCache; |
46 | // private long assetCacheMemoryUsage; | 45 | // private long assetCacheMemoryUsage; |
@@ -73,11 +72,6 @@ namespace OpenSim.Framework.Monitoring | |||
73 | private volatile float activeScripts; | 72 | private volatile float activeScripts; |
74 | private volatile float scriptLinesPerSecond; | 73 | private volatile float scriptLinesPerSecond; |
75 | 74 | ||
76 | /// <summary> | ||
77 | /// Number of times that a client thread terminated because of an exception | ||
78 | /// </summary> | ||
79 | public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } } | ||
80 | |||
81 | // /// <summary> | 75 | // /// <summary> |
82 | // /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the | 76 | // /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the |
83 | // /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these | 77 | // /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these |
@@ -166,11 +160,6 @@ namespace OpenSim.Framework.Monitoring | |||
166 | private IDictionary<UUID, PacketQueueStatsCollector> packetQueueStatsCollectors | 160 | private IDictionary<UUID, PacketQueueStatsCollector> packetQueueStatsCollectors |
167 | = new Dictionary<UUID, PacketQueueStatsCollector>(); | 161 | = new Dictionary<UUID, PacketQueueStatsCollector>(); |
168 | 162 | ||
169 | public void AddAbnormalClientThreadTermination() | ||
170 | { | ||
171 | abnormalClientThreadTerminations++; | ||
172 | } | ||
173 | |||
174 | // public void AddAsset(AssetBase asset) | 163 | // public void AddAsset(AssetBase asset) |
175 | // { | 164 | // { |
176 | // assetsInCache++; | 165 | // assetsInCache++; |
@@ -324,10 +313,12 @@ Asset service request failures: {3}" + Environment.NewLine, | |||
324 | sb.Append(Environment.NewLine); | 313 | sb.Append(Environment.NewLine); |
325 | sb.Append("CONNECTION STATISTICS"); | 314 | sb.Append("CONNECTION STATISTICS"); |
326 | sb.Append(Environment.NewLine); | 315 | sb.Append(Environment.NewLine); |
327 | sb.Append( | 316 | |
328 | string.Format( | 317 | List<Stat> stats = StatsManager.GetStatsFromEachContainer("clientstack", "ClientLogoutsDueToNoReceives"); |
329 | "Abnormal client thread terminations: {0}" + Environment.NewLine, | 318 | |
330 | abnormalClientThreadTerminations)); | 319 | sb.AppendFormat( |
320 | "Client logouts due to no data receive timeout: {0}\n\n", | ||
321 | stats != null ? stats.Sum(s => s.Value).ToString() : "unknown"); | ||
331 | 322 | ||
332 | // sb.Append(Environment.NewLine); | 323 | // sb.Append(Environment.NewLine); |
333 | // sb.Append("INVENTORY STATISTICS"); | 324 | // sb.Append("INVENTORY STATISTICS"); |
@@ -338,7 +329,7 @@ Asset service request failures: {3}" + Environment.NewLine, | |||
338 | // InventoryServiceRetrievalFailures)); | 329 | // InventoryServiceRetrievalFailures)); |
339 | 330 | ||
340 | sb.Append(Environment.NewLine); | 331 | sb.Append(Environment.NewLine); |
341 | sb.Append("FRAME STATISTICS"); | 332 | sb.Append("SAMPLE FRAME STATISTICS"); |
342 | sb.Append(Environment.NewLine); | 333 | sb.Append(Environment.NewLine); |
343 | sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS"); | 334 | sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS"); |
344 | sb.Append(Environment.NewLine); | 335 | sb.Append(Environment.NewLine); |
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index a5b54c9..e6a2304 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs | |||
@@ -271,7 +271,7 @@ namespace OpenSim.Framework.Monitoring | |||
271 | // Stat name is not unique across category/container/shortname key. | 271 | // Stat name is not unique across category/container/shortname key. |
272 | // XXX: For now just return false. This is to avoid problems in regression tests where all tests | 272 | // XXX: For now just return false. This is to avoid problems in regression tests where all tests |
273 | // in a class are run in the same instance of the VM. | 273 | // in a class are run in the same instance of the VM. |
274 | if (TryGetStat(stat, out category, out container)) | 274 | if (TryGetStatParents(stat, out category, out container)) |
275 | return false; | 275 | return false; |
276 | 276 | ||
277 | // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. | 277 | // 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 | |||
307 | 307 | ||
308 | lock (RegisteredStats) | 308 | lock (RegisteredStats) |
309 | { | 309 | { |
310 | if (!TryGetStat(stat, out category, out container)) | 310 | if (!TryGetStatParents(stat, out category, out container)) |
311 | return false; | 311 | return false; |
312 | 312 | ||
313 | newContainer = new SortedDictionary<string, Stat>(container); | 313 | newContainer = new SortedDictionary<string, Stat>(container); |
@@ -323,12 +323,67 @@ namespace OpenSim.Framework.Monitoring | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | public static bool TryGetStats(string category, out SortedDictionary<string, SortedDictionary<string, Stat>> stats) | 326 | public static bool TryGetStat(string category, string container, string statShortName, out Stat stat) |
327 | { | 327 | { |
328 | return RegisteredStats.TryGetValue(category, out stats); | 328 | stat = null; |
329 | SortedDictionary<string, SortedDictionary<string, Stat>> categoryStats; | ||
330 | |||
331 | lock (RegisteredStats) | ||
332 | { | ||
333 | if (!TryGetStatsForCategory(category, out categoryStats)) | ||
334 | return false; | ||
335 | |||
336 | SortedDictionary<string, Stat> containerStats; | ||
337 | |||
338 | if (!categoryStats.TryGetValue(container, out containerStats)) | ||
339 | return false; | ||
340 | |||
341 | return containerStats.TryGetValue(statShortName, out stat); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | public static bool TryGetStatsForCategory( | ||
346 | string category, out SortedDictionary<string, SortedDictionary<string, Stat>> stats) | ||
347 | { | ||
348 | lock (RegisteredStats) | ||
349 | return RegisteredStats.TryGetValue(category, out stats); | ||
350 | } | ||
351 | |||
352 | /// <summary> | ||
353 | /// Get the same stat for each container in a given category. | ||
354 | /// </summary> | ||
355 | /// <returns> | ||
356 | /// The stats if there were any to fetch. Otherwise null. | ||
357 | /// </returns> | ||
358 | /// <param name='category'></param> | ||
359 | /// <param name='statShortName'></param> | ||
360 | public static List<Stat> GetStatsFromEachContainer(string category, string statShortName) | ||
361 | { | ||
362 | SortedDictionary<string, SortedDictionary<string, Stat>> categoryStats; | ||
363 | |||
364 | lock (RegisteredStats) | ||
365 | { | ||
366 | if (!RegisteredStats.TryGetValue(category, out categoryStats)) | ||
367 | return null; | ||
368 | |||
369 | List<Stat> stats = null; | ||
370 | |||
371 | foreach (SortedDictionary<string, Stat> containerStats in categoryStats.Values) | ||
372 | { | ||
373 | if (containerStats.ContainsKey(statShortName)) | ||
374 | { | ||
375 | if (stats == null) | ||
376 | stats = new List<Stat>(); | ||
377 | |||
378 | stats.Add(containerStats[statShortName]); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | return stats; | ||
383 | } | ||
329 | } | 384 | } |
330 | 385 | ||
331 | public static bool TryGetStat( | 386 | public static bool TryGetStatParents( |
332 | Stat stat, | 387 | Stat stat, |
333 | out SortedDictionary<string, SortedDictionary<string, Stat>> category, | 388 | out SortedDictionary<string, SortedDictionary<string, Stat>> category, |
334 | out SortedDictionary<string, Stat> container) | 389 | out SortedDictionary<string, Stat> container) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 25e10be..9e6a401 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -69,9 +69,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
69 | 69 | ||
70 | StatsManager.RegisterStat( | 70 | StatsManager.RegisterStat( |
71 | new Stat( | 71 | new Stat( |
72 | "ClientLogoutsDueToNoReceives", | ||
73 | "Number of times a client has been logged out because no packets were received before the timeout.", | ||
74 | "", | ||
75 | "", | ||
76 | "clientstack", | ||
77 | scene.Name, | ||
78 | StatType.Pull, | ||
79 | MeasuresOfInterest.None, | ||
80 | stat => stat.Value = m_udpServer.ClientLogoutsDueToNoReceives, | ||
81 | StatVerbosity.Debug)); | ||
82 | |||
83 | StatsManager.RegisterStat( | ||
84 | new Stat( | ||
72 | "IncomingUDPReceivesCount", | 85 | "IncomingUDPReceivesCount", |
73 | "Number of UDP receives performed", | 86 | "Number of UDP receives performed", |
74 | "Number of UDP receives performed", | 87 | "", |
75 | "", | 88 | "", |
76 | "clientstack", | 89 | "clientstack", |
77 | scene.Name, | 90 | scene.Name, |
@@ -84,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
84 | new Stat( | 97 | new Stat( |
85 | "IncomingPacketsProcessedCount", | 98 | "IncomingPacketsProcessedCount", |
86 | "Number of inbound LL protocol packets processed", | 99 | "Number of inbound LL protocol packets processed", |
87 | "Number of inbound LL protocol packets processed", | 100 | "", |
88 | "", | 101 | "", |
89 | "clientstack", | 102 | "clientstack", |
90 | scene.Name, | 103 | scene.Name, |
@@ -97,7 +110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
97 | new Stat( | 110 | new Stat( |
98 | "OutgoingUDPSendsCount", | 111 | "OutgoingUDPSendsCount", |
99 | "Number of UDP sends performed", | 112 | "Number of UDP sends performed", |
100 | "Number of UDP sends performed", | 113 | "", |
101 | "", | 114 | "", |
102 | "clientstack", | 115 | "clientstack", |
103 | scene.Name, | 116 | scene.Name, |
@@ -149,6 +162,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
149 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> | 162 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> |
150 | public const int MTU = 1400; | 163 | public const int MTU = 1400; |
151 | 164 | ||
165 | /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary> | ||
166 | public int ClientLogoutsDueToNoReceives { get; private set; } | ||
167 | |||
152 | /// <summary> | 168 | /// <summary> |
153 | /// Default packet debug level given to new clients | 169 | /// Default packet debug level given to new clients |
154 | /// </summary> | 170 | /// </summary> |
@@ -1037,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1037 | timeoutTicks = m_pausedAckTimeout; | 1053 | timeoutTicks = m_pausedAckTimeout; |
1038 | 1054 | ||
1039 | if (client.IsActive && | 1055 | if (client.IsActive && |
1040 | (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) | 1056 | (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > -1) |
1041 | { | 1057 | { |
1042 | // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even | 1058 | // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even |
1043 | // though it's set later on by LLClientView.Close() | 1059 | // though it's set later on by LLClientView.Close() |
@@ -1778,7 +1794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1778 | "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", | 1794 | "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", |
1779 | client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); | 1795 | client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); |
1780 | 1796 | ||
1781 | StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); | 1797 | ClientLogoutsDueToNoReceives++; |
1782 | 1798 | ||
1783 | if (!client.SceneAgent.IsChildAgent) | 1799 | if (!client.SceneAgent.IsChildAgent) |
1784 | client.Kick("Simulator logged you out due to connection timeout"); | 1800 | client.Kick("Simulator logged you out due to connection timeout"); |