Add an optional mechanism for physics modules to collect and return arbitrary stats.

If active, the physics module can return arbitrary stat counters that can be seen via the MonitoringModule
(http://opensimulator.org/wiki/Monitoring_Module)
This is only active in OdeScene if collect_stats = true in [ODEPhysicsSettings].
This patch allows OdeScene to collect elapsed time information for calls to the ODE native collision methods to assess what proportion of time this takes compared to total physics processing.
This data is returned as ODENativeCollisionFrameMS in the monitoring module, updated every 3 seconds.
The performance effect of collecting stats is probably extremely minor, dwarfed by the rest of the physics code.
This commit is contained in:
Justin Clark-Casey (justincc)
2012-05-31 01:52:26 +01:00
parent bf0b8170f7
commit 0b02a4d42e
6 changed files with 271 additions and 71 deletions

View File

@@ -26,7 +26,7 @@
*/
using System;
//using System.Collections.Generic;
using System.Collections.Generic;
using System.Timers;
using OpenMetaverse.Packets;
using OpenSim.Framework;
@@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes
{
/// <summary>
/// Collect statistics from the scene to send to the client and for access by other monitoring tools.
/// </summary>
/// <remarks>
/// FIXME: This should be a monitoring region module
/// </remarks>
public class SimStatsReporter
{
// 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);
public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
public delegate void SendStatResult(SimStats stats);
@@ -100,6 +108,14 @@ namespace OpenSim.Region.Framework.Scenes
get { return lastReportedSimStats; }
}
/// <summary>
/// Extra sim statistics that are used by monitors but not sent to the client.
/// </summary>
/// <value>
/// The keys are the stat names.
/// </value>
private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>();
// Sending a stats update every 3 seconds-
private int statsUpdatesEveryMS = 3000;
private float statsUpdateFactor = 0;
@@ -334,7 +350,20 @@ namespace OpenSim.Region.Framework.Scenes
}
// Extra statistics that aren't currently sent to clients
LastReportedObjectUpdates = m_objectUpdates / statsUpdateFactor;
lock (m_lastReportedExtraSimStats)
{
m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / statsUpdateFactor;
Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
if (physicsStats != null)
{
foreach (KeyValuePair<string, float> tuple in physicsStats)
{
m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / statsUpdateFactor;
}
}
}
resetvalues();
}
@@ -487,7 +516,10 @@ namespace OpenSim.Region.Framework.Scenes
public void AddPendingDownloads(int count)
{
m_pendingDownloads += count;
if (m_pendingDownloads < 0) m_pendingDownloads = 0;
if (m_pendingDownloads < 0)
m_pendingDownloads = 0;
//m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
}
@@ -509,5 +541,11 @@ namespace OpenSim.Region.Framework.Scenes
}
#endregion
public Dictionary<string, float> GetExtraSimStats()
{
lock (m_lastReportedExtraSimStats)
return new Dictionary<string, float>(m_lastReportedExtraSimStats);
}
}
}