29 using System.Collections.Generic;
31 using System.Threading;
32 using OpenMetaverse.Packets;
33 using OpenSim.Framework;
34 using OpenSim.Framework.Monitoring;
35 using OpenSim.Region.Framework.Interfaces;
37 namespace OpenSim.
Region.Framework.Scenes
47 private static readonly log4net.ILog m_log
48 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
50 public const string LastReportedObjectUpdateStatName =
"LastReportedObjectUpdates";
51 public const string SlowFramesStatName =
"SlowFrames";
53 public delegate
void SendStatResult(
SimStats stats);
55 public delegate
void YourStatsAreWrong();
61 private SendStatResult handlerSendStatResult;
63 private YourStatsAreWrong handlerStatsIncorrect;
67 private const int m_statisticViewerArraySize = 38;
69 private const int m_statisticExtraArraySize = (int)(
Stats.SimExtraCountEnd -
Stats.SimExtraCountStart);
97 LSLScriptLinesPerSecond = 16,
98 InPacketsPerSecond = 17,
99 OutPacketsPerSecond = 18,
100 PendingDownloads = 19,
104 PendingLocalUploads = 23,
106 PhysicsPinnedTasks = 25,
107 PhysicsLodTasks = 26,
108 SimPhysicsStepMs = 27,
109 SimPhysicsShapeMs = 28,
110 SimPhysicsOtherMs = 29,
111 SimPhysicsMemory = 30,
116 SimPCTSscriptsRun = 35,
118 SimRegionIdlePossible = 37,
119 SimAIStepTimeMS = 38,
120 SimSkippedSillouet_PS = 39,
121 SimSkippedCharsPerC = 40,
124 SimExtraCountStart = 1000,
126 internalLSLScriptLinesPerSecond = 1000,
127 FrameDilation2 = 1001,
128 UsersLoggingIn = 1002,
133 SimExtraCountEnd = 1006
139 public float LastReportedSimFPS
141 get {
return lastReportedSimFPS; }
151 public float LastReportedObjectUpdates {
get;
private set; }
153 public float[] LastReportedSimStats
155 get {
return lastReportedSimStats; }
161 public Stat SlowFramesStat {
get;
private set; }
166 public int SlowFramesStatReportThreshold {
get;
private set; }
174 private Dictionary<string, float> m_lastReportedExtraSimStats =
new Dictionary<string, float>();
177 private int m_statsUpdatesEveryMS = 3000;
178 private double m_lastUpdateTS;
179 private double m_prevFrameStatsTS;
180 private double m_FrameStatsTS;
181 private float m_timeDilation;
184 private object m_statsLock =
new object();
185 private object m_statsFrameLock =
new object();
200 private float m_statisticsFPSfactor = 5.0f;
201 private float m_targetFrameTime = 0.1f;
203 private float lastReportedSimFPS;
204 private float[] lastReportedSimStats =
new float[m_statisticExtraArraySize + m_statisticViewerArraySize];
205 private float m_pfps;
210 private int m_agentUpdates;
215 private int m_objectUpdates;
217 private float m_frameMS;
219 private float m_netMS;
220 private float m_agentMS;
221 private float m_physicsMS;
222 private float m_imageMS;
223 private float m_otherMS;
224 private float m_sleeptimeMS;
225 private float m_scriptTimeMS;
227 private int m_rootAgents;
228 private int m_childAgents;
229 private int m_numPrim;
230 private int m_numGeoPrim;
231 private int m_numMesh;
232 private int m_inPacketsPerSecond;
233 private int m_outPacketsPerSecond;
234 private int m_activePrim;
235 private int m_unAckedBytes;
236 private int m_pendingDownloads;
237 private int m_pendingUploads = 0;
238 private int m_activeScripts;
239 private int m_scriptLinesPerSecond;
240 private int m_scriptEventsPerSecond;
242 private int m_objectCapacity = 45000;
245 private int m_usersLoggingIn;
249 private int m_inUseThreads;
251 private Scene m_scene;
255 private System.Timers.Timer m_report =
new System.Timers.Timer();
266 m_statisticsFPSfactor = 55.0f * m_scene.FrameTime;
268 m_statisticsFPSfactor = 1.0f;
270 m_targetFrameTime = 1000.0f * m_scene.FrameTime / m_statisticsFPSfactor;
272 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
273 m_report.AutoReset =
true;
274 m_report.Interval = m_statsUpdatesEveryMS;
275 m_report.Elapsed += TriggerStatsHeartbeat;
276 m_report.Enabled =
true;
278 m_lastUpdateTS = Util.GetTimeStampMS();
279 m_FrameStatsTS = m_lastUpdateTS;
280 m_prevFrameStatsTS = m_lastUpdateTS;
282 if (StatsManager.SimExtraStats != null)
283 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
287 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.FrameTime * 1000 * 1.2);
293 "Number of frames where frame time has been significantly longer than the desired frame time.",
301 StatsManager.RegisterStat(SlowFramesStat);
307 m_report.Elapsed -= TriggerStatsHeartbeat;
317 m_statsUpdatesEveryMS = ms;
318 m_report.Interval = m_statsUpdatesEveryMS;
321 private void TriggerStatsHeartbeat(
object sender, EventArgs args)
325 statsHeartBeat(sender, args);
329 m_log.Warn(string.Format(
330 "[SIM STATS REPORTER] Update for {0} failed with exception ",
331 m_scene.RegionInfo.RegionName), e);
335 private void statsHeartBeat(
object sender, EventArgs e)
342 if(Monitor.TryEnter(m_statsLock))
346 SimStatsPacket.StatBlock[] sb =
new SimStatsPacket.StatBlock[m_statisticViewerArraySize];
347 SimStatsPacket.StatBlock[] sbex =
new SimStatsPacket.StatBlock[m_statisticExtraArraySize];
348 SimStatsPacket.RegionBlock rb =
new SimStatsPacket.RegionBlock();
349 uint regionFlags = 0;
353 if (estateModule == null)
354 estateModule = m_scene.RequestModuleInterface<
IEstateModule>();
355 regionFlags = estateModule != null ? estateModule.GetRegionFlags() : (uint) 0;
362 #region various statistic googly moogly
363 double timeTmp = m_lastUpdateTS;
364 m_lastUpdateTS = Util.GetTimeStampMS();
365 float updateElapsed = (float)((m_lastUpdateTS - timeTmp)/1000.0);
368 float updateTimeFactor = 1.0f / updateElapsed;
380 float totalFrameTime;
382 float invFrameElapsed;
385 lock(m_statsFrameLock)
387 timeDilation = m_timeDilation;
391 physicsMS = m_physicsMS;
393 sleeptime = m_sleeptimeMS;
394 scriptTimeMS = m_scriptTimeMS;
395 totalFrameTime = m_frameMS;
397 invFrameElapsed = (float)((m_FrameStatsTS - m_prevFrameStatsTS) / 1000.0);
402 if (invFrameElapsed / updateElapsed < 0.8)
405 invFrameElapsed = updateTimeFactor;
407 invFrameElapsed = 1.0f / invFrameElapsed;
409 float perframefactor;
410 if (reportedFPS <= 0)
414 perframefactor = 1.0f;
419 timeDilation /= reportedFPS;
420 reportedFPS *= m_statisticsFPSfactor;
421 perframefactor = 1.0f / (float)reportedFPS;
422 reportedFPS *= invFrameElapsed;
423 physfps *= invFrameElapsed * m_statisticsFPSfactor;
427 if(physfps > reportedFPS)
428 physfps = reportedFPS;
431 lastReportedSimFPS = reportedFPS;
435 totalFrameTime *= perframefactor;
436 sleeptime *= perframefactor;
437 otherMS *= perframefactor;
438 physicsMS *= perframefactor;
439 agentMS *= perframefactor;
440 scriptTimeMS *= perframefactor;
444 sparetime = m_targetFrameTime - (physicsMS + agentMS + otherMS);
448 else if (sparetime > totalFrameTime)
449 sparetime = totalFrameTime;
453 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
454 m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
455 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
456 m_numGeoPrim = m_scene.SceneGraph.GetTotalPrimObjectsCount();
457 m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount();
458 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
459 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
460 m_scriptLinesPerSecond = m_scene.SceneGraph.GetScriptLPS();
466 for (
int i = 0; i < m_statisticViewerArraySize; i++)
468 sb[i] =
new SimStatsPacket.StatBlock();
471 sb[0].StatID = (uint) Stats.TimeDilation;
472 sb[0].StatValue = (Single.IsNaN(timeDilation)) ? 0.0f : (
float)Math.Round(timeDilation,3);
474 sb[1].StatID = (uint) Stats.SimFPS;
475 sb[1].StatValue = (
float)Math.Round(reportedFPS,1);;
477 sb[2].StatID = (uint) Stats.PhysicsFPS;
478 sb[2].StatValue = (
float)Math.Round(physfps,1);
480 sb[3].StatID = (uint) Stats.AgentUpdates;
481 sb[3].StatValue = m_agentUpdates * updateTimeFactor;
483 sb[4].StatID = (uint) Stats.Agents;
484 sb[4].StatValue = m_rootAgents;
486 sb[5].StatID = (uint) Stats.ChildAgents;
487 sb[5].StatValue = m_childAgents;
489 sb[6].StatID = (uint) Stats.TotalPrim;
490 sb[6].StatValue = m_numPrim;
492 sb[7].StatID = (uint) Stats.ActivePrim;
493 sb[7].StatValue = m_activePrim;
495 sb[8].StatID = (uint)Stats.FrameMS;
496 sb[8].StatValue = totalFrameTime;
498 sb[9].StatID = (uint)Stats.NetMS;
499 sb[9].StatValue = m_netMS * perframefactor;
501 sb[10].StatID = (uint)Stats.PhysicsMS;
502 sb[10].StatValue = physicsMS;
504 sb[11].StatID = (uint)Stats.ImageMS ;
505 sb[11].StatValue = m_imageMS * perframefactor;
507 sb[12].StatID = (uint)Stats.OtherMS;
508 sb[12].StatValue = otherMS;
510 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
511 sb[13].StatValue = (
float)Math.Round(m_inPacketsPerSecond * updateTimeFactor);
513 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
514 sb[14].StatValue = (
float)Math.Round(m_outPacketsPerSecond * updateTimeFactor);
516 sb[15].StatID = (uint)Stats.UnAckedBytes;
517 sb[15].StatValue = m_unAckedBytes;
519 sb[16].StatID = (uint)Stats.AgentMS;
520 sb[16].StatValue = agentMS;
522 sb[17].StatID = (uint)Stats.PendingDownloads;
523 sb[17].StatValue = m_pendingDownloads;
525 sb[18].StatID = (uint)Stats.PendingUploads;
526 sb[18].StatValue = m_pendingUploads;
528 sb[19].StatID = (uint)Stats.ActiveScripts;
529 sb[19].StatValue = m_activeScripts;
531 sb[20].StatID = (uint)Stats.SimSleepMs;
532 sb[20].StatValue = sleeptime;
534 sb[21].StatID = (uint)Stats.SimSpareMs;
535 sb[21].StatValue = sparetime;
538 sb[22].StatID = (uint)Stats.SimPhysicsStepMs;
539 sb[22].StatValue = 20;
544 sb[23].StatID = (uint)Stats.VirtualSizeKb;
545 sb[23].StatValue = 0;
547 sb[24].StatID = (uint)Stats.ResidentSizeKb;
548 sb[24].StatValue = 0;
550 sb[25].StatID = (uint)Stats.PendingLocalUploads;
551 sb[25].StatValue = 0;
553 sb[26].StatID = (uint)Stats.PhysicsPinnedTasks;
554 sb[26].StatValue = 0;
556 sb[27].StatID = (uint)Stats.PhysicsLodTasks;
557 sb[27].StatValue = 0;
559 sb[28].StatID = (uint)Stats.ScriptEps;
560 sb[28].StatValue = (float)Math.Round(m_scriptEventsPerSecond * updateTimeFactor);
562 sb[29].StatID = (uint)Stats.SimAIStepTimeMS;
563 sb[29].StatValue = 0;
565 sb[30].StatID = (uint)Stats.SimIoPumpTime;
566 sb[30].StatValue = 0;
568 sb[31].StatID = (uint)Stats.SimPCTSscriptsRun;
569 sb[31].StatValue = 0;
571 sb[32].StatID = (uint)Stats.SimRegionIdle;
572 sb[32].StatValue = 0;
574 sb[33].StatID = (uint)Stats.SimRegionIdlePossible;
575 sb[33].StatValue = 0;
577 sb[34].StatID = (uint)Stats.SimSkippedSillouet_PS;
578 sb[34].StatValue = 0;
580 sb[35].StatID = (uint)Stats.SimSkippedCharsPerC;
581 sb[35].StatValue = 0;
583 sb[36].StatID = (uint)Stats.SimPhysicsMemory;
584 sb[36].StatValue = 0;
586 sb[37].StatID = (uint)Stats.ScriptMS;
587 sb[37].StatValue = scriptTimeMS;
589 for (
int i = 0; i < m_statisticViewerArraySize; i++)
591 lastReportedSimStats[i] = sb[i].StatValue;
597 for (
int i = 0; i < m_statisticExtraArraySize; i++)
599 sbex[i] =
new SimStatsPacket.StatBlock();
602 sbex[0].StatID = (uint)Stats.LSLScriptLinesPerSecond;
603 sbex[0].StatValue = m_scriptLinesPerSecond * updateTimeFactor;
604 lastReportedSimStats[38] = m_scriptLinesPerSecond * updateTimeFactor;
606 sbex[1].StatID = (uint)Stats.FrameDilation2;
607 sbex[1].StatValue = (Single.IsNaN(timeDilation)) ? 0.1f : timeDilation;
608 lastReportedSimStats[39] = (Single.IsNaN(timeDilation)) ? 0.1f : timeDilation;
610 sbex[2].StatID = (uint)Stats.UsersLoggingIn;
611 sbex[2].StatValue = m_usersLoggingIn;
612 lastReportedSimStats[40] = m_usersLoggingIn;
614 sbex[3].StatID = (uint)Stats.TotalGeoPrim;
615 sbex[3].StatValue = m_numGeoPrim;
616 lastReportedSimStats[41] = m_numGeoPrim;
618 sbex[4].StatID = (uint)Stats.TotalMesh;
619 sbex[4].StatValue = m_numMesh;
620 lastReportedSimStats[42] = m_numMesh;
622 sbex[5].StatID = (uint)Stats.ThreadCount;
623 sbex[5].StatValue = m_inUseThreads;
624 lastReportedSimStats[43] = m_inUseThreads;
628 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)m_objectCapacity,
629 rb, sb, sbex, m_scene.RegionInfo.originRegionID);
631 handlerSendStatResult = OnSendStatsResult;
632 if (handlerSendStatResult != null)
634 handlerSendStatResult(simStats);
638 if (m_scene.PhysicsScene != null)
640 lock (m_lastReportedExtraSimStats)
642 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates * updateTimeFactor;
643 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
645 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
647 if (physicsStats != null)
649 foreach (KeyValuePair<string, float> tuple
in physicsStats)
654 if (tuple.Key.EndsWith(
"MS"))
655 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * perframefactor;
657 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * updateTimeFactor;
665 Monitor.Exit(m_statsLock);
669 private void ResetValues()
674 m_scriptEventsPerSecond = 0;
681 internal void CheckStatSanity()
683 if (m_rootAgents < 0 || m_childAgents < 0)
685 handlerStatsIncorrect = OnStatsIncorrect;
686 if (handlerStatsIncorrect != null)
688 handlerStatsIncorrect();
691 if (m_rootAgents == 0 && m_childAgents == 0)
697 # region methods called from Scene
699 public void AddFrameStats(
float _timeDilation,
float _physicsFPS,
float _agentMS,
700 float _physicsMS,
float _otherMS ,
float _sleepMS,
701 float _frameMS,
float _scriptTimeMS)
703 lock(m_statsFrameLock)
706 m_timeDilation += _timeDilation;
707 m_pfps += _physicsFPS;
708 m_agentMS += _agentMS;
709 m_physicsMS += _physicsMS;
710 m_otherMS += _otherMS;
711 m_sleeptimeMS += _sleepMS;
712 m_frameMS += _frameMS;
713 m_scriptTimeMS += _scriptTimeMS;
715 if (_frameMS > SlowFramesStatReportThreshold)
716 SlowFramesStat.Value++;
718 m_FrameStatsTS = Util.GetTimeStampMS();
722 private void ResetFrameStats()
725 m_timeDilation = 0.0f;
730 m_sleeptimeMS = 0.0f;
732 m_scriptTimeMS = 0.0f;
734 m_prevFrameStatsTS = m_FrameStatsTS;
739 m_objectUpdates += numUpdates;
744 m_agentUpdates += numUpdates;
749 m_inPacketsPerSecond = numPackets;
754 m_outPacketsPerSecond = numPackets;
759 m_unAckedBytes += numBytes;
760 if (m_unAckedBytes < 0) m_unAckedBytes = 0;
776 m_pendingDownloads += count;
778 if (m_pendingDownloads < 0)
779 m_pendingDownloads = 0;
786 m_scriptEventsPerSecond += count;
791 AddInPackets(inPackets);
792 AddOutPackets(outPackets);
793 AddunAckedBytes(unAckedBytes);
818 m_inUseThreads = inUseThreads;
825 lock (m_lastReportedExtraSimStats)
826 return new Dictionary<string, float>(m_lastReportedExtraSimStats);
void AddFrameStats(float _timeDilation, float _physicsFPS, float _agentMS, float _physicsMS, float _otherMS, float _sleepMS, float _frameMS, float _scriptTimeMS)
SimStatsReporter(Scene scene)
OpenSim.Framework.RegionInfo RegionInfo
void AddOutPackets(int numPackets)
void addScriptEvents(int count)
Holds individual statistic details
YourStatsAreWrong OnStatsIncorrect
Enapsulate statistics for a simulator/scene.
Stats
These are the IDs of stats sent in the StatsPacket to the viewer.
void AddObjectUpdates(int numUpdates)
SendStatResult OnSendStatsResult
void addImageMS(float ms)
void UpdateUsersLoggingIn(bool isLoggingIn)
void SetUpdateMS(int ms)
Sets the number of milliseconds between stat updates.
StatVerbosity
Verbosity of stat.
void AddInPackets(int numPackets)
void SetThreadCount(int inUseThreads)
void AddPendingDownloads(int count)
Collect statistics from the scene to send to the client and for access by other monitoring tools...
void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)
void AddunAckedBytes(int numBytes)
void AddAgentUpdates(int numUpdates)
Dictionary< string, float > GetExtraSimStats()