From 30eea2618dcc0a43d1d4d764590100c19bd7c05d Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 22 Feb 2008 20:50:30 +0000 Subject: * Implement packet queue statistics * This will show the packets waiting in each queue for each client logged into a region server * These are displayed using 'show stats' on the region command line * This is in pursuit of a memory leak. * This will require a prebuild --- .../Framework/Statistics/SimExtraStatsReporter.cs | 95 ++++++++++++++++++++-- OpenSim/Region/ClientStack/ClientView.cs | 2 +- OpenSim/Region/ClientStack/PacketQueue.cs | 37 ++++++++- 3 files changed, 124 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs index c8b8223..acf2ecb 100644 --- a/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs +++ b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs @@ -26,12 +26,19 @@ * */ +using System; +using System.Collections.Generic; +using System.Text; + using OpenSim.Framework; +using OpenSim.Framework.Statistics.Interfaces; + +using libsecondlife; namespace OpenSim.Framework.Statistics { public class SimExtraStatsReporter - { + { private long assetsInCache; private long texturesInCache; private long assetCacheMemoryUsage; @@ -42,6 +49,12 @@ namespace OpenSim.Framework.Statistics public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } } public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } } + /// + /// Retain a dictionary of all packet queues stats reporters + /// + private IDictionary packetQueueStatsReporters + = new Dictionary(); + public void AddAsset(AssetBase asset) { assetsInCache++; @@ -56,19 +69,87 @@ namespace OpenSim.Framework.Statistics texturesInCache++; textureCacheMemoryUsage += image.Data.Length; } - } + } + + /// + /// Register as a packet queue stats provider + /// + /// An agent LLUUID + /// + public void RegisterPacketQueueStatsProvider(LLUUID uuid, IPullStatsProvider provider) + { + lock (packetQueueStatsReporters) + { + packetQueueStatsReporters[uuid] = new PacketQueueStatsReporter(provider); + } + } + + /// + /// Deregister a packet queue stats provider + /// + /// An agent LLUUID + public void DeregisterPacketQueueStatsProvider(LLUUID uuid) + { + lock (packetQueueStatsReporters) + { + packetQueueStatsReporters.Remove(uuid); + } + } /// /// Report back collected statistical information. /// /// public string Report() - { - return string.Format( + { + StringBuilder sb = new StringBuilder(Environment.NewLine); + sb.Append("PACKET QUEUE STATISTICS"); + sb.Append(Environment.NewLine); + sb.Append( + string.Format( @"Asset cache contains {0,6} assets using {1,10:0.000}K -Texture cache contains {2,6} textures using {3,10:0.000}K", - AssetsInCache, AssetCacheMemoryUsage / 1024.0, - TexturesInCache, TextureCacheMemoryUsage / 1024.0); +Texture cache contains {2,6} textures using {3,10:0.000}K" + Environment.NewLine, + AssetsInCache, AssetCacheMemoryUsage / 1024.0, + TexturesInCache, TextureCacheMemoryUsage / 1024.0)); + + sb.Append(Environment.NewLine); + sb.Append("PACKET QUEUE STATISTICS"); + sb.Append(Environment.NewLine); + sb.Append("Agent UUID "); + sb.Append(" Send In Out Resend "); + sb.Append(" Land Wind Cloud Task Texture Asset"); + sb.Append(Environment.NewLine); + + foreach (LLUUID key in packetQueueStatsReporters.Keys) + { + sb.Append(string.Format("{0}: ", key)); + sb.Append(packetQueueStatsReporters[key].Report()); + sb.Append(Environment.NewLine); + } + + return sb.ToString(); } } + + /// + /// Pull packet queue stats from packet queues and report + /// + public class PacketQueueStatsReporter + { + private IPullStatsProvider m_statsProvider; + + public PacketQueueStatsReporter(IPullStatsProvider provider) + { + m_statsProvider = provider; + } + + /// + /// Report back collected statistical information. + /// + /// + public string Report() + { + return m_statsProvider.GetStats(); + } + } } diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 2cedc81..8bdbe89 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -317,7 +317,7 @@ namespace OpenSim.Region.ClientStack // in it to process. It's an on-purpose threadlock though because // without it, the clientloop will suck up all sim resources. - m_packetQueue = new PacketQueue(); + m_packetQueue = new PacketQueue(agentId); RegisterLocalPacketHandlers(); diff --git a/OpenSim/Region/ClientStack/PacketQueue.cs b/OpenSim/Region/ClientStack/PacketQueue.cs index 06ed32e..4673082 100644 --- a/OpenSim/Region/ClientStack/PacketQueue.cs +++ b/OpenSim/Region/ClientStack/PacketQueue.cs @@ -29,13 +29,16 @@ using System; using System.Collections.Generic; using System.Threading; using System.Timers; +using libsecondlife; using libsecondlife.Packets; using OpenSim.Framework; +using OpenSim.Framework.Statistics; +using OpenSim.Framework.Statistics.Interfaces; using Timer=System.Timers.Timer; namespace OpenSim.Region.ClientStack { - public class PacketQueue + public class PacketQueue : IPullStatsProvider { //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -76,8 +79,10 @@ namespace OpenSim.Region.ClientStack // private long LastThrottle; // private long ThrottleInterval; private Timer throttleTimer; + + private LLUUID m_agentId; - public PacketQueue() + public PacketQueue(LLUUID agentId) { // While working on this, the BlockingQueue had me fooled for a bit. // The Blocking queue causes the thread to stop until there's something @@ -116,6 +121,13 @@ namespace OpenSim.Region.ClientStack // TIMERS needed for this // LastThrottle = DateTime.Now.Ticks; // ThrottleInterval = (long)(throttletimems/throttleTimeDivisor); + + m_agentId = agentId; + + if (StatsManager.SimExtraStats != null) + { + StatsManager.SimExtraStats.RegisterPacketQueueStatsProvider(m_agentId, this); + } } /* STANDARD QUEUE MANIPULATION INTERFACES */ @@ -214,6 +226,11 @@ namespace OpenSim.Region.ClientStack { m_enabled = false; throttleTimer.Stop(); + + if (StatsManager.SimExtraStats != null) + { + StatsManager.SimExtraStats.DeregisterPacketQueueStatsProvider(m_agentId); + } } private void ResetCounters() @@ -483,5 +500,21 @@ namespace OpenSim.Region.ClientStack // effectively wiggling the slider causes things reset ResetCounters(); } + + // See IPullStatsProvider + public string GetStats() + { + return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", + SendQueue.Count(), + IncomingPacketQueue.Count, + OutgoingPacketQueue.Count, + ResendOutgoingPacketQueue.Count, + LandOutgoingPacketQueue.Count, + WindOutgoingPacketQueue.Count, + CloudOutgoingPacketQueue.Count, + TaskOutgoingPacketQueue.Count, + TextureOutgoingPacketQueue.Count, + AssetOutgoingPacketQueue.Count); + } } } -- cgit v1.1