aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Monitoring
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Monitoring')
-rw-r--r--OpenSim/Framework/Monitoring/AssetStatsCollector.cs104
-rw-r--r--OpenSim/Framework/Monitoring/BaseStatsCollector.cs67
-rw-r--r--OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs41
-rw-r--r--OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs49
-rw-r--r--OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs463
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs65
-rw-r--r--OpenSim/Framework/Monitoring/UserStatsCollector.cs92
7 files changed, 881 insertions, 0 deletions
diff --git a/OpenSim/Framework/Monitoring/AssetStatsCollector.cs b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
new file mode 100644
index 0000000..2a4d45b
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
@@ -0,0 +1,104 @@
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.Timers;
30
31namespace OpenSim.Framework.Monitoring
32{
33 /// <summary>
34 /// Asset service statistics collection
35 /// </summary>
36 public class AssetStatsCollector : BaseStatsCollector
37 {
38 private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
39 private DateTime startTime = DateTime.Now;
40
41 private long assetRequestsToday;
42 private long assetRequestsNotFoundToday;
43 private long assetRequestsYesterday;
44 private long assetRequestsNotFoundYesterday;
45
46 public long AssetRequestsToday { get { return assetRequestsToday; } }
47 public long AssetRequestsNotFoundToday { get { return assetRequestsNotFoundToday; } }
48 public long AssetRequestsYesterday { get { return assetRequestsYesterday; } }
49 public long AssetRequestsNotFoundYesterday { get { return assetRequestsNotFoundYesterday; } }
50
51 public AssetStatsCollector()
52 {
53 ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
54 ageStatsTimer.Enabled = true;
55 }
56
57 private void OnAgeing(object source, ElapsedEventArgs e)
58 {
59 assetRequestsYesterday = assetRequestsToday;
60
61 // There is a possibility that an asset request could occur between the execution of these
62 // two statements. But we're better off without the synchronization overhead.
63 assetRequestsToday = 0;
64
65 assetRequestsNotFoundYesterday = assetRequestsNotFoundToday;
66 assetRequestsNotFoundToday = 0;
67 }
68
69 /// <summary>
70 /// Record that an asset request failed to find an asset
71 /// </summary>
72 public void AddNotFoundRequest()
73 {
74 assetRequestsNotFoundToday++;
75 }
76
77 /// <summary>
78 /// Record that a request was made to the asset server
79 /// </summary>
80 public void AddRequest()
81 {
82 assetRequestsToday++;
83 }
84
85 /// <summary>
86 /// Report back collected statistical information.
87 /// </summary>
88 /// <returns></returns>
89 override public string Report()
90 {
91 double elapsedHours = (DateTime.Now - startTime).TotalHours;
92 if (elapsedHours <= 0) { elapsedHours = 1; } // prevent divide by zero
93
94 long assetRequestsTodayPerHour = (long)Math.Round(AssetRequestsToday / elapsedHours);
95 long assetRequestsYesterdayPerHour = (long)Math.Round(AssetRequestsYesterday / 24.0);
96
97 return string.Format(
98@"Asset requests today : {0} ({1} per hour) of which {2} were not found
99Asset requests yesterday : {3} ({4} per hour) of which {5} were not found",
100 AssetRequestsToday, assetRequestsTodayPerHour, AssetRequestsNotFoundToday,
101 AssetRequestsYesterday, assetRequestsYesterdayPerHour, AssetRequestsNotFoundYesterday);
102 }
103 }
104}
diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
new file mode 100644
index 0000000..57a63ef
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
@@ -0,0 +1,67 @@
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.Diagnostics;
30using System.Text;
31using OpenMetaverse;
32using OpenMetaverse.StructuredData;
33
34namespace OpenSim.Framework.Monitoring
35{
36 /// <summary>
37 /// Statistics which all collectors are interested in reporting
38 /// </summary>
39 public class BaseStatsCollector : IStatsCollector
40 {
41 public virtual string Report()
42 {
43 StringBuilder sb = new StringBuilder(Environment.NewLine);
44 sb.Append("MEMORY STATISTICS");
45 sb.Append(Environment.NewLine);
46
47 sb.AppendFormat(
48 "Allocated to OpenSim objects: {0} MB\n",
49 Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
50
51 sb.AppendFormat(
52 "OpenSim object memory churn : {0} MB/s\n",
53 Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
54
55 sb.AppendFormat(
56 "Process memory : {0} MB\n",
57 Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
58
59 return sb.ToString();
60 }
61
62 public virtual string XReport(string uptime, string version)
63 {
64 return (string) Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0).ToString() ;
65 }
66 }
67}
diff --git a/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
new file mode 100644
index 0000000..86a6620
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
@@ -0,0 +1,41 @@
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
28namespace OpenSim.Framework.Monitoring.Interfaces
29{
30 /// <summary>
31 /// Implemented by objects which allow statistical information to be pulled from them.
32 /// </summary>
33 public interface IPullStatsProvider
34 {
35 /// <summary>
36 /// Provide statistical information. Only temporary one long string.
37 /// </summary>
38 /// <returns></returns>
39 string GetStats();
40 }
41}
diff --git a/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
new file mode 100644
index 0000000..99f75e3
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
@@ -0,0 +1,49 @@
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
28namespace OpenSim.Framework.Monitoring
29{
30 /// <summary>
31 /// Implemented by classes which collect up non-viewer statistical information
32 /// </summary>
33 public interface IStatsCollector
34 {
35 /// <summary>
36 /// Report back collected statistical information.
37 /// </summary>
38 /// <returns></returns>
39 string Report();
40
41 /// <summary>
42 /// Report back collected statistical information in json
43 /// </summary>
44 /// <returns>
45 /// A <see cref="System.String"/>
46 /// </returns>
47 string XReport(string uptime, string version);
48 }
49}
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
new file mode 100644
index 0000000..cdd7cc7
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -0,0 +1,463 @@
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.Text;
31using OpenMetaverse;
32using OpenMetaverse.StructuredData;
33using OpenSim.Framework.Monitoring.Interfaces;
34
35namespace OpenSim.Framework.Monitoring
36{
37 /// <summary>
38 /// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane
39 /// </summary>
40 public class SimExtraStatsCollector : BaseStatsCollector
41 {
42 private long abnormalClientThreadTerminations;
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
76 /// <summary>
77 /// Number of times that a client thread terminated because of an exception
78 /// </summary>
79 public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } }
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 AddAbnormalClientThreadTermination()
170 {
171 abnormalClientThreadTerminations++;
172 }
173
174// public void AddAsset(AssetBase asset)
175// {
176// assetsInCache++;
177// //assetCacheMemoryUsage += asset.Data.Length;
178// }
179//
180// public void RemoveAsset(UUID uuid)
181// {
182// assetsInCache--;
183// }
184//
185// public void AddTexture(AssetBase image)
186// {
187// if (image.Data != null)
188// {
189// texturesInCache++;
190//
191// // This could have been a pull stat, though there was originally a nebulous idea to measure flow rates
192// textureCacheMemoryUsage += image.Data.Length;
193// }
194// }
195//
196// /// <summary>
197// /// Signal that the asset cache has been cleared.
198// /// </summary>
199// public void ClearAssetCacheStatistics()
200// {
201// assetsInCache = 0;
202// assetCacheMemoryUsage = 0;
203// texturesInCache = 0;
204// textureCacheMemoryUsage = 0;
205// }
206//
207// public void AddAssetRequestTimeAfterCacheMiss(TimeSpan ts)
208// {
209// assetRequestTimeAfterCacheMiss = ts;
210// }
211//
212// public void AddBlockedMissingTextureRequest()
213// {
214// blockedMissingTextureRequests++;
215// }
216//
217// public void AddAssetServiceRequestFailure()
218// {
219// assetServiceRequestFailures++;
220// }
221
222// public void AddInventoryServiceRetrievalFailure()
223// {
224// inventoryServiceRetrievalFailures++;
225// }
226
227 /// <summary>
228 /// Register as a packet queue stats provider
229 /// </summary>
230 /// <param name="uuid">An agent UUID</param>
231 /// <param name="provider"></param>
232 public void RegisterPacketQueueStatsProvider(UUID uuid, IPullStatsProvider provider)
233 {
234 lock (packetQueueStatsCollectors)
235 {
236 // FIXME: If the region service is providing more than one region, then the child and root agent
237 // queues are wrongly replacing each other here.
238 packetQueueStatsCollectors[uuid] = new PacketQueueStatsCollector(provider);
239 }
240 }
241
242 /// <summary>
243 /// Deregister a packet queue stats provider
244 /// </summary>
245 /// <param name="uuid">An agent UUID</param>
246 public void DeregisterPacketQueueStatsProvider(UUID uuid)
247 {
248 lock (packetQueueStatsCollectors)
249 {
250 packetQueueStatsCollectors.Remove(uuid);
251 }
252 }
253
254 /// <summary>
255 /// This is the method on which the classic sim stats reporter (which collects stats for
256 /// client purposes) sends information to listeners.
257 /// </summary>
258 /// <param name="pack"></param>
259 public void ReceiveClassicSimStatsPacket(SimStats stats)
260 {
261 // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
262 // SimStatsPacket that was being used).
263 timeDilation = stats.StatsBlock[0].StatValue;
264 simFps = stats.StatsBlock[1].StatValue;
265 physicsFps = stats.StatsBlock[2].StatValue;
266 agentUpdates = stats.StatsBlock[3].StatValue;
267 rootAgents = stats.StatsBlock[4].StatValue;
268 childAgents = stats.StatsBlock[5].StatValue;
269 totalPrims = stats.StatsBlock[6].StatValue;
270 activePrims = stats.StatsBlock[7].StatValue;
271 totalFrameTime = stats.StatsBlock[8].StatValue;
272 netFrameTime = stats.StatsBlock[9].StatValue;
273 physicsFrameTime = stats.StatsBlock[10].StatValue;
274 otherFrameTime = stats.StatsBlock[11].StatValue;
275 imageFrameTime = stats.StatsBlock[12].StatValue;
276 inPacketsPerSecond = stats.StatsBlock[13].StatValue;
277 outPacketsPerSecond = stats.StatsBlock[14].StatValue;
278 unackedBytes = stats.StatsBlock[15].StatValue;
279 agentFrameTime = stats.StatsBlock[16].StatValue;
280 pendingDownloads = stats.StatsBlock[17].StatValue;
281 pendingUploads = stats.StatsBlock[18].StatValue;
282 activeScripts = stats.StatsBlock[19].StatValue;
283 scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
284 }
285
286 /// <summary>
287 /// Report back collected statistical information.
288 /// </summary>
289 /// <returns></returns>
290 public override string Report()
291 {
292 StringBuilder sb = new StringBuilder(Environment.NewLine);
293// sb.Append("ASSET STATISTICS");
294// sb.Append(Environment.NewLine);
295
296 /*
297 sb.Append(
298 string.Format(
299@"Asset cache contains {0,6} non-texture assets using {1,10} K
300Texture cache contains {2,6} texture assets using {3,10} K
301Latest asset request time after cache miss: {4}s
302Blocked client requests for missing textures: {5}
303Asset service request failures: {6}"+ Environment.NewLine,
304 AssetsInCache, Math.Round(AssetCacheMemoryUsage / 1024.0),
305 TexturesInCache, Math.Round(TextureCacheMemoryUsage / 1024.0),
306 assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
307 BlockedMissingTextureRequests,
308 AssetServiceRequestFailures));
309 */
310
311 /*
312 sb.Append(
313 string.Format(
314@"Asset cache contains {0,6} assets
315Latest asset request time after cache miss: {1}s
316Blocked client requests for missing textures: {2}
317Asset service request failures: {3}" + Environment.NewLine,
318 AssetsInCache,
319 assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
320 BlockedMissingTextureRequests,
321 AssetServiceRequestFailures));
322 */
323
324 sb.Append(Environment.NewLine);
325 sb.Append("CONNECTION STATISTICS");
326 sb.Append(Environment.NewLine);
327 sb.Append(
328 string.Format(
329 "Abnormal client thread terminations: {0}" + Environment.NewLine,
330 abnormalClientThreadTerminations));
331
332// sb.Append(Environment.NewLine);
333// sb.Append("INVENTORY STATISTICS");
334// sb.Append(Environment.NewLine);
335// sb.Append(
336// string.Format(
337// "Initial inventory caching failures: {0}" + Environment.NewLine,
338// InventoryServiceRetrievalFailures));
339
340 sb.Append(Environment.NewLine);
341 sb.Append("FRAME STATISTICS");
342 sb.Append(Environment.NewLine);
343 sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS");
344 sb.Append(Environment.NewLine);
345 sb.Append(
346 string.Format(
347 "{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}",
348 timeDilation, simFps, physicsFps, agentUpdates, rootAgents,
349 childAgents, totalPrims, activePrims, activeScripts, scriptLinesPerSecond));
350
351 sb.Append(Environment.NewLine);
352 sb.Append(Environment.NewLine);
353 // There is no script frame time currently because we don't yet collect it
354 sb.Append("PktsIn PktOut PendDl PendUl UnackB TotlFt NetFt PhysFt OthrFt AgntFt ImgsFt");
355 sb.Append(Environment.NewLine);
356 sb.Append(
357 string.Format(
358 "{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}",
359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
361 sb.Append(Environment.NewLine);
362
363 /*
364 sb.Append(Environment.NewLine);
365 sb.Append("PACKET QUEUE STATISTICS");
366 sb.Append(Environment.NewLine);
367 sb.Append("Agent UUID ");
368 sb.Append(
369 string.Format(
370 " {0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
371 "Send", "In", "Out", "Resend", "Land", "Wind", "Cloud", "Task", "Texture", "Asset"));
372 sb.Append(Environment.NewLine);
373
374 foreach (UUID key in packetQueueStatsCollectors.Keys)
375 {
376 sb.Append(string.Format("{0}: ", key));
377 sb.Append(packetQueueStatsCollectors[key].Report());
378 sb.Append(Environment.NewLine);
379 }
380 */
381
382 sb.Append(base.Report());
383
384 return sb.ToString();
385 }
386
387 /// <summary>
388 /// Report back collected statistical information as json serialization.
389 /// </summary>
390 /// <returns></returns>
391 public override string XReport(string uptime, string version)
392 {
393 OSDMap args = new OSDMap(30);
394// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
395// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
396// assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0));
397// args["BlockedMissingTextureRequests"] = OSD.FromString (String.Format ("{0:0.##}",
398// BlockedMissingTextureRequests));
399// args["AssetServiceRequestFailures"] = OSD.FromString (String.Format ("{0:0.##}",
400// AssetServiceRequestFailures));
401// args["abnormalClientThreadTerminations"] = OSD.FromString (String.Format ("{0:0.##}",
402// abnormalClientThreadTerminations));
403// args["InventoryServiceRetrievalFailures"] = OSD.FromString (String.Format ("{0:0.##}",
404// InventoryServiceRetrievalFailures));
405 args["Dilatn"] = OSD.FromString (String.Format ("{0:0.##}", timeDilation));
406 args["SimFPS"] = OSD.FromString (String.Format ("{0:0.##}", simFps));
407 args["PhyFPS"] = OSD.FromString (String.Format ("{0:0.##}", physicsFps));
408 args["AgntUp"] = OSD.FromString (String.Format ("{0:0.##}", agentUpdates));
409 args["RootAg"] = OSD.FromString (String.Format ("{0:0.##}", rootAgents));
410 args["ChldAg"] = OSD.FromString (String.Format ("{0:0.##}", childAgents));
411 args["Prims"] = OSD.FromString (String.Format ("{0:0.##}", totalPrims));
412 args["AtvPrm"] = OSD.FromString (String.Format ("{0:0.##}", activePrims));
413 args["AtvScr"] = OSD.FromString (String.Format ("{0:0.##}", activeScripts));
414 args["ScrLPS"] = OSD.FromString (String.Format ("{0:0.##}", scriptLinesPerSecond));
415 args["PktsIn"] = OSD.FromString (String.Format ("{0:0.##}", inPacketsPerSecond));
416 args["PktOut"] = OSD.FromString (String.Format ("{0:0.##}", outPacketsPerSecond));
417 args["PendDl"] = OSD.FromString (String.Format ("{0:0.##}", pendingDownloads));
418 args["PendUl"] = OSD.FromString (String.Format ("{0:0.##}", pendingUploads));
419 args["UnackB"] = OSD.FromString (String.Format ("{0:0.##}", unackedBytes));
420 args["TotlFt"] = OSD.FromString (String.Format ("{0:0.##}", totalFrameTime));
421 args["NetFt"] = OSD.FromString (String.Format ("{0:0.##}", netFrameTime));
422 args["PhysFt"] = OSD.FromString (String.Format ("{0:0.##}", physicsFrameTime));
423 args["OthrFt"] = OSD.FromString (String.Format ("{0:0.##}", otherFrameTime));
424 args["AgntFt"] = OSD.FromString (String.Format ("{0:0.##}", agentFrameTime));
425 args["ImgsFt"] = OSD.FromString (String.Format ("{0:0.##}", imageFrameTime));
426 args["Memory"] = OSD.FromString (base.XReport (uptime, version));
427 args["Uptime"] = OSD.FromString (uptime);
428 args["Version"] = OSD.FromString (version);
429
430 string strBuffer = "";
431 strBuffer = OSDParser.SerializeJsonString(args);
432
433 return strBuffer;
434 }
435 }
436
437 /// <summary>
438 /// Pull packet queue stats from packet queues and report
439 /// </summary>
440 public class PacketQueueStatsCollector : IStatsCollector
441 {
442 private IPullStatsProvider m_statsProvider;
443
444 public PacketQueueStatsCollector(IPullStatsProvider provider)
445 {
446 m_statsProvider = provider;
447 }
448
449 /// <summary>
450 /// Report back collected statistical information.
451 /// </summary>
452 /// <returns></returns>
453 public string Report()
454 {
455 return m_statsProvider.GetStats();
456 }
457
458 public string XReport(string uptime, string version)
459 {
460 return "";
461 }
462 }
463}
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
new file mode 100644
index 0000000..d78fa6a
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -0,0 +1,65 @@
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
28namespace OpenSim.Framework.Monitoring
29{
30 /// <summary>
31 /// Singleton used to provide access to statistics reporters
32 /// </summary>
33 public class StatsManager
34 {
35 private static AssetStatsCollector assetStats;
36 private static UserStatsCollector userStats;
37 private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
38
39 public static AssetStatsCollector AssetStats { get { return assetStats; } }
40 public static UserStatsCollector UserStats { get { return userStats; } }
41 public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
42
43 /// <summary>
44 /// Start collecting statistics related to assets.
45 /// Should only be called once.
46 /// </summary>
47 public static AssetStatsCollector StartCollectingAssetStats()
48 {
49 assetStats = new AssetStatsCollector();
50
51 return assetStats;
52 }
53
54 /// <summary>
55 /// Start collecting statistics related to users.
56 /// Should only be called once.
57 /// </summary>
58 public static UserStatsCollector StartCollectingUserStats()
59 {
60 userStats = new UserStatsCollector();
61
62 return userStats;
63 }
64 }
65} \ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/UserStatsCollector.cs b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
new file mode 100644
index 0000000..e89c8e6
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
@@ -0,0 +1,92 @@
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.Timers;
29
30namespace OpenSim.Framework.Monitoring
31{
32 /// <summary>
33 /// Collects user service statistics
34 /// </summary>
35 public class UserStatsCollector : BaseStatsCollector
36 {
37 private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
38
39 private int successfulLoginsToday;
40 public int SuccessfulLoginsToday { get { return successfulLoginsToday; } }
41
42 private int successfulLoginsYesterday;
43 public int SuccessfulLoginsYesterday { get { return successfulLoginsYesterday; } }
44
45 private int successfulLogins;
46 public int SuccessfulLogins { get { return successfulLogins; } }
47
48 private int logouts;
49 public int Logouts { get { return logouts; } }
50
51 public UserStatsCollector()
52 {
53 ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
54 ageStatsTimer.Enabled = true;
55 }
56
57 private void OnAgeing(object source, ElapsedEventArgs e)
58 {
59 successfulLoginsYesterday = successfulLoginsToday;
60
61 // There is a possibility that an asset request could occur between the execution of these
62 // two statements. But we're better off without the synchronization overhead.
63 successfulLoginsToday = 0;
64 }
65
66 /// <summary>
67 /// Record a successful login
68 /// </summary>
69 public void AddSuccessfulLogin()
70 {
71 successfulLogins++;
72 successfulLoginsToday++;
73 }
74
75 public void AddLogout()
76 {
77 logouts++;
78 }
79
80 /// <summary>
81 /// Report back collected statistical information.
82 /// </summary>
83 /// <returns></returns>
84 override public string Report()
85 {
86 return string.Format(
87@"Successful logins total : {0}, today : {1}, yesterday : {2}
88 Logouts total : {3}",
89 SuccessfulLogins, SuccessfulLoginsToday, SuccessfulLoginsYesterday, Logouts);
90 }
91 }
92}