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