aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs')
-rwxr-xr-xOpenSim/Framework/Monitoring/SimExtraStatsCollector.cs536
1 files changed, 536 insertions, 0 deletions
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
new file mode 100755
index 0000000..e4df7ee
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -0,0 +1,536 @@
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
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.Linq;
32using System.Text;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using OpenSim.Framework.Monitoring.Interfaces;
36
37namespace OpenSim.Framework.Monitoring
38{
39 /// <summary>
40 /// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane
41 /// </summary>
42 public class SimExtraStatsCollector : BaseStatsCollector
43 {
44// private long assetsInCache;
45// private long texturesInCache;
46// private long assetCacheMemoryUsage;
47// private long textureCacheMemoryUsage;
48// private TimeSpan assetRequestTimeAfterCacheMiss;
49// private long blockedMissingTextureRequests;
50
51// private long assetServiceRequestFailures;
52// private long inventoryServiceRetrievalFailures;
53
54 private volatile float timeDilation;
55 private volatile float simFps;
56 private volatile float physicsFps;
57 private volatile float agentUpdates;
58 private volatile float rootAgents;
59 private volatile float childAgents;
60 private volatile float totalPrims;
61 private volatile float activePrims;
62 private volatile float totalFrameTime;
63 private volatile float netFrameTime;
64 private volatile float physicsFrameTime;
65 private volatile float otherFrameTime;
66 private volatile float imageFrameTime;
67 private volatile float inPacketsPerSecond;
68 private volatile float outPacketsPerSecond;
69 private volatile float unackedBytes;
70 private volatile float agentFrameTime;
71 private volatile float pendingDownloads;
72 private volatile float pendingUploads;
73 private volatile float activeScripts;
74 private volatile float scriptLinesPerSecond;
75 private volatile float m_frameDilation;
76 private volatile float m_usersLoggingIn;
77 private volatile float m_totalGeoPrims;
78 private volatile float m_totalMeshes;
79 private volatile float m_inUseThreads;
80
81// /// <summary>
82// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
83// /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these
84// /// haven't yet been implemented...
85// /// </summary>
86// public long AssetsInCache { get { return assetsInCache; } }
87//
88// /// <value>
89// /// Currently unused
90// /// </value>
91// public long TexturesInCache { get { return texturesInCache; } }
92//
93// /// <value>
94// /// Currently misleading since we can't currently subtract removed asset memory usage without a performance hit
95// /// </value>
96// public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } }
97//
98// /// <value>
99// /// Currently unused
100// /// </value>
101// public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } }
102
103 public float TimeDilation { get { return timeDilation; } }
104 public float SimFps { get { return simFps; } }
105 public float PhysicsFps { get { return physicsFps; } }
106 public float AgentUpdates { get { return agentUpdates; } }
107 public float RootAgents { get { return rootAgents; } }
108 public float ChildAgents { get { return childAgents; } }
109 public float TotalPrims { get { return totalPrims; } }
110 public float ActivePrims { get { return activePrims; } }
111 public float TotalFrameTime { get { return totalFrameTime; } }
112 public float NetFrameTime { get { return netFrameTime; } }
113 public float PhysicsFrameTime { get { return physicsFrameTime; } }
114 public float OtherFrameTime { get { return otherFrameTime; } }
115 public float ImageFrameTime { get { return imageFrameTime; } }
116 public float InPacketsPerSecond { get { return inPacketsPerSecond; } }
117 public float OutPacketsPerSecond { get { return outPacketsPerSecond; } }
118 public float UnackedBytes { get { return unackedBytes; } }
119 public float AgentFrameTime { get { return agentFrameTime; } }
120 public float PendingDownloads { get { return pendingDownloads; } }
121 public float PendingUploads { get { return pendingUploads; } }
122 public float ActiveScripts { get { return activeScripts; } }
123 public float ScriptLinesPerSecond { get { return scriptLinesPerSecond; } }
124
125// /// <summary>
126// /// This is the time it took for the last asset request made in response to a cache miss.
127// /// </summary>
128// public TimeSpan AssetRequestTimeAfterCacheMiss { get { return assetRequestTimeAfterCacheMiss; } }
129//
130// /// <summary>
131// /// Number of persistent requests for missing textures we have started blocking from clients. To some extent
132// /// this is just a temporary statistic to keep this problem in view - the root cause of this lies either
133// /// in a mishandling of the reply protocol, related to avatar appearance or may even originate in graphics
134// /// driver bugs on clients (though this seems less likely).
135// /// </summary>
136// public long BlockedMissingTextureRequests { get { return blockedMissingTextureRequests; } }
137//
138// /// <summary>
139// /// Record the number of times that an asset request has failed. Failures are effectively exceptions, such as
140// /// request timeouts. If an asset service replies that a particular asset cannot be found, this is not counted
141// /// as a failure
142// /// </summary>
143// public long AssetServiceRequestFailures { get { return assetServiceRequestFailures; } }
144
145 /// <summary>
146 /// Number of known failures to retrieve avatar inventory from the inventory service. This does not
147 /// cover situations where the inventory service accepts the request but never returns any data, since
148 /// we do not yet timeout this situation.
149 /// </summary>
150 /// <remarks>Commented out because we do not cache inventory at this point</remarks>
151// public long InventoryServiceRetrievalFailures { get { return inventoryServiceRetrievalFailures; } }
152
153 /// <summary>
154 /// Retrieve the total frame time (in ms) of the last frame
155 /// </summary>
156 //public float TotalFrameTime { get { return totalFrameTime; } }
157
158 /// <summary>
159 /// Retrieve the physics update component (in ms) of the last frame
160 /// </summary>
161 //public float PhysicsFrameTime { get { return physicsFrameTime; } }
162
163 /// <summary>
164 /// Retain a dictionary of all packet queues stats reporters
165 /// </summary>
166 private IDictionary<UUID, PacketQueueStatsCollector> packetQueueStatsCollectors
167 = new Dictionary<UUID, PacketQueueStatsCollector>();
168
169// public void AddAsset(AssetBase asset)
170// {
171// assetsInCache++;
172// //assetCacheMemoryUsage += asset.Data.Length;
173// }
174//
175// public void RemoveAsset(UUID uuid)
176// {
177// assetsInCache--;
178// }
179//
180// public void AddTexture(AssetBase image)
181// {
182// if (image.Data != null)
183// {
184// texturesInCache++;
185//
186// // This could have been a pull stat, though there was originally a nebulous idea to measure flow rates
187// textureCacheMemoryUsage += image.Data.Length;
188// }
189// }
190//
191// /// <summary>
192// /// Signal that the asset cache has been cleared.
193// /// </summary>
194// public void ClearAssetCacheStatistics()
195// {
196// assetsInCache = 0;
197// assetCacheMemoryUsage = 0;
198// texturesInCache = 0;
199// textureCacheMemoryUsage = 0;
200// }
201//
202// public void AddAssetRequestTimeAfterCacheMiss(TimeSpan ts)
203// {
204// assetRequestTimeAfterCacheMiss = ts;
205// }
206//
207// public void AddBlockedMissingTextureRequest()
208// {
209// blockedMissingTextureRequests++;
210// }
211//
212// public void AddAssetServiceRequestFailure()
213// {
214// assetServiceRequestFailures++;
215// }
216
217// public void AddInventoryServiceRetrievalFailure()
218// {
219// inventoryServiceRetrievalFailures++;
220// }
221
222 /// <summary>
223 /// Register as a packet queue stats provider
224 /// </summary>
225 /// <param name="uuid">An agent UUID</param>
226 /// <param name="provider"></param>
227 public void RegisterPacketQueueStatsProvider(UUID uuid, IPullStatsProvider provider)
228 {
229 lock (packetQueueStatsCollectors)
230 {
231 // FIXME: If the region service is providing more than one region, then the child and root agent
232 // queues are wrongly replacing each other here.
233 packetQueueStatsCollectors[uuid] = new PacketQueueStatsCollector(provider);
234 }
235 }
236
237 /// <summary>
238 /// Deregister a packet queue stats provider
239 /// </summary>
240 /// <param name="uuid">An agent UUID</param>
241 public void DeregisterPacketQueueStatsProvider(UUID uuid)
242 {
243 lock (packetQueueStatsCollectors)
244 {
245 packetQueueStatsCollectors.Remove(uuid);
246 }
247 }
248
249 /// <summary>
250 /// This is the method on which the classic sim stats reporter (which collects stats for
251 /// client purposes) sends information to listeners.
252 /// </summary>
253 /// <param name="pack"></param>
254 public void ReceiveClassicSimStatsPacket(SimStats stats)
255 {
256 // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
257 // SimStatsPacket that was being used).
258
259 // For an unknown reason the original designers decided not to
260 // include the spare MS statistic inside of this class, this is
261 // located inside the StatsBlock at location 21, thus it is skipped
262 timeDilation = stats.StatsBlock[0].StatValue;
263 simFps = stats.StatsBlock[1].StatValue;
264 physicsFps = stats.StatsBlock[2].StatValue;
265 agentUpdates = stats.StatsBlock[3].StatValue;
266 rootAgents = stats.StatsBlock[4].StatValue;
267 childAgents = stats.StatsBlock[5].StatValue;
268 totalPrims = stats.StatsBlock[6].StatValue;
269 activePrims = stats.StatsBlock[7].StatValue;
270 totalFrameTime = stats.StatsBlock[8].StatValue;
271 netFrameTime = stats.StatsBlock[9].StatValue;
272 physicsFrameTime = stats.StatsBlock[10].StatValue;
273 otherFrameTime = stats.StatsBlock[11].StatValue;
274 imageFrameTime = stats.StatsBlock[12].StatValue;
275 inPacketsPerSecond = stats.StatsBlock[13].StatValue;
276 outPacketsPerSecond = stats.StatsBlock[14].StatValue;
277 unackedBytes = stats.StatsBlock[15].StatValue;
278 agentFrameTime = stats.StatsBlock[16].StatValue;
279 pendingDownloads = stats.StatsBlock[17].StatValue;
280 pendingUploads = stats.StatsBlock[18].StatValue;
281 activeScripts = stats.StatsBlock[19].StatValue;
282 scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
283 m_frameDilation = stats.StatsBlock[22].StatValue;
284 m_usersLoggingIn = stats.StatsBlock[23].StatValue;
285 m_totalGeoPrims = stats.StatsBlock[24].StatValue;
286 m_totalMeshes = stats.StatsBlock[25].StatValue;
287 m_inUseThreads = stats.StatsBlock[26].StatValue;
288 }
289
290 /// <summary>
291 /// Report back collected statistical information.
292 /// </summary>
293 /// <returns></returns>
294 public override string Report()
295 {
296 StringBuilder sb = new StringBuilder(Environment.NewLine);
297// sb.Append("ASSET STATISTICS");
298// sb.Append(Environment.NewLine);
299
300 /*
301 sb.Append(
302 string.Format(
303@"Asset cache contains {0,6} non-texture assets using {1,10} K
304Texture cache contains {2,6} texture assets using {3,10} K
305Latest asset request time after cache miss: {4}s
306Blocked client requests for missing textures: {5}
307Asset service request failures: {6}"+ Environment.NewLine,
308 AssetsInCache, Math.Round(AssetCacheMemoryUsage / 1024.0),
309 TexturesInCache, Math.Round(TextureCacheMemoryUsage / 1024.0),
310 assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
311 BlockedMissingTextureRequests,
312 AssetServiceRequestFailures));
313 */
314
315 /*
316 sb.Append(
317 string.Format(
318@"Asset cache contains {0,6} assets
319Latest asset request time after cache miss: {1}s
320Blocked client requests for missing textures: {2}
321Asset service request failures: {3}" + Environment.NewLine,
322 AssetsInCache,
323 assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
324 BlockedMissingTextureRequests,
325 AssetServiceRequestFailures));
326 */
327
328 sb.Append(Environment.NewLine);
329 sb.Append("CONNECTION STATISTICS");
330 sb.Append(Environment.NewLine);
331
332 List<Stat> stats = StatsManager.GetStatsFromEachContainer("clientstack", "ClientLogoutsDueToNoReceives");
333
334 sb.AppendFormat(
335 "Client logouts due to no data receive timeout: {0}\n\n",
336 stats != null ? stats.Sum(s => s.Value).ToString() : "unknown");
337
338// sb.Append(Environment.NewLine);
339// sb.Append("INVENTORY STATISTICS");
340// sb.Append(Environment.NewLine);
341// sb.Append(
342// string.Format(
343// "Initial inventory caching failures: {0}" + Environment.NewLine,
344// InventoryServiceRetrievalFailures));
345
346 sb.Append(Environment.NewLine);
347 sb.Append("SAMPLE FRAME STATISTICS");
348 sb.Append(Environment.NewLine);
349 sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS");
350 sb.Append(Environment.NewLine);
351 sb.Append(
352 string.Format(
353 "{0,6:0.00} {1,6:0} {2,6:0.0} {3,6:0.0} {4,6:0} {5,6:0} {6,6:0} {7,6:0} {8,6:0} {9,6:0}",
354 timeDilation, simFps, physicsFps, agentUpdates, rootAgents,
355 childAgents, totalPrims, activePrims, activeScripts, scriptLinesPerSecond));
356
357 sb.Append(Environment.NewLine);
358 sb.Append(Environment.NewLine);
359 // There is no script frame time currently because we don't yet collect it
360 sb.Append("PktsIn PktOut PendDl PendUl UnackB TotlFt NetFt PhysFt OthrFt AgntFt ImgsFt");
361 sb.Append(Environment.NewLine);
362 sb.Append(
363 string.Format(
364 "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n",
365 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
366 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
367
368 /* 20130319 RA: For the moment, disable the dump of 'scene' catagory as they are mostly output by
369 * the two formatted printouts above.
370 SortedDictionary<string, SortedDictionary<string, Stat>> sceneStats;
371 if (StatsManager.TryGetStats("scene", out sceneStats))
372 {
373 foreach (KeyValuePair<string, SortedDictionary<string, Stat>> kvp in sceneStats)
374 {
375 foreach (Stat stat in kvp.Value.Values)
376 {
377 if (stat.Verbosity == StatVerbosity.Info)
378 {
379 sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName);
380 }
381 }
382 }
383 }
384 */
385
386 /*
387 sb.Append(Environment.NewLine);
388 sb.Append("PACKET QUEUE STATISTICS");
389 sb.Append(Environment.NewLine);
390 sb.Append("Agent UUID ");
391 sb.Append(
392 string.Format(
393 " {0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
394 "Send", "In", "Out", "Resend", "Land", "Wind", "Cloud", "Task", "Texture", "Asset"));
395 sb.Append(Environment.NewLine);
396
397 foreach (UUID key in packetQueueStatsCollectors.Keys)
398 {
399 sb.Append(string.Format("{0}: ", key));
400 sb.Append(packetQueueStatsCollectors[key].Report());
401 sb.Append(Environment.NewLine);
402 }
403 */
404
405 sb.Append(base.Report());
406
407 return sb.ToString();
408 }
409
410 /// <summary>
411 /// Report back collected statistical information as json serialization.
412 /// </summary>
413 /// <returns></returns>
414 public override string XReport(string uptime, string version)
415 {
416 return OSDParser.SerializeJsonString(OReport(uptime, version));
417 }
418
419 /// <summary>
420 /// Report back collected statistical information as an OSDMap
421 /// </summary>
422 /// <returns></returns>
423 public override OSDMap OReport(string uptime, string version)
424 {
425 // Get the amount of physical memory, allocated with the instance of this program, in kilobytes;
426 // the working set is the set of memory pages currently visible to this program in physical RAM
427 // memory and includes both shared (e.g. system libraries) and private data
428 double memUsage = Process.GetCurrentProcess().WorkingSet64 / 1024.0;
429
430 // Get the number of threads from the system that are currently
431 // running
432 int numberThreadsRunning = 0;
433 foreach (ProcessThread currentThread in
434 Process.GetCurrentProcess().Threads)
435 {
436 // A known issue with the current process .Threads property is
437 // that it can return null threads, thus don't count those as
438 // running threads and prevent the program function from failing
439 if (currentThread != null &&
440 currentThread.ThreadState == ThreadState.Running)
441 {
442 numberThreadsRunning++;
443 }
444 }
445
446 OSDMap args = new OSDMap(30);
447// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
448// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
449// assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0));
450// args["BlockedMissingTextureRequests"] = OSD.FromString (String.Format ("{0:0.##}",
451// BlockedMissingTextureRequests));
452// args["AssetServiceRequestFailures"] = OSD.FromString (String.Format ("{0:0.##}",
453// AssetServiceRequestFailures));
454// args["abnormalClientThreadTerminations"] = OSD.FromString (String.Format ("{0:0.##}",
455// abnormalClientThreadTerminations));
456// args["InventoryServiceRetrievalFailures"] = OSD.FromString (String.Format ("{0:0.##}",
457// InventoryServiceRetrievalFailures));
458 args["Dilatn"] = OSD.FromString (String.Format ("{0:0.##}", timeDilation));
459 args["SimFPS"] = OSD.FromString (String.Format ("{0:0.##}", simFps));
460 args["PhyFPS"] = OSD.FromString (String.Format ("{0:0.##}", physicsFps));
461 args["AgntUp"] = OSD.FromString (String.Format ("{0:0.##}", agentUpdates));
462 args["RootAg"] = OSD.FromString (String.Format ("{0:0.##}", rootAgents));
463 args["ChldAg"] = OSD.FromString (String.Format ("{0:0.##}", childAgents));
464 args["Prims"] = OSD.FromString (String.Format ("{0:0.##}", totalPrims));
465 args["AtvPrm"] = OSD.FromString (String.Format ("{0:0.##}", activePrims));
466 args["AtvScr"] = OSD.FromString (String.Format ("{0:0.##}", activeScripts));
467 args["ScrLPS"] = OSD.FromString (String.Format ("{0:0.##}", scriptLinesPerSecond));
468 args["PktsIn"] = OSD.FromString (String.Format ("{0:0.##}", inPacketsPerSecond));
469 args["PktOut"] = OSD.FromString (String.Format ("{0:0.##}", outPacketsPerSecond));
470 args["PendDl"] = OSD.FromString (String.Format ("{0:0.##}", pendingDownloads));
471 args["PendUl"] = OSD.FromString (String.Format ("{0:0.##}", pendingUploads));
472 args["UnackB"] = OSD.FromString (String.Format ("{0:0.##}", unackedBytes));
473 args["TotlFt"] = OSD.FromString (String.Format ("{0:0.##}", totalFrameTime));
474 args["NetFt"] = OSD.FromString (String.Format ("{0:0.##}", netFrameTime));
475 args["PhysFt"] = OSD.FromString (String.Format ("{0:0.##}", physicsFrameTime));
476 args["OthrFt"] = OSD.FromString (String.Format ("{0:0.##}", otherFrameTime));
477 args["AgntFt"] = OSD.FromString (String.Format ("{0:0.##}", agentFrameTime));
478 args["ImgsFt"] = OSD.FromString (String.Format ("{0:0.##}", imageFrameTime));
479 args["Memory"] = OSD.FromString (base.XReport (uptime, version));
480 args["Uptime"] = OSD.FromString (uptime);
481 args["Version"] = OSD.FromString (version);
482
483 args["FrameDilatn"] = OSD.FromString(String.Format("{0:0.##}", m_frameDilation));
484 args["Logging in Users"] = OSD.FromString(String.Format("{0:0.##}",
485 m_usersLoggingIn));
486 args["GeoPrims"] = OSD.FromString(String.Format("{0:0.##}",
487 m_totalGeoPrims));
488 args["Mesh Objects"] = OSD.FromString(String.Format("{0:0.##}",
489 m_totalMeshes));
490 args["XEngine Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
491 m_inUseThreads));
492 args["Util Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
493 Util.GetSmartThreadPoolInfo().InUseThreads));
494 args["System Thread Count"] = OSD.FromString(String.Format(
495 "{0:0.##}", numberThreadsRunning));
496 args["ProcMem"] = OSD.FromString(String.Format("{0:#,###,###.##}",
497 memUsage));
498
499 return args;
500 }
501 }
502
503
504 /// <summary>
505 /// Pull packet queue stats from packet queues and report
506 /// </summary>
507 public class PacketQueueStatsCollector : IStatsCollector
508 {
509 private IPullStatsProvider m_statsProvider;
510
511 public PacketQueueStatsCollector(IPullStatsProvider provider)
512 {
513 m_statsProvider = provider;
514 }
515
516 /// <summary>
517 /// Report back collected statistical information.
518 /// </summary>
519 /// <returns></returns>
520 public string Report()
521 {
522 return m_statsProvider.GetStats();
523 }
524
525 public string XReport(string uptime, string version)
526 {
527 return "";
528 }
529
530 public OSDMap OReport(string uptime, string version)
531 {
532 OSDMap ret = new OSDMap();
533 return ret;
534 }
535 }
536}