* 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
afrisby-rexmerge
Justin Clarke Casey 2008-02-22 20:50:30 +00:00
parent e741dcde6a
commit 30eea2618d
4 changed files with 126 additions and 10 deletions

View File

@ -26,12 +26,19 @@
* *
*/ */
using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics.Interfaces;
using libsecondlife;
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Statistics
{ {
public class SimExtraStatsReporter public class SimExtraStatsReporter
{ {
private long assetsInCache; private long assetsInCache;
private long texturesInCache; private long texturesInCache;
private long assetCacheMemoryUsage; private long assetCacheMemoryUsage;
@ -42,6 +49,12 @@ namespace OpenSim.Framework.Statistics
public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } } public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } }
public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } } public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } }
/// <summary>
/// Retain a dictionary of all packet queues stats reporters
/// </summary>
private IDictionary<LLUUID, PacketQueueStatsReporter> packetQueueStatsReporters
= new Dictionary<LLUUID, PacketQueueStatsReporter>();
public void AddAsset(AssetBase asset) public void AddAsset(AssetBase asset)
{ {
assetsInCache++; assetsInCache++;
@ -56,19 +69,87 @@ namespace OpenSim.Framework.Statistics
texturesInCache++; texturesInCache++;
textureCacheMemoryUsage += image.Data.Length; textureCacheMemoryUsage += image.Data.Length;
} }
} }
/// <summary>
/// Register as a packet queue stats provider
/// </summary>
/// <param name="uuid">An agent LLUUID</param>
/// <param name="provider"></param>
public void RegisterPacketQueueStatsProvider(LLUUID uuid, IPullStatsProvider provider)
{
lock (packetQueueStatsReporters)
{
packetQueueStatsReporters[uuid] = new PacketQueueStatsReporter(provider);
}
}
/// <summary>
/// Deregister a packet queue stats provider
/// </summary>
/// <param name="uuid">An agent LLUUID</param>
public void DeregisterPacketQueueStatsProvider(LLUUID uuid)
{
lock (packetQueueStatsReporters)
{
packetQueueStatsReporters.Remove(uuid);
}
}
/// <summary> /// <summary>
/// Report back collected statistical information. /// Report back collected statistical information.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public string Report() 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 @"Asset cache contains {0,6} assets using {1,10:0.000}K
Texture cache contains {2,6} textures using {3,10:0.000}K", Texture cache contains {2,6} textures using {3,10:0.000}K" + Environment.NewLine,
AssetsInCache, AssetCacheMemoryUsage / 1024.0, AssetsInCache, AssetCacheMemoryUsage / 1024.0,
TexturesInCache, TextureCacheMemoryUsage / 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();
} }
} }
/// <summary>
/// Pull packet queue stats from packet queues and report
/// </summary>
public class PacketQueueStatsReporter
{
private IPullStatsProvider m_statsProvider;
public PacketQueueStatsReporter(IPullStatsProvider provider)
{
m_statsProvider = provider;
}
/// <summary>
/// Report back collected statistical information.
/// </summary>
/// <returns></returns>
public string Report()
{
return m_statsProvider.GetStats();
}
}
} }

View File

@ -317,7 +317,7 @@ namespace OpenSim.Region.ClientStack
// in it to process. It's an on-purpose threadlock though because // in it to process. It's an on-purpose threadlock though because
// without it, the clientloop will suck up all sim resources. // without it, the clientloop will suck up all sim resources.
m_packetQueue = new PacketQueue(); m_packetQueue = new PacketQueue(agentId);
RegisterLocalPacketHandlers(); RegisterLocalPacketHandlers();

View File

@ -29,13 +29,16 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
using libsecondlife;
using libsecondlife.Packets; using libsecondlife.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics;
using OpenSim.Framework.Statistics.Interfaces;
using Timer=System.Timers.Timer; using Timer=System.Timers.Timer;
namespace OpenSim.Region.ClientStack 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); //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 LastThrottle;
// private long ThrottleInterval; // private long ThrottleInterval;
private Timer throttleTimer; 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. // While working on this, the BlockingQueue had me fooled for a bit.
// The Blocking queue causes the thread to stop until there's something // The Blocking queue causes the thread to stop until there's something
@ -116,6 +121,13 @@ namespace OpenSim.Region.ClientStack
// TIMERS needed for this // TIMERS needed for this
// LastThrottle = DateTime.Now.Ticks; // LastThrottle = DateTime.Now.Ticks;
// ThrottleInterval = (long)(throttletimems/throttleTimeDivisor); // ThrottleInterval = (long)(throttletimems/throttleTimeDivisor);
m_agentId = agentId;
if (StatsManager.SimExtraStats != null)
{
StatsManager.SimExtraStats.RegisterPacketQueueStatsProvider(m_agentId, this);
}
} }
/* STANDARD QUEUE MANIPULATION INTERFACES */ /* STANDARD QUEUE MANIPULATION INTERFACES */
@ -214,6 +226,11 @@ namespace OpenSim.Region.ClientStack
{ {
m_enabled = false; m_enabled = false;
throttleTimer.Stop(); throttleTimer.Stop();
if (StatsManager.SimExtraStats != null)
{
StatsManager.SimExtraStats.DeregisterPacketQueueStatsProvider(m_agentId);
}
} }
private void ResetCounters() private void ResetCounters()
@ -483,5 +500,21 @@ namespace OpenSim.Region.ClientStack
// effectively wiggling the slider causes things reset // effectively wiggling the slider causes things reset
ResetCounters(); 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);
}
} }
} }

View File

@ -147,6 +147,7 @@
<ReferencePath>../../../bin/</ReferencePath> <ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/> <Reference name="System"/>
<Reference name="libsecondlife.dll"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Files> <Files>
@ -752,6 +753,7 @@
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Communications.Local"/> <Reference name="OpenSim.Region.Communications.Local"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="XMLRPC.dll"/> <Reference name="XMLRPC.dll"/>