OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SimStatsReporter.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Timers;
31 using System.Threading;
32 using OpenMetaverse.Packets;
33 using OpenSim.Framework;
34 using OpenSim.Framework.Monitoring;
35 using OpenSim.Region.Framework.Interfaces;
36 
37 namespace OpenSim.Region.Framework.Scenes
38 {
45  public class SimStatsReporter
46  {
47  private static readonly log4net.ILog m_log
48  = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
49 
50  public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
51  public const string SlowFramesStatName = "SlowFrames";
52 
53  public delegate void SendStatResult(SimStats stats);
54 
55  public delegate void YourStatsAreWrong();
56 
57  public event SendStatResult OnSendStatsResult;
58 
59  public event YourStatsAreWrong OnStatsIncorrect;
60 
61  private SendStatResult handlerSendStatResult;
62 
63  private YourStatsAreWrong handlerStatsIncorrect;
64 
65  // Determines the size of the array that is used to collect StatBlocks
66  // for sending viewer compatible stats must be conform with sb array filling below
67  private const int m_statisticViewerArraySize = 38;
68  // size of LastReportedSimFPS with extra stats.
69  private const int m_statisticExtraArraySize = (int)(Stats.SimExtraCountEnd - Stats.SimExtraCountStart);
70 
78  public enum Stats : uint
79  {
80 // viewers defined IDs
81  TimeDilation = 0,
82  SimFPS = 1,
83  PhysicsFPS = 2,
84  AgentUpdates = 3,
85  FrameMS = 4,
86  NetMS = 5,
87  OtherMS = 6,
88  PhysicsMS = 7,
89  AgentMS = 8,
90  ImageMS = 9,
91  ScriptMS = 10,
92  TotalPrim = 11,
93  ActivePrim = 12,
94  Agents = 13,
95  ChildAgents = 14,
96  ActiveScripts = 15,
97  LSLScriptLinesPerSecond = 16, // viewers don't like this anymore
98  InPacketsPerSecond = 17,
99  OutPacketsPerSecond = 18,
100  PendingDownloads = 19,
101  PendingUploads = 20,
102  VirtualSizeKb = 21,
103  ResidentSizeKb = 22,
104  PendingLocalUploads = 23,
105  UnAckedBytes = 24,
106  PhysicsPinnedTasks = 25,
107  PhysicsLodTasks = 26,
108  SimPhysicsStepMs = 27,
109  SimPhysicsShapeMs = 28,
110  SimPhysicsOtherMs = 29,
111  SimPhysicsMemory = 30,
112  ScriptEps = 31,
113  SimSpareMs = 32,
114  SimSleepMs = 33,
115  SimIoPumpTime = 34,
116  SimPCTSscriptsRun = 35,
117  SimRegionIdle = 36, // dataserver only
118  SimRegionIdlePossible = 37, // dataserver only
119  SimAIStepTimeMS = 38,
120  SimSkippedSillouet_PS = 39,
121  SimSkippedCharsPerC = 40,
122 
123 // extra stats IDs irrelevant, just far from viewer defined ones
124  SimExtraCountStart = 1000,
125 
126  internalLSLScriptLinesPerSecond = 1000,
127  FrameDilation2 = 1001,
128  UsersLoggingIn = 1002,
129  TotalGeoPrim = 1003,
130  TotalMesh = 1004,
131  ThreadCount = 1005,
132 
133  SimExtraCountEnd = 1006
134  }
135 
139  public float LastReportedSimFPS
140  {
141  get { return lastReportedSimFPS; }
142  }
143 
151  public float LastReportedObjectUpdates { get; private set; }
152 
153  public float[] LastReportedSimStats
154  {
155  get { return lastReportedSimStats; }
156  }
157 
161  public Stat SlowFramesStat { get; private set; }
162 
166  public int SlowFramesStatReportThreshold { get; private set; }
167 
174  private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>();
175 
176  // Sending a stats update every 3 seconds-
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;
182  private int m_fps;
183 
184  private object m_statsLock = new object();
185  private object m_statsFrameLock = new object();
186 
200  private float m_statisticsFPSfactor = 5.0f;
201  private float m_targetFrameTime = 0.1f;
202  // saved last reported value so there is something available for llGetRegionFPS
203  private float lastReportedSimFPS;
204  private float[] lastReportedSimStats = new float[m_statisticExtraArraySize + m_statisticViewerArraySize];
205  private float m_pfps;
206 
210  private int m_agentUpdates;
211 
215  private int m_objectUpdates;
216 
217  private float m_frameMS;
218 
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;
226 
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; // FIXME: Not currently filled in
238  private int m_activeScripts;
239  private int m_scriptLinesPerSecond;
240  private int m_scriptEventsPerSecond;
241 
242  private int m_objectCapacity = 45000;
243 
244  // The current number of users attempting to login to the region
245  private int m_usersLoggingIn;
246 
247  // The last reported value of threads from the SmartThreadPool inside of
248  // XEngine
249  private int m_inUseThreads;
250 
251  private Scene m_scene;
252 
253  private RegionInfo ReportingRegion;
254 
255  private System.Timers.Timer m_report = new System.Timers.Timer();
256 
257  private IEstateModule estateModule;
258 
259  public SimStatsReporter(Scene scene)
260  {
261  m_scene = scene;
262 
263  ReportingRegion = scene.RegionInfo;
264 
265  if(scene.Normalized55FPS)
266  m_statisticsFPSfactor = 55.0f * m_scene.FrameTime;
267  else
268  m_statisticsFPSfactor = 1.0f;
269 
270  m_targetFrameTime = 1000.0f * m_scene.FrameTime / m_statisticsFPSfactor;
271 
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;
277 
278  m_lastUpdateTS = Util.GetTimeStampMS();
279  m_FrameStatsTS = m_lastUpdateTS;
280  m_prevFrameStatsTS = m_lastUpdateTS;
281 
282  if (StatsManager.SimExtraStats != null)
283  OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
284 
287  SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.FrameTime * 1000 * 1.2);
288 
289  SlowFramesStat
290  = new Stat(
291  "SlowFrames",
292  "Slow Frames",
293  "Number of frames where frame time has been significantly longer than the desired frame time.",
294  " frames",
295  "scene",
296  m_scene.Name,
297  StatType.Push,
298  null,
299  StatVerbosity.Info);
300 
301  StatsManager.RegisterStat(SlowFramesStat);
302  }
303 
304 
305  public void Close()
306  {
307  m_report.Elapsed -= TriggerStatsHeartbeat;
308  m_report.Close();
309  }
310 
315  public void SetUpdateMS(int ms)
316  {
317  m_statsUpdatesEveryMS = ms;
318  m_report.Interval = m_statsUpdatesEveryMS;
319  }
320 
321  private void TriggerStatsHeartbeat(object sender, EventArgs args)
322  {
323  try
324  {
325  statsHeartBeat(sender, args);
326  }
327  catch (Exception e)
328  {
329  m_log.Warn(string.Format(
330  "[SIM STATS REPORTER] Update for {0} failed with exception ",
331  m_scene.RegionInfo.RegionName), e);
332  }
333  }
334 
335  private void statsHeartBeat(object sender, EventArgs e)
336  {
337  if (!m_scene.Active)
338  return;
339 
340  // dont do it if if still been done
341 
342  if(Monitor.TryEnter(m_statsLock))
343  {
344  // m_log.Debug("Firing Stats Heart Beat");
345 
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;
350 
351  try
352  {
353  if (estateModule == null)
354  estateModule = m_scene.RequestModuleInterface<IEstateModule>();
355  regionFlags = estateModule != null ? estateModule.GetRegionFlags() : (uint) 0;
356  }
357  catch (Exception)
358  {
359  // leave region flags at 0
360  }
361 
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);
366 
367  // factor to consider updates integration time
368  float updateTimeFactor = 1.0f / updateElapsed;
369 
370 
371  // scene frame stats
372  float reportedFPS;
373  float physfps;
374  float timeDilation;
375  float agentMS;
376  float physicsMS;
377  float otherMS;
378  float sleeptime;
379  float scriptTimeMS;
380  float totalFrameTime;
381 
382  float invFrameElapsed;
383 
384  // get a copy under lock and reset
385  lock(m_statsFrameLock)
386  {
387  timeDilation = m_timeDilation;
388  reportedFPS = m_fps;
389  physfps = m_pfps;
390  agentMS = m_agentMS;
391  physicsMS = m_physicsMS;
392  otherMS = m_otherMS;
393  sleeptime = m_sleeptimeMS;
394  scriptTimeMS = m_scriptTimeMS;
395  totalFrameTime = m_frameMS;
396  // still not inv
397  invFrameElapsed = (float)((m_FrameStatsTS - m_prevFrameStatsTS) / 1000.0);
398 
399  ResetFrameStats();
400  }
401 
402  if (invFrameElapsed / updateElapsed < 0.8)
403  // scene is in trouble, its account of time is most likely wrong
404  // can even be in stall
405  invFrameElapsed = updateTimeFactor;
406  else
407  invFrameElapsed = 1.0f / invFrameElapsed;
408 
409  float perframefactor;
410  if (reportedFPS <= 0)
411  {
412  reportedFPS = 0.0f;
413  physfps = 0.0f;
414  perframefactor = 1.0f;
415  timeDilation = 0.0f;
416  }
417  else
418  {
419  timeDilation /= reportedFPS;
420  reportedFPS *= m_statisticsFPSfactor;
421  perframefactor = 1.0f / (float)reportedFPS;
422  reportedFPS *= invFrameElapsed;
423  physfps *= invFrameElapsed * m_statisticsFPSfactor;
424  }
425 
426  // some engines track frame time with error related to the simulation step size
427  if(physfps > reportedFPS)
428  physfps = reportedFPS;
429 
430  // save the reported value so there is something available for llGetRegionFPS
431  lastReportedSimFPS = reportedFPS;
432 
433  // scale frame stats
434 
435  totalFrameTime *= perframefactor;
436  sleeptime *= perframefactor;
437  otherMS *= perframefactor;
438  physicsMS *= perframefactor;
439  agentMS *= perframefactor;
440  scriptTimeMS *= perframefactor;
441 
442  // estimate spare time
443  float sparetime;
444  sparetime = m_targetFrameTime - (physicsMS + agentMS + otherMS);
445 
446  if (sparetime < 0)
447  sparetime = 0;
448  else if (sparetime > totalFrameTime)
449  sparetime = totalFrameTime;
450 
451 #endregion
452 
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();
461 
462  // FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code
463  // so that stat numbers are always consistent.
464  CheckStatSanity();
465 
466  for (int i = 0; i < m_statisticViewerArraySize; i++)
467  {
468  sb[i] = new SimStatsPacket.StatBlock();
469  }
470 
471  sb[0].StatID = (uint) Stats.TimeDilation;
472  sb[0].StatValue = (Single.IsNaN(timeDilation)) ? 0.0f : (float)Math.Round(timeDilation,3);
473 
474  sb[1].StatID = (uint) Stats.SimFPS;
475  sb[1].StatValue = (float)Math.Round(reportedFPS,1);;
476 
477  sb[2].StatID = (uint) Stats.PhysicsFPS;
478  sb[2].StatValue = (float)Math.Round(physfps,1);
479 
480  sb[3].StatID = (uint) Stats.AgentUpdates;
481  sb[3].StatValue = m_agentUpdates * updateTimeFactor;
482 
483  sb[4].StatID = (uint) Stats.Agents;
484  sb[4].StatValue = m_rootAgents;
485 
486  sb[5].StatID = (uint) Stats.ChildAgents;
487  sb[5].StatValue = m_childAgents;
488 
489  sb[6].StatID = (uint) Stats.TotalPrim;
490  sb[6].StatValue = m_numPrim;
491 
492  sb[7].StatID = (uint) Stats.ActivePrim;
493  sb[7].StatValue = m_activePrim;
494 
495  sb[8].StatID = (uint)Stats.FrameMS;
496  sb[8].StatValue = totalFrameTime;
497 
498  sb[9].StatID = (uint)Stats.NetMS;
499  sb[9].StatValue = m_netMS * perframefactor;
500 
501  sb[10].StatID = (uint)Stats.PhysicsMS;
502  sb[10].StatValue = physicsMS;
503 
504  sb[11].StatID = (uint)Stats.ImageMS ;
505  sb[11].StatValue = m_imageMS * perframefactor;
506 
507  sb[12].StatID = (uint)Stats.OtherMS;
508  sb[12].StatValue = otherMS;
509 
510  sb[13].StatID = (uint)Stats.InPacketsPerSecond;
511  sb[13].StatValue = (float)Math.Round(m_inPacketsPerSecond * updateTimeFactor);
512 
513  sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
514  sb[14].StatValue = (float)Math.Round(m_outPacketsPerSecond * updateTimeFactor);
515 
516  sb[15].StatID = (uint)Stats.UnAckedBytes;
517  sb[15].StatValue = m_unAckedBytes;
518 
519  sb[16].StatID = (uint)Stats.AgentMS;
520  sb[16].StatValue = agentMS;
521 
522  sb[17].StatID = (uint)Stats.PendingDownloads;
523  sb[17].StatValue = m_pendingDownloads;
524 
525  sb[18].StatID = (uint)Stats.PendingUploads;
526  sb[18].StatValue = m_pendingUploads;
527 
528  sb[19].StatID = (uint)Stats.ActiveScripts;
529  sb[19].StatValue = m_activeScripts;
530 
531  sb[20].StatID = (uint)Stats.SimSleepMs;
532  sb[20].StatValue = sleeptime;
533 
534  sb[21].StatID = (uint)Stats.SimSpareMs;
535  sb[21].StatValue = sparetime;
536 
537  // this should came from phys engine
538  sb[22].StatID = (uint)Stats.SimPhysicsStepMs;
539  sb[22].StatValue = 20;
540 
541  // send the ones we dont have as zeros, to clean viewers state
542  // specially arriving from regions with wrond IDs in use
543 
544  sb[23].StatID = (uint)Stats.VirtualSizeKb;
545  sb[23].StatValue = 0;
546 
547  sb[24].StatID = (uint)Stats.ResidentSizeKb;
548  sb[24].StatValue = 0;
549 
550  sb[25].StatID = (uint)Stats.PendingLocalUploads;
551  sb[25].StatValue = 0;
552 
553  sb[26].StatID = (uint)Stats.PhysicsPinnedTasks;
554  sb[26].StatValue = 0;
555 
556  sb[27].StatID = (uint)Stats.PhysicsLodTasks;
557  sb[27].StatValue = 0;
558 
559  sb[28].StatID = (uint)Stats.ScriptEps; // we actuall have this, but not messing array order AGAIN
560  sb[28].StatValue = (float)Math.Round(m_scriptEventsPerSecond * updateTimeFactor);
561 
562  sb[29].StatID = (uint)Stats.SimAIStepTimeMS;
563  sb[29].StatValue = 0;
564 
565  sb[30].StatID = (uint)Stats.SimIoPumpTime;
566  sb[30].StatValue = 0;
567 
568  sb[31].StatID = (uint)Stats.SimPCTSscriptsRun;
569  sb[31].StatValue = 0;
570 
571  sb[32].StatID = (uint)Stats.SimRegionIdle;
572  sb[32].StatValue = 0;
573 
574  sb[33].StatID = (uint)Stats.SimRegionIdlePossible;
575  sb[33].StatValue = 0;
576 
577  sb[34].StatID = (uint)Stats.SimSkippedSillouet_PS;
578  sb[34].StatValue = 0;
579 
580  sb[35].StatID = (uint)Stats.SimSkippedCharsPerC;
581  sb[35].StatValue = 0;
582 
583  sb[36].StatID = (uint)Stats.SimPhysicsMemory;
584  sb[36].StatValue = 0;
585 
586  sb[37].StatID = (uint)Stats.ScriptMS;
587  sb[37].StatValue = scriptTimeMS;
588 
589  for (int i = 0; i < m_statisticViewerArraySize; i++)
590  {
591  lastReportedSimStats[i] = sb[i].StatValue;
592  }
593 
594 
595  // add extra stats for internal use
596 
597  for (int i = 0; i < m_statisticExtraArraySize; i++)
598  {
599  sbex[i] = new SimStatsPacket.StatBlock();
600  }
601 
602  sbex[0].StatID = (uint)Stats.LSLScriptLinesPerSecond;
603  sbex[0].StatValue = m_scriptLinesPerSecond * updateTimeFactor;
604  lastReportedSimStats[38] = m_scriptLinesPerSecond * updateTimeFactor;
605 
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;
609 
610  sbex[2].StatID = (uint)Stats.UsersLoggingIn;
611  sbex[2].StatValue = m_usersLoggingIn;
612  lastReportedSimStats[40] = m_usersLoggingIn;
613 
614  sbex[3].StatID = (uint)Stats.TotalGeoPrim;
615  sbex[3].StatValue = m_numGeoPrim;
616  lastReportedSimStats[41] = m_numGeoPrim;
617 
618  sbex[4].StatID = (uint)Stats.TotalMesh;
619  sbex[4].StatValue = m_numMesh;
620  lastReportedSimStats[42] = m_numMesh;
621 
622  sbex[5].StatID = (uint)Stats.ThreadCount;
623  sbex[5].StatValue = m_inUseThreads;
624  lastReportedSimStats[43] = m_inUseThreads;
625 
626  SimStats simStats
627  = new SimStats(
628  ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)m_objectCapacity,
629  rb, sb, sbex, m_scene.RegionInfo.originRegionID);
630 
631  handlerSendStatResult = OnSendStatsResult;
632  if (handlerSendStatResult != null)
633  {
634  handlerSendStatResult(simStats);
635  }
636 
637  // Extra statistics that aren't currently sent to clients
638  if (m_scene.PhysicsScene != null)
639  {
640  lock (m_lastReportedExtraSimStats)
641  {
642  m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates * updateTimeFactor;
643  m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
644 
645  Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
646 
647  if (physicsStats != null)
648  {
649  foreach (KeyValuePair<string, float> tuple in physicsStats)
650  {
651  // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second
652  // Need to change things so that stats source can indicate whether they are per second or
653  // per frame.
654  if (tuple.Key.EndsWith("MS"))
655  m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * perframefactor;
656  else
657  m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * updateTimeFactor;
658  }
659  }
660  }
661  }
662 
663 // LastReportedObjectUpdates = m_objectUpdates / m_statsUpdateFactor;
664  ResetValues();
665  Monitor.Exit(m_statsLock);
666  }
667  }
668 
669  private void ResetValues()
670  {
671  m_agentUpdates = 0;
672  m_objectUpdates = 0;
673  m_unAckedBytes = 0;
674  m_scriptEventsPerSecond = 0;
675 
676  m_netMS = 0;
677  m_imageMS = 0;
678  }
679 
680 
681  internal void CheckStatSanity()
682  {
683  if (m_rootAgents < 0 || m_childAgents < 0)
684  {
685  handlerStatsIncorrect = OnStatsIncorrect;
686  if (handlerStatsIncorrect != null)
687  {
688  handlerStatsIncorrect();
689  }
690  }
691  if (m_rootAgents == 0 && m_childAgents == 0)
692  {
693  m_unAckedBytes = 0;
694  }
695  }
696 
697  # region methods called from Scene
698 
699  public void AddFrameStats(float _timeDilation, float _physicsFPS, float _agentMS,
700  float _physicsMS, float _otherMS , float _sleepMS,
701  float _frameMS, float _scriptTimeMS)
702  {
703  lock(m_statsFrameLock)
704  {
705  m_fps++;
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;
714 
715  if (_frameMS > SlowFramesStatReportThreshold)
716  SlowFramesStat.Value++;
717 
718  m_FrameStatsTS = Util.GetTimeStampMS();
719  }
720  }
721 
722  private void ResetFrameStats()
723  {
724  m_fps = 0;
725  m_timeDilation = 0.0f;
726  m_pfps = 0.0f;
727  m_agentMS = 0.0f;
728  m_physicsMS = 0.0f;
729  m_otherMS = 0.0f;
730  m_sleeptimeMS = 0.0f;
731  m_frameMS = 0.0f;
732  m_scriptTimeMS = 0.0f;
733 
734  m_prevFrameStatsTS = m_FrameStatsTS;
735  }
736 
737  public void AddObjectUpdates(int numUpdates)
738  {
739  m_objectUpdates += numUpdates;
740  }
741 
742  public void AddAgentUpdates(int numUpdates)
743  {
744  m_agentUpdates += numUpdates;
745  }
746 
747  public void AddInPackets(int numPackets)
748  {
749  m_inPacketsPerSecond = numPackets;
750  }
751 
752  public void AddOutPackets(int numPackets)
753  {
754  m_outPacketsPerSecond = numPackets;
755  }
756 
757  public void AddunAckedBytes(int numBytes)
758  {
759  m_unAckedBytes += numBytes;
760  if (m_unAckedBytes < 0) m_unAckedBytes = 0;
761  }
762 
763 
764  public void addNetMS(float ms)
765  {
766  m_netMS += ms;
767  }
768 
769  public void addImageMS(float ms)
770  {
771  m_imageMS += ms;
772  }
773 
774  public void AddPendingDownloads(int count)
775  {
776  m_pendingDownloads += count;
777 
778  if (m_pendingDownloads < 0)
779  m_pendingDownloads = 0;
780 
781  //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
782  }
783 
784  public void addScriptEvents(int count)
785  {
786  m_scriptEventsPerSecond += count;
787  }
788 
789  public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)
790  {
791  AddInPackets(inPackets);
792  AddOutPackets(outPackets);
793  AddunAckedBytes(unAckedBytes);
794  }
795 
796  public void UpdateUsersLoggingIn(bool isLoggingIn)
797  {
798  // Determine whether the user has started logging in or has completed
799  // logging into the region
800  if (isLoggingIn)
801  {
802  // The user is starting to login to the region so increment the
803  // number of users attempting to login to the region
804  m_usersLoggingIn++;
805  }
806  else
807  {
808  // The user has finished logging into the region so decrement the
809  // number of users logging into the region
810  m_usersLoggingIn--;
811  }
812  }
813 
814  public void SetThreadCount(int inUseThreads)
815  {
816  // Save the new number of threads to our member variable to send to
817  // the extra stats collector
818  m_inUseThreads = inUseThreads;
819  }
820 
821  #endregion
822 
823  public Dictionary<string, float> GetExtraSimStats()
824  {
825  lock (m_lastReportedExtraSimStats)
826  return new Dictionary<string, float>(m_lastReportedExtraSimStats);
827  }
828  }
829 }
void AddFrameStats(float _timeDilation, float _physicsFPS, float _agentMS, float _physicsMS, float _otherMS, float _sleepMS, float _frameMS, float _scriptTimeMS)
OpenSim.Framework.RegionInfo RegionInfo
Holds individual statistic details
Definition: Stat.cs:41
Enapsulate statistics for a simulator/scene.
Definition: SimStats.cs:39
Stats
These are the IDs of stats sent in the StatsPacket to the viewer.
void SetUpdateMS(int ms)
Sets the number of milliseconds between stat updates.
StatVerbosity
Verbosity of stat.
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)