aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorTeravus Ovares2009-01-03 03:30:03 +0000
committerTeravus Ovares2009-01-03 03:30:03 +0000
commite9cef70f892bfbf4aad0e4471a958367766d849a (patch)
tree397e078977b430526a2f04041e0dfb9a5fb99156 /OpenSim/Region
parentSplit agent updates into two messages: full update and position+camera update... (diff)
downloadopensim-SC-e9cef70f892bfbf4aad0e4471a958367766d849a.zip
opensim-SC-e9cef70f892bfbf4aad0e4471a958367766d849a.tar.gz
opensim-SC-e9cef70f892bfbf4aad0e4471a958367766d849a.tar.bz2
opensim-SC-e9cef70f892bfbf4aad0e4471a958367766d849a.tar.xz
* Updates the sim stats module. Cleans out some of the rot.
* Adds a prototype web stats module which is disabled by default. It's functional with one report right now, however, the database structure may change, so I don't recommend enabling this to keep actual stats right now. I'll let you know when it's safe. * Adds Prototype for ajaxy web content * removed a warning or two.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs4
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs78
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Environment/Scenes/SimStatsReporter.cs13
-rw-r--r--OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs185
-rw-r--r--OpenSim/Region/UserStatistics/Default_Report.cs215
-rw-r--r--OpenSim/Region/UserStatistics/HTMLUtil.cs185
-rw-r--r--OpenSim/Region/UserStatistics/IStatsReport.cs10
-rw-r--r--OpenSim/Region/UserStatistics/Prototype_distributor.cs33
-rw-r--r--OpenSim/Region/UserStatistics/SimStatsAJAX.cs190
-rw-r--r--OpenSim/Region/UserStatistics/Updater_distributor.cs35
-rw-r--r--OpenSim/Region/UserStatistics/WebStatsModule.cs1083
12 files changed, 2000 insertions, 42 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
index a698d41..29cfd99 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
@@ -603,10 +603,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
603 public void Flush() 603 public void Flush()
604 { 604 {
605 m_PacketQueue.Flush(); 605 m_PacketQueue.Flush();
606 m_UnackedBytes = (-1 * m_UnackedBytes);
607 SendPacketStats();
606 } 608 }
607 609
608 public void Clear() 610 public void Clear()
609 { 611 {
612 m_UnackedBytes = (-1 * m_UnackedBytes);
613 SendPacketStats();
610 m_NeedAck.Clear(); 614 m_NeedAck.Clear();
611 m_PendingAcks.Clear(); 615 m_PendingAcks.Clear();
612 m_Sequence += 1000000; 616 m_Sequence += 1000000;
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 408f100..daeb186 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Region.Environment.Scenes
69 69
70 protected Timer m_restartWaitTimer = new Timer(); 70 protected Timer m_restartWaitTimer = new Timer();
71 71
72 protected SimStatsReporter m_statsReporter; 72 public SimStatsReporter StatsReporter;
73 73
74 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 74 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
75 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 75 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
@@ -244,7 +244,7 @@ namespace OpenSim.Region.Environment.Scenes
244 /// </summary> 244 /// </summary>
245 public float SimulatorFPS 245 public float SimulatorFPS
246 { 246 {
247 get { return m_statsReporter.getLastReportedSimFPS(); } 247 get { return StatsReporter.getLastReportedSimFPS(); }
248 } 248 }
249 249
250 public int TimePhase 250 public int TimePhase
@@ -358,10 +358,10 @@ namespace OpenSim.Region.Environment.Scenes
358 358
359 m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics; 359 m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
360 360
361 m_statsReporter = new SimStatsReporter(this); 361 StatsReporter = new SimStatsReporter(this);
362 m_statsReporter.OnSendStatsResult += SendSimStatsPackets; 362 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
363 363
364 m_statsReporter.SetObjectCapacity(objectCapacity); 364 StatsReporter.SetObjectCapacity(objectCapacity);
365 365
366 m_simulatorVersion = simulatorVersion 366 m_simulatorVersion = simulatorVersion
367 + " (OS " + Util.GetOperatingSystemInformation() + ")" 367 + " (OS " + Util.GetOperatingSystemInformation() + ")"
@@ -814,7 +814,7 @@ namespace OpenSim.Region.Environment.Scenes
814 if (m_update_entities == 1) 814 if (m_update_entities == 1)
815 { 815 {
816 m_update_entities = 5; 816 m_update_entities = 5;
817 m_statsReporter.SetUpdateMS(6000); 817 StatsReporter.SetUpdateMS(6000);
818 } 818 }
819 } 819 }
820 else 820 else
@@ -822,7 +822,7 @@ namespace OpenSim.Region.Environment.Scenes
822 if (m_update_entities == 5) 822 if (m_update_entities == 5)
823 { 823 {
824 m_update_entities = 1; 824 m_update_entities = 1;
825 m_statsReporter.SetUpdateMS(3000); 825 StatsReporter.SetUpdateMS(3000);
826 } 826 }
827 } 827 }
828 828
@@ -891,20 +891,20 @@ namespace OpenSim.Region.Environment.Scenes
891 otherMS = System.Environment.TickCount - otherMS; 891 otherMS = System.Environment.TickCount - otherMS;
892 // if (m_frame%m_update_avatars == 0) 892 // if (m_frame%m_update_avatars == 0)
893 // UpdateInWorldTime(); 893 // UpdateInWorldTime();
894 m_statsReporter.AddPhysicsFPS(physicsFPS); 894 StatsReporter.AddPhysicsFPS(physicsFPS);
895 m_statsReporter.AddTimeDilation(m_timedilation); 895 StatsReporter.AddTimeDilation(m_timedilation);
896 m_statsReporter.AddFPS(1); 896 StatsReporter.AddFPS(1);
897 m_statsReporter.AddInPackets(0); 897 StatsReporter.AddInPackets(0);
898 m_statsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); 898 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
899 m_statsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); 899 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
900 m_statsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); 900 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
901 m_statsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); 901 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
902 frameMS = System.Environment.TickCount - frameMS; 902 frameMS = System.Environment.TickCount - frameMS;
903 m_statsReporter.addFrameMS(frameMS); 903 StatsReporter.addFrameMS(frameMS);
904 m_statsReporter.addPhysicsMS(physicsMS); 904 StatsReporter.addPhysicsMS(physicsMS);
905 m_statsReporter.addOtherMS(otherMS); 905 StatsReporter.addOtherMS(otherMS);
906 m_statsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); 906 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
907 m_statsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); 907 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
908 } 908 }
909 } 909 }
910 catch (NotImplementedException) 910 catch (NotImplementedException)
@@ -2380,8 +2380,8 @@ namespace OpenSim.Region.Environment.Scenes
2380 2380
2381 client.OnObjectOwner += ObjectOwner; 2381 client.OnObjectOwner += ObjectOwner;
2382 2382
2383 if (m_statsReporter != null) 2383 if (StatsReporter != null)
2384 client.OnNetworkStatsUpdate += m_statsReporter.AddPacketsFromClientStats; 2384 client.OnNetworkStatsUpdate += StatsReporter.AddPacketsFromClientStats;
2385 2385
2386 // EventManager.TriggerOnNewClient(client); 2386 // EventManager.TriggerOnNewClient(client);
2387 } 2387 }
@@ -3027,14 +3027,14 @@ namespace OpenSim.Region.Environment.Scenes
3027 if (presence != null) 3027 if (presence != null)
3028 { 3028 {
3029 // Nothing is removed here, so down count it as such 3029 // Nothing is removed here, so down count it as such
3030 // if (presence.IsChildAgent) 3030 if (presence.IsChildAgent)
3031 // { 3031 {
3032 // m_sceneGraph.removeUserCount(false); 3032 m_sceneGraph.removeUserCount(false);
3033 // } 3033 }
3034 // else 3034 else
3035 // { 3035 {
3036 // m_sceneGraph.removeUserCount(true); 3036 m_sceneGraph.removeUserCount(true);
3037 // } 3037 }
3038 3038
3039 // Don't do this to root agents on logout, it's not nice for the viewer 3039 // Don't do this to root agents on logout, it's not nice for the viewer
3040 if (presence.IsChildAgent) 3040 if (presence.IsChildAgent)
@@ -3322,9 +3322,9 @@ namespace OpenSim.Region.Environment.Scenes
3322 if (RegionInfo.ObjectCapacity != 0) 3322 if (RegionInfo.ObjectCapacity != 0)
3323 objects = RegionInfo.ObjectCapacity; 3323 objects = RegionInfo.ObjectCapacity;
3324 3324
3325 if (m_statsReporter != null) 3325 if (StatsReporter != null)
3326 { 3326 {
3327 m_statsReporter.SetObjectCapacity(objects); 3327 StatsReporter.SetObjectCapacity(objects);
3328 } 3328 }
3329 objectCapacity = objects; 3329 objectCapacity = objects;
3330 } 3330 }
@@ -3430,25 +3430,25 @@ namespace OpenSim.Region.Environment.Scenes
3430 3430
3431 public void AddPacketStats(int inPackets, int outPackets, int unAckedBytes) 3431 public void AddPacketStats(int inPackets, int outPackets, int unAckedBytes)
3432 { 3432 {
3433 m_statsReporter.AddInPackets(inPackets); 3433 StatsReporter.AddInPackets(inPackets);
3434 m_statsReporter.AddOutPackets(outPackets); 3434 StatsReporter.AddOutPackets(outPackets);
3435 m_statsReporter.AddunAckedBytes(unAckedBytes); 3435 StatsReporter.AddunAckedBytes(unAckedBytes);
3436 } 3436 }
3437 3437
3438 public void AddAgentTime(int ms) 3438 public void AddAgentTime(int ms)
3439 { 3439 {
3440 m_statsReporter.addFrameMS(ms); 3440 StatsReporter.addFrameMS(ms);
3441 m_statsReporter.addAgentMS(ms); 3441 StatsReporter.addAgentMS(ms);
3442 } 3442 }
3443 3443
3444 public void AddAgentUpdates(int count) 3444 public void AddAgentUpdates(int count)
3445 { 3445 {
3446 m_statsReporter.AddAgentUpdates(count); 3446 StatsReporter.AddAgentUpdates(count);
3447 } 3447 }
3448 3448
3449 public void AddPendingDownloads(int count) 3449 public void AddPendingDownloads(int count)
3450 { 3450 {
3451 m_statsReporter.addPendingDownload(count); 3451 StatsReporter.addPendingDownload(count);
3452 } 3452 }
3453 3453
3454 #endregion 3454 #endregion
diff --git a/OpenSim/Region/Environment/Scenes/SceneGraph.cs b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
index d998dbb..3ffa5c3 100644
--- a/OpenSim/Region/Environment/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
@@ -306,8 +306,19 @@ namespace OpenSim.Region.Environment.Scenes
306 if (!resultOfObjectLinked) 306 if (!resultOfObjectLinked)
307 { 307 {
308 m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; 308 m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count;
309
310 if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
311 {
312 RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count);
313 }
309 } 314 }
315
316
317
310 Entities.Remove(uuid); 318 Entities.Remove(uuid);
319 //SceneObjectGroup part;
320 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
321
311 322
312 return true; 323 return true;
313 } 324 }
diff --git a/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs b/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs
index c614f78..e2afa5a 100644
--- a/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29//using System.Collections.Generic;
29using System.Timers; 30using System.Timers;
30using OpenMetaverse.Packets; 31using OpenMetaverse.Packets;
31using OpenSim.Framework; 32using OpenSim.Framework;
@@ -189,7 +190,7 @@ namespace OpenSim.Region.Environment.Scenes
189 } 190 }
190 191
191 sb[0].StatID = (uint) Stats.TimeDilation; 192 sb[0].StatID = (uint) Stats.TimeDilation;
192 sb[0].StatValue = m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 193 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
193 194
194 sb[1].StatID = (uint) Stats.SimFPS; 195 sb[1].StatID = (uint) Stats.SimFPS;
195 sb[1].StatValue = simfps/statsUpdateFactor; 196 sb[1].StatValue = simfps/statsUpdateFactor;
@@ -253,7 +254,7 @@ namespace OpenSim.Region.Environment.Scenes
253 254
254 SimStats simStats 255 SimStats simStats
255 = new SimStats( 256 = new SimStats(
256 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)objectCapacity, rb, sb); 257 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)objectCapacity, rb, sb, m_scene.RegionInfo.originRegionID);
257 258
258 handlerSendStatResult = OnSendStatsResult; 259 handlerSendStatResult = OnSendStatsResult;
259 if (handlerSendStatResult != null) 260 if (handlerSendStatResult != null)
@@ -309,7 +310,11 @@ namespace OpenSim.Region.Environment.Scenes
309 310
310 public void SetChildAgents(int childAgents) 311 public void SetChildAgents(int childAgents)
311 { 312 {
312 m_childAgents = childAgents; 313 m_childAgents = (childAgents > 0) ? childAgents : 0;
314 if (childAgents < 0)
315 {
316 //List<ScenePresence> avs= m_scene.GetScenePresences();
317 }
313 } 318 }
314 319
315 public void SetObjects(int objects) 320 public void SetObjects(int objects)
@@ -350,6 +355,7 @@ namespace OpenSim.Region.Environment.Scenes
350 public void AddunAckedBytes(int numBytes) 355 public void AddunAckedBytes(int numBytes)
351 { 356 {
352 m_unAckedBytes += numBytes; 357 m_unAckedBytes += numBytes;
358 if (m_unAckedBytes < 0) m_unAckedBytes = 0;
353 } 359 }
354 360
355 public void addFrameMS(int ms) 361 public void addFrameMS(int ms)
@@ -383,6 +389,7 @@ namespace OpenSim.Region.Environment.Scenes
383 public void addPendingDownload(int count) 389 public void addPendingDownload(int count)
384 { 390 {
385 m_pendingDownloads += count; 391 m_pendingDownloads += count;
392 if (m_pendingDownloads < 0) m_pendingDownloads = 0;
386 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); 393 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
387 } 394 }
388 395
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
new file mode 100644
index 0000000..2dcd2b8
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
@@ -0,0 +1,185 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Reflection;
5using System.Text;
6using Mono.Data.SqliteClient;
7using OpenMetaverse;
8using OpenSim.Region.Environment.Scenes;
9using OpenSim.Framework.Statistics;
10
11namespace OpenSim.Region.UserStatistics
12{
13 public class ActiveConnectionsAJAX : IStatsController
14 {
15 #region IStatsController Members
16
17 public Hashtable ProcessModel(Hashtable pParams)
18 {
19
20 List<Scene> m_scene = (List<Scene>)pParams["Scenes"];
21
22 Hashtable nh = new Hashtable();
23 nh.Add("hdata", m_scene);
24
25 return nh;
26 }
27
28 public string RenderView(Hashtable pModelResult)
29 {
30 List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"];
31
32 StringBuilder output = new StringBuilder();
33 HTMLUtil.OL_O(ref output, "");
34 foreach (Scene scene in all_scenes)
35 {
36 List<ScenePresence> avatarInScene = scene.GetScenePresences();
37
38 HTMLUtil.LI_O(ref output, "");
39 output.Append(scene.RegionInfo.RegionName);
40 HTMLUtil.OL_O(ref output, "");
41 foreach (ScenePresence av in avatarInScene)
42 {
43 Dictionary<string,string> queues = new Dictionary<string, string>();
44 if (av.ControllingClient is IStatsCollector)
45 {
46 IStatsCollector isClient = (IStatsCollector) av.ControllingClient;
47 queues = decodeQueueReport(isClient.Report());
48 }
49 HTMLUtil.LI_O(ref output, "");
50 output.Append(av.Name);
51 output.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
52 output.Append((av.IsChildAgent ? "Child" : "Root"));
53
54 Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
55
56 HTMLUtil.UL_O(ref output, "");
57 foreach (string throttlename in throttles.Keys)
58 {
59 HTMLUtil.LI_O(ref output, "");
60 output.Append(throttlename);
61 output.Append(":");
62 output.Append(throttles[throttlename].ToString());
63 if (queues.ContainsKey(throttlename))
64 {
65 output.Append("/");
66 output.Append(queues[throttlename]);
67 }
68 HTMLUtil.LI_C(ref output);
69 }
70 if (queues.ContainsKey("Incoming") && queues.ContainsKey("Outgoing"))
71 {
72 HTMLUtil.LI_O(ref output, "red");
73 output.Append("SEND:");
74 output.Append(queues["Outgoing"]);
75 output.Append("/");
76 output.Append(queues["Incoming"]);
77 HTMLUtil.LI_C(ref output);
78 }
79
80 HTMLUtil.UL_C(ref output);
81 HTMLUtil.LI_C(ref output);
82 }
83 HTMLUtil.OL_C(ref output);
84 }
85 HTMLUtil.OL_C(ref output);
86 return output.ToString();
87 }
88
89 public Dictionary<string, int> DecodeClientThrottles(byte[] throttle)
90 {
91 Dictionary<string, int> returndict = new Dictionary<string, int>();
92 // From mantis http://opensimulator.org/mantis/view.php?id=1374
93 // it appears that sometimes we are receiving empty throttle byte arrays.
94 // TODO: Investigate this behaviour
95 if (throttle.Length == 0)
96 {
97 return new Dictionary<string, int>();
98 }
99
100 int tResend = -1;
101 int tLand = -1;
102 int tWind = -1;
103 int tCloud = -1;
104 int tTask = -1;
105 int tTexture = -1;
106 int tAsset = -1;
107 int tall = -1;
108 const int singlefloat = 4;
109
110 //Agent Throttle Block contains 7 single floatingpoint values.
111 int j = 0;
112
113 // Some Systems may be big endian...
114 // it might be smart to do this check more often...
115 if (!BitConverter.IsLittleEndian)
116 for (int i = 0; i < 7; i++)
117 Array.Reverse(throttle, j + i * singlefloat, singlefloat);
118
119 // values gotten from OpenMetaverse.org/wiki/Throttle. Thanks MW_
120 // bytes
121 // Convert to integer, since.. the full fp space isn't used.
122 tResend = (int)BitConverter.ToSingle(throttle, j);
123 returndict.Add("Resend", tResend);
124 j += singlefloat;
125 tLand = (int)BitConverter.ToSingle(throttle, j);
126 returndict.Add("Land", tLand);
127 j += singlefloat;
128 tWind = (int)BitConverter.ToSingle(throttle, j);
129 returndict.Add("Wind", tWind);
130 j += singlefloat;
131 tCloud = (int)BitConverter.ToSingle(throttle, j);
132 returndict.Add("Cloud", tCloud);
133 j += singlefloat;
134 tTask = (int)BitConverter.ToSingle(throttle, j);
135 returndict.Add("Task", tTask);
136 j += singlefloat;
137 tTexture = (int)BitConverter.ToSingle(throttle, j);
138 returndict.Add("Texture", tTexture);
139 j += singlefloat;
140 tAsset = (int)BitConverter.ToSingle(throttle, j);
141 returndict.Add("Asset", tAsset);
142
143 tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset;
144 returndict.Add("All", tall);
145
146 return returndict;
147 }
148 public Dictionary<string,string> decodeQueueReport(string rep)
149 {
150 Dictionary<string, string> returndic = new Dictionary<string, string>();
151 if (rep.Length == 79)
152 {
153 int pos = 1;
154 returndic.Add("All", rep.Substring((6 * pos), 8)); pos++;
155 returndic.Add("Incoming", rep.Substring((7 * pos), 8)); pos++;
156 returndic.Add("Outgoing", rep.Substring((7 * pos) , 8)); pos++;
157 returndic.Add("Resend", rep.Substring((7 * pos) , 8)); pos++;
158 returndic.Add("Land", rep.Substring((7 * pos) , 8)); pos++;
159 returndic.Add("Wind", rep.Substring((7 * pos) , 8)); pos++;
160 returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++;
161 returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++;
162 returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++;
163 returndic.Add("Asset", rep.Substring((7 * pos), 8));
164 /*
165 * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
166 SendQueue.Count(),
167 IncomingPacketQueue.Count,
168 OutgoingPacketQueue.Count,
169 ResendOutgoingPacketQueue.Count,
170 LandOutgoingPacketQueue.Count,
171 WindOutgoingPacketQueue.Count,
172 CloudOutgoingPacketQueue.Count,
173 TaskOutgoingPacketQueue.Count,
174 TextureOutgoingPacketQueue.Count,
175 AssetOutgoingPacketQueue.Count);
176 */
177 }
178
179
180
181 return returndic;
182 }
183 #endregion
184 }
185}
diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs
new file mode 100644
index 0000000..02b15ad
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/Default_Report.cs
@@ -0,0 +1,215 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Reflection;
5using System.Text;
6using Mono.Data.SqliteClient;
7using OpenMetaverse;
8using OpenSim.Region.Environment.Scenes;
9using OpenSim.Framework.Statistics;
10
11
12namespace OpenSim.Region.UserStatistics
13{
14 public class Default_Report : IStatsController
15 {
16
17 public Default_Report()
18 {
19
20 }
21
22 #region IStatsController Members
23
24 public Hashtable ProcessModel(Hashtable pParams)
25 {
26 SqliteConnection conn = (SqliteConnection)pParams["DatabaseConnection"];
27 List<Scene> m_scene = (List<Scene>)pParams["Scenes"];
28
29 stats_default_page_values mData = rep_DefaultReport_data(conn, m_scene);
30 mData.sim_stat_data = (Dictionary<UUID,USimStatsData>)pParams["SimStats"];
31
32 Hashtable nh = new Hashtable();
33 nh.Add("hdata", mData);
34
35 return nh;
36 }
37
38 public string RenderView(Hashtable pModelResult)
39 {
40 stats_default_page_values mData = (stats_default_page_values) pModelResult["hdata"];
41 return rep_Default_report_view(mData);
42 }
43
44 #endregion
45
46 public string rep_Default_report_view(stats_default_page_values values)
47 {
48
49 StringBuilder output = new StringBuilder();
50
51
52
53 const string TableClass = "defaultr";
54 const string TRClass = "defaultr";
55 const string TDHeaderClass = "header";
56 const string TDDataClass = "content";
57 //const string TDDataClassRight = "contentright";
58 const string TDDataClassCenter = "contentcenter";
59
60 const string STYLESHEET =
61 @"
62<STYLE>
63body
64{
65 font-size:15px; font-family:Helvetica, Verdana; color:Black;
66}
67TABLE.defaultr { }
68TR.defaultr { padding: 5px; }
69TD.header { font-weight:bold; padding:5px; }
70TD.content {}
71TD.contentright { text-align: right; }
72TD.contentcenter { text-align: center; }
73TD.align_top { vertical-align: top; }
74</STYLE>
75";
76 HTMLUtil.HtmlHeaders_O(ref output);
77
78 HTMLUtil.InsertProtoTypeAJAX(ref output);
79 string[] ajaxUpdaterDivs = new string[2];
80 int[] ajaxUpdaterSeconds = new int[2];
81 string[] ajaxUpdaterReportFragments = new string[2];
82
83 ajaxUpdaterDivs[0] = "activeconnections";
84 ajaxUpdaterSeconds[0] = 10;
85 ajaxUpdaterReportFragments[0] = "activeconnectionsajax.ajax";
86
87 ajaxUpdaterDivs[1] = "activesimstats";
88 ajaxUpdaterSeconds[1] = 20;
89 ajaxUpdaterReportFragments[1] = "simstatsajax.ajax";
90
91 HTMLUtil.InsertPeriodicUpdaters(ref output, ajaxUpdaterDivs, ajaxUpdaterSeconds, ajaxUpdaterReportFragments);
92
93 output.Append(STYLESHEET);
94 HTMLUtil.HtmlHeaders_C(ref output);
95
96 HTMLUtil.TABLE_O(ref output, TableClass);
97 HTMLUtil.TR_O(ref output, TRClass);
98 HTMLUtil.TD_O(ref output, TDHeaderClass);
99 output.Append("# Users Total");
100 HTMLUtil.TD_C(ref output);
101 HTMLUtil.TD_O(ref output, TDHeaderClass);
102 output.Append("# Sessions Total");
103 HTMLUtil.TD_C(ref output);
104 HTMLUtil.TD_O(ref output, TDHeaderClass);
105 output.Append("Avg Client FPS");
106 HTMLUtil.TD_C(ref output);
107 HTMLUtil.TD_O(ref output, TDHeaderClass);
108 output.Append("Avg Client Mem Use");
109 HTMLUtil.TD_C(ref output);
110 HTMLUtil.TD_O(ref output, TDHeaderClass);
111 output.Append("Avg Sim FPS");
112 HTMLUtil.TD_C(ref output);
113 HTMLUtil.TD_O(ref output, TDHeaderClass);
114 output.Append("Avg Ping");
115 HTMLUtil.TD_C(ref output);
116 HTMLUtil.TD_O(ref output, TDHeaderClass);
117 output.Append("KB Out Total");
118 HTMLUtil.TD_C(ref output);
119 HTMLUtil.TD_O(ref output, TDHeaderClass);
120 output.Append("KB In Total");
121 HTMLUtil.TD_C(ref output);
122 HTMLUtil.TR_C(ref output);
123 HTMLUtil.TR_O(ref output, TRClass);
124 HTMLUtil.TD_O(ref output, TDDataClass);
125 output.Append(values.total_num_users);
126 HTMLUtil.TD_C(ref output);
127 HTMLUtil.TD_O(ref output, TDDataClass);
128 output.Append(values.total_num_sessions);
129 HTMLUtil.TD_C(ref output);
130 HTMLUtil.TD_O(ref output, TDDataClassCenter);
131 output.Append(values.avg_client_fps);
132 HTMLUtil.TD_C(ref output);
133 HTMLUtil.TD_O(ref output, TDDataClassCenter);
134 output.Append(values.avg_client_mem_use);
135 HTMLUtil.TD_C(ref output);
136 HTMLUtil.TD_O(ref output, TDDataClassCenter);
137 output.Append(values.avg_sim_fps);
138 HTMLUtil.TD_C(ref output);
139 HTMLUtil.TD_O(ref output, TDDataClassCenter);
140 output.Append(values.avg_ping);
141 HTMLUtil.TD_C(ref output);
142 HTMLUtil.TD_O(ref output, TDDataClassCenter);
143 output.Append(values.total_kb_out);
144 HTMLUtil.TD_C(ref output);
145 HTMLUtil.TD_O(ref output, TDDataClassCenter);
146 output.Append(values.total_kb_in);
147 HTMLUtil.TD_C(ref output);
148 HTMLUtil.TR_C(ref output);
149 HTMLUtil.TABLE_C(ref output);
150
151 HTMLUtil.HR(ref output, "");
152 HTMLUtil.TABLE_O(ref output, "");
153 HTMLUtil.TR_O(ref output, "");
154 HTMLUtil.TD_O(ref output, "align_top");
155 output.Append("<DIV id=\"activeconnections\">loading...</DIV>");
156 HTMLUtil.TD_C(ref output);
157 HTMLUtil.TD_O(ref output, "align_top");
158 output.Append("<DIV id=\"activesimstats\">loading...</DIV>");
159
160 HTMLUtil.TD_C(ref output);
161 HTMLUtil.TR_C(ref output);
162 HTMLUtil.TABLE_C(ref output);
163 output.Append("</BODY></HTML>");
164 // TODO: FIXME: template
165 return output.ToString();
166 }
167
168
169
170 public stats_default_page_values rep_DefaultReport_data(SqliteConnection db, List<Scene> m_scene)
171 {
172 stats_default_page_values returnstruct = new stats_default_page_values();
173 returnstruct.all_scenes = m_scene.ToArray();
174 lock (db)
175 {
176 string SQL = @"SELECT COUNT(DISTINCT agent_id) as agents, COUNT(*) as sessions, AVG(avg_fps) as client_fps,
177 AVG(avg_sim_fps) as savg_sim_fps, AVG(avg_ping) as sav_ping, SUM(n_out_kb) as num_in_kb,
178 SUM(n_out_pk) as num_in_packets, SUM(n_in_kb) as num_out_kb, SUM(n_in_pk) as num_out_packets, AVG(mem_use) as sav_mem_use
179 FROM stats_session_data;";
180 SqliteCommand cmd = new SqliteCommand(SQL, db);
181 SqliteDataReader sdr = cmd.ExecuteReader();
182 if (sdr.HasRows)
183 {
184 sdr.Read();
185 returnstruct.total_num_users = Convert.ToInt32(sdr["agents"]);
186 returnstruct.total_num_sessions = Convert.ToInt32(sdr["sessions"]);
187 returnstruct.avg_client_fps = Convert.ToSingle(sdr["client_fps"]);
188 returnstruct.avg_sim_fps = Convert.ToSingle(sdr["savg_sim_fps"]);
189 returnstruct.avg_ping = Convert.ToSingle(sdr["sav_ping"]);
190 returnstruct.total_kb_out = Convert.ToSingle(sdr["num_out_kb"]);
191 returnstruct.total_kb_in = Convert.ToSingle(sdr["num_in_kb"]);
192 returnstruct.avg_client_mem_use = Convert.ToSingle(sdr["sav_mem_use"]);
193
194 }
195 }
196 return returnstruct;
197 }
198
199 }
200
201 public struct stats_default_page_values
202 {
203 public int total_num_users;
204 public int total_num_sessions;
205 public float avg_client_fps;
206 public float avg_client_mem_use;
207 public float avg_sim_fps;
208 public float avg_ping;
209 public float total_kb_out;
210 public float total_kb_in;
211 public float avg_client_resends;
212 public Scene[] all_scenes;
213 public Dictionary<UUID, USimStatsData> sim_stat_data;
214 }
215}
diff --git a/OpenSim/Region/UserStatistics/HTMLUtil.cs b/OpenSim/Region/UserStatistics/HTMLUtil.cs
new file mode 100644
index 0000000..ed8cc98
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/HTMLUtil.cs
@@ -0,0 +1,185 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace OpenSim.Region.UserStatistics
6{
7 public static class HTMLUtil
8 {
9
10 public static void TR_O(ref StringBuilder o, string pclass)
11 {
12 o.Append("<tr");
13 if (pclass.Length > 0)
14 {
15 GenericClass(ref o, pclass);
16 }
17 o.Append(">\n\t");
18 }
19 public static void TR_C(ref StringBuilder o)
20 {
21 o.Append("</tr>\n");
22 }
23
24 public static void TD_O(ref StringBuilder o, string pclass)
25 {
26 o.Append("<td");
27 if (pclass.Length > 0)
28 {
29 GenericClass(ref o, pclass);
30 }
31 o.Append(">");
32 }
33 public static void TD_C(ref StringBuilder o)
34 {
35 o.Append("</td>");
36 }
37 public static void TABLE_O(ref StringBuilder o, string pclass)
38 {
39 o.Append("<table");
40 if (pclass.Length > 0)
41 {
42 GenericClass(ref o, pclass);
43 }
44 o.Append(">\n\t");
45 }
46 public static void TABLE_C(ref StringBuilder o)
47 {
48 o.Append("</table>\n");
49 }
50
51 public static void BLOCKQUOTE_O(ref StringBuilder o, string pclass)
52 {
53 o.Append("<blockquote");
54 if (pclass.Length > 0)
55 {
56 GenericClass(ref o, pclass);
57 }
58 o.Append(" />\n");
59 }
60
61 public static void BLOCKQUOTE_C(ref StringBuilder o)
62 {
63 o.Append("</blockquote>\n");
64 }
65
66 public static void BR(ref StringBuilder o)
67 {
68 o.Append("<br />\n");
69 }
70
71 public static void HR(ref StringBuilder o, string pclass)
72 {
73 o.Append("<hr");
74 if (pclass.Length > 0)
75 {
76 GenericClass(ref o, pclass);
77 }
78 o.Append(" />\n");
79 }
80
81 public static void UL_O(ref StringBuilder o, string pclass)
82 {
83 o.Append("<ul");
84 if (pclass.Length > 0)
85 {
86 GenericClass(ref o, pclass);
87 }
88 o.Append(" />\n");
89 }
90
91 public static void UL_C(ref StringBuilder o)
92 {
93 o.Append("</ul>\n");
94 }
95
96 public static void OL_O(ref StringBuilder o, string pclass)
97 {
98 o.Append("<ol");
99 if (pclass.Length > 0)
100 {
101 GenericClass(ref o, pclass);
102 }
103 o.Append(" />\n");
104 }
105
106 public static void OL_C(ref StringBuilder o)
107 {
108 o.Append("</ol>\n");
109 }
110
111 public static void LI_O(ref StringBuilder o, string pclass)
112 {
113 o.Append("<li");
114 if (pclass.Length > 0)
115 {
116 GenericClass(ref o, pclass);
117 }
118 o.Append(" />\n");
119 }
120
121 public static void LI_C(ref StringBuilder o)
122 {
123 o.Append("</li>\n");
124 }
125
126 public static void GenericClass(ref StringBuilder o, string pclass)
127 {
128 o.Append(" class=\"");
129 o.Append(pclass);
130 o.Append("\"");
131 }
132
133 public static void InsertProtoTypeAJAX(ref StringBuilder o)
134 {
135 o.Append("<script type=\"text/javascript\" src=\"prototype.js\"></script>\n");
136 o.Append("<script type=\"text/javascript\" src=\"updater.js\"></script>\n");
137 }
138
139 public static void InsertPeriodicUpdaters(ref StringBuilder o, string[] divID, int[] seconds, string[] reportfrag)
140 {
141 o.Append("<script type=\"text/javascript\">\n");
142 o.Append(
143 @"
144 // <![CDATA[
145 document.observe('dom:loaded', function() {
146 /*
147 first arg : div to update
148 second arg : interval to poll in seconds
149 third arg : file to get data
150 */
151");
152 for (int i = 0; i < divID.Length; i++)
153 {
154
155 o.Append("new updater('");
156 o.Append(divID[i]);
157 o.Append("', ");
158 o.Append(seconds[i]);
159 o.Append(", '");
160 o.Append(reportfrag[i]);
161 o.Append("');\n");
162 }
163
164 o.Append(@"
165 });
166 // ]]>
167 </script>");
168
169 }
170
171 public static void HtmlHeaders_O ( ref StringBuilder o)
172 {
173 o.Append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
174 o.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"nl\">");
175 o.Append("<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />");
176
177
178 }
179 public static void HtmlHeaders_C ( ref StringBuilder o)
180 {
181 o.Append("</HEAD>");
182 o.Append("<BODY>");
183 }
184 }
185}
diff --git a/OpenSim/Region/UserStatistics/IStatsReport.cs b/OpenSim/Region/UserStatistics/IStatsReport.cs
new file mode 100644
index 0000000..4295c82
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/IStatsReport.cs
@@ -0,0 +1,10 @@
1using System.Collections;
2
3namespace OpenSim.Region.UserStatistics
4{
5 public interface IStatsController
6 {
7 Hashtable ProcessModel(Hashtable pParams);
8 string RenderView(Hashtable pModelResult);
9 }
10}
diff --git a/OpenSim/Region/UserStatistics/Prototype_distributor.cs b/OpenSim/Region/UserStatistics/Prototype_distributor.cs
new file mode 100644
index 0000000..8a7a18f
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/Prototype_distributor.cs
@@ -0,0 +1,33 @@
1using System;
2using System.IO;
3using System.Collections;
4using System.Collections.Generic;
5using System.Text;
6using OpenSim.Framework;
7
8namespace OpenSim.Region.UserStatistics
9{
10 public class Prototype_distributor : IStatsController
11 {
12 private string prototypejs=string.Empty;
13
14
15 public Hashtable ProcessModel(Hashtable pParams)
16 {
17 Hashtable pResult = new Hashtable();
18 if (prototypejs.Length == 0)
19 {
20 StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open));
21 prototypejs = fs.ReadToEnd();
22 }
23 pResult["js"] = prototypejs;
24 return pResult;
25 }
26
27 public string RenderView(Hashtable pModelResult)
28 {
29 return pModelResult["js"].ToString();
30 }
31
32 }
33}
diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
new file mode 100644
index 0000000..f6dd1d6
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
@@ -0,0 +1,190 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Reflection;
5using System.Text;
6using Mono.Data.SqliteClient;
7using OpenMetaverse;
8using OpenSim.Region.Environment.Scenes;
9using OpenSim.Framework.Statistics;
10
11namespace OpenSim.Region.UserStatistics
12{
13 public class SimStatsAJAX : IStatsController
14 {
15 #region IStatsController Members
16
17 public Hashtable ProcessModel(Hashtable pParams)
18 {
19 List<Scene> m_scene = (List<Scene>)pParams["Scenes"];
20
21 Hashtable nh = new Hashtable();
22 nh.Add("hdata", m_scene);
23 nh.Add("simstats", pParams["SimStats"]);
24
25 return nh;
26 }
27
28 public string RenderView(Hashtable pModelResult)
29 {
30 StringBuilder output = new StringBuilder();
31 List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"];
32 Dictionary<UUID, USimStatsData> sdatadic = (Dictionary<UUID,USimStatsData>)pModelResult["simstats"];
33
34 const string TableClass = "defaultr";
35 const string TRClass = "defaultr";
36 const string TDHeaderClass = "header";
37 const string TDDataClass = "content";
38 //const string TDDataClassRight = "contentright";
39 const string TDDataClassCenter = "contentcenter";
40
41 foreach (USimStatsData sdata in sdatadic.Values)
42 {
43
44
45 foreach (Scene sn in all_scenes)
46 {
47 if (sn.RegionInfo.RegionID == sdata.RegionId)
48 {
49 output.Append("<H2>");
50 output.Append(sn.RegionInfo.RegionName);
51 output.Append("</H2>");
52 }
53 }
54 HTMLUtil.TABLE_O(ref output, TableClass);
55 HTMLUtil.TR_O(ref output, TRClass);
56 HTMLUtil.TD_O(ref output, TDHeaderClass);
57 output.Append("Dilatn");
58 HTMLUtil.TD_C(ref output);
59 HTMLUtil.TD_O(ref output, TDHeaderClass);
60 output.Append("SimFPS");
61 HTMLUtil.TD_C(ref output);
62 HTMLUtil.TD_O(ref output, TDHeaderClass);
63 output.Append("PhysFPS");
64 HTMLUtil.TD_C(ref output);
65 HTMLUtil.TD_O(ref output, TDHeaderClass);
66 output.Append("AgntUp");
67 HTMLUtil.TD_C(ref output);
68 HTMLUtil.TD_O(ref output, TDHeaderClass);
69 output.Append("RootAg");
70 HTMLUtil.TD_C(ref output);
71 HTMLUtil.TD_O(ref output, TDHeaderClass);
72 output.Append("ChldAg");
73 HTMLUtil.TD_C(ref output);
74 HTMLUtil.TD_O(ref output, TDHeaderClass);
75 output.Append("Prims");
76 HTMLUtil.TD_C(ref output);
77 HTMLUtil.TD_O(ref output, TDHeaderClass);
78 output.Append("ATvPrm");
79 HTMLUtil.TD_C(ref output);
80 HTMLUtil.TD_O(ref output, TDHeaderClass);
81 output.Append("AtvScr");
82 HTMLUtil.TD_C(ref output);
83 HTMLUtil.TD_O(ref output, TDHeaderClass);
84 output.Append("ScrLPS");
85 HTMLUtil.TD_C(ref output);
86 HTMLUtil.TR_C(ref output);
87 HTMLUtil.TR_O(ref output, TRClass);
88 HTMLUtil.TD_O(ref output, TDDataClass);
89 output.Append(sdata.TimeDilation);
90 HTMLUtil.TD_C(ref output);
91 HTMLUtil.TD_O(ref output, TDDataClass);
92 output.Append(sdata.SimFps);
93 HTMLUtil.TD_C(ref output);
94 HTMLUtil.TD_O(ref output, TDDataClassCenter);
95 output.Append(sdata.PhysicsFps);
96 HTMLUtil.TD_C(ref output);
97 HTMLUtil.TD_O(ref output, TDDataClassCenter);
98 output.Append(sdata.AgentUpdates);
99 HTMLUtil.TD_C(ref output);
100 HTMLUtil.TD_O(ref output, TDDataClassCenter);
101 output.Append(sdata.RootAgents);
102 HTMLUtil.TD_C(ref output);
103 HTMLUtil.TD_O(ref output, TDDataClassCenter);
104 output.Append(sdata.ChildAgents);
105 HTMLUtil.TD_C(ref output);
106 HTMLUtil.TD_O(ref output, TDDataClassCenter);
107 output.Append(sdata.TotalPrims);
108 HTMLUtil.TD_C(ref output);
109 HTMLUtil.TD_O(ref output, TDDataClassCenter);
110 output.Append(sdata.ActivePrims);
111 HTMLUtil.TD_C(ref output);
112 HTMLUtil.TD_O(ref output, TDDataClassCenter);
113 output.Append(sdata.ActiveScripts);
114 HTMLUtil.TD_C(ref output);
115 HTMLUtil.TD_O(ref output, TDDataClassCenter);
116 output.Append(sdata.ScriptLinesPerSecond);
117 HTMLUtil.TD_C(ref output);
118 HTMLUtil.TR_C(ref output);
119 HTMLUtil.TR_O(ref output, TRClass);
120 HTMLUtil.TD_O(ref output, TDHeaderClass);
121 output.Append("FrmMS");
122 HTMLUtil.TD_C(ref output);
123 HTMLUtil.TD_O(ref output, TDHeaderClass);
124 output.Append("AgtMS");
125 HTMLUtil.TD_C(ref output);
126 HTMLUtil.TD_O(ref output, TDHeaderClass);
127 output.Append("PhysMS");
128 HTMLUtil.TD_C(ref output);
129 HTMLUtil.TD_O(ref output, TDHeaderClass);
130 output.Append("OthrMS");
131 HTMLUtil.TD_C(ref output);
132 HTMLUtil.TD_O(ref output, TDHeaderClass);
133 output.Append("ScrLPS");
134 HTMLUtil.TD_C(ref output);
135 HTMLUtil.TD_O(ref output, TDHeaderClass);
136 output.Append("OutPPS");
137 HTMLUtil.TD_C(ref output);
138 HTMLUtil.TD_O(ref output, TDHeaderClass);
139 output.Append("InPPS");
140 HTMLUtil.TD_C(ref output);
141 HTMLUtil.TD_O(ref output, TDHeaderClass);
142 output.Append("NoAckKB");
143 HTMLUtil.TD_C(ref output);
144 HTMLUtil.TD_O(ref output, TDHeaderClass);
145 output.Append("PndDWN");
146 HTMLUtil.TD_C(ref output);
147 HTMLUtil.TD_O(ref output, TDHeaderClass);
148 output.Append("PndUP");
149 HTMLUtil.TD_C(ref output);
150 HTMLUtil.TR_C(ref output);
151 HTMLUtil.TR_O(ref output, TRClass);
152 HTMLUtil.TD_O(ref output, TDDataClass);
153 output.Append(sdata.TotalFrameTime);
154 HTMLUtil.TD_C(ref output);
155 HTMLUtil.TD_O(ref output, TDDataClass);
156 output.Append(sdata.AgentFrameTime);
157 HTMLUtil.TD_C(ref output);
158 HTMLUtil.TD_O(ref output, TDDataClassCenter);
159 output.Append(sdata.PhysicsFrameTime);
160 HTMLUtil.TD_C(ref output);
161 HTMLUtil.TD_O(ref output, TDDataClassCenter);
162 output.Append(sdata.OtherFrameTime);
163 HTMLUtil.TD_C(ref output);
164 HTMLUtil.TD_O(ref output, TDDataClassCenter);
165 output.Append(sdata.ScriptLinesPerSecond);
166 HTMLUtil.TD_C(ref output);
167 HTMLUtil.TD_O(ref output, TDDataClassCenter);
168 output.Append(sdata.OutPacketsPerSecond);
169 HTMLUtil.TD_C(ref output);
170 HTMLUtil.TD_O(ref output, TDDataClassCenter);
171 output.Append(sdata.InPacketsPerSecond);
172 HTMLUtil.TD_C(ref output);
173 HTMLUtil.TD_O(ref output, TDDataClassCenter);
174 output.Append(sdata.UnackedBytes);
175 HTMLUtil.TD_C(ref output);
176 HTMLUtil.TD_O(ref output, TDDataClassCenter);
177 output.Append(sdata.PendingDownloads);
178 HTMLUtil.TD_C(ref output);
179 HTMLUtil.TD_O(ref output, TDDataClassCenter);
180 output.Append(sdata.PendingUploads);
181 HTMLUtil.TD_C(ref output);
182 HTMLUtil.TR_C(ref output);
183 HTMLUtil.TABLE_C(ref output);
184 }
185 return output.ToString();
186 }
187
188 #endregion
189 }
190}
diff --git a/OpenSim/Region/UserStatistics/Updater_distributor.cs b/OpenSim/Region/UserStatistics/Updater_distributor.cs
new file mode 100644
index 0000000..4d571fa
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/Updater_distributor.cs
@@ -0,0 +1,35 @@
1using System;
2using System.IO;
3using System.Collections;
4using System.Collections.Generic;
5using System.Text;
6using OpenSim.Framework;
7
8namespace OpenSim.Region.UserStatistics
9{
10 public class Updater_distributor : IStatsController
11 {
12 private string updaterjs = string.Empty;
13
14
15 public Hashtable ProcessModel(Hashtable pParams)
16 {
17 Hashtable pResult = new Hashtable();
18 if (updaterjs.Length == 0)
19 {
20 StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/updater.js", FileMode.Open));
21 updaterjs = fs.ReadToEnd();
22 fs.Close();
23 fs.Dispose();
24 }
25 pResult["js"] = updaterjs;
26 return pResult;
27 }
28
29 public string RenderView(Hashtable pModelResult)
30 {
31 return pModelResult["js"].ToString();
32 }
33
34 }
35} \ No newline at end of file
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs
new file mode 100644
index 0000000..4eb8cb7
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs
@@ -0,0 +1,1083 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Net; // to be used for REST-->Grid shortly
5using System.Reflection;
6using log4net;
7using Nini.Config;
8using OpenMetaverse;
9using OpenMetaverse.StructuredData;
10using OpenSim.Framework;
11using OpenSim.Framework.Servers;
12using OpenSim.Region.Environment.Interfaces;
13using OpenSim.Region.Environment.Scenes;
14using Mono.Data.SqliteClient;
15
16
17using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
18
19using OSD = OpenMetaverse.StructuredData.OSD;
20using OSDMap = OpenMetaverse.StructuredData.OSDMap;
21
22namespace OpenSim.Region.UserStatistics
23{
24 public class WebStatsModule : IRegionModule
25 {
26 private static readonly ILog m_log =
27 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
28 private static SqliteConnection dbConn;
29 private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>();
30 private List<Scene> m_scene = new List<Scene>();
31 private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>();
32 private Dictionary<UUID, USimStatsData> m_simstatsCounters = new Dictionary<UUID, USimStatsData>();
33 private const int updateStatsMod = 6;
34 private volatile int concurrencyCounter = 0;
35 private bool enabled = false;
36
37
38 public virtual void Initialise(Scene scene, IConfigSource config)
39 {
40 IConfig cnfg;
41 try
42 {
43 cnfg = config.Configs["WebStats"];
44 enabled = cnfg.GetBoolean("enabled", false);
45
46 }
47 catch (Exception)
48 {
49 enabled = false;
50 }
51 if (!enabled)
52 {
53 return;
54 }
55
56 lock (m_scene)
57 {
58 if (m_scene.Count == 0)
59 {
60 IConfig startupConfig = config.Configs["Startup"];
61
62 dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3");
63 dbConn.Open();
64 CheckAndUpdateDatabase(dbConn);
65
66 Default_Report rep = new Default_Report();
67 Prototype_distributor protodep = new Prototype_distributor();
68 Updater_distributor updatedep = new Updater_distributor();
69 ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX();
70 SimStatsAJAX ajSimStats = new SimStatsAJAX();
71 reports.Add("", rep);
72 reports.Add("index.aspx", rep);
73 reports.Add("prototype.js", protodep);
74 reports.Add("updater.js", updatedep);
75 reports.Add("activeconnectionsajax.ajax", ajConnections);
76 reports.Add("simstatsajax.ajax", ajSimStats);
77
78 scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest);
79
80
81 }
82 m_scene.Add(scene);
83 m_simstatsCounters.Add(scene.RegionInfo.RegionID, new USimStatsData(scene.RegionInfo.RegionID));
84 scene.StatsReporter.OnSendStatsResult += ReceiveClassicSimStatsPacket;
85 }
86
87 }
88
89 public void ReceiveClassicSimStatsPacket(SimStats stats)
90 {
91 if (!enabled)
92 {
93 return;
94 }
95
96 try
97 {
98
99 if (concurrencyCounter > 0)
100 return;
101
102 USimStatsData ss = m_simstatsCounters[stats.RegionUUID];
103
104 if ((++ss.StatsCounter % updateStatsMod) == 0)
105 {
106 ss.ConsumeSimStats(stats);
107 }
108 }
109 catch (KeyNotFoundException)
110 {
111
112 }
113 }
114
115 public Hashtable HandleStatsRequest(Hashtable request)
116 {
117 Hashtable responsedata = new Hashtable();
118 string regpath = request["uri"].ToString();
119 int response_code = 404;
120 string contenttype = "text/html";
121
122 string strOut = string.Empty;
123
124 regpath = regpath.Remove(0, 8);
125 if (reports.ContainsKey(regpath))
126 {
127 IStatsController rep = reports[regpath];
128 Hashtable repParams = new Hashtable();
129
130 repParams["DatabaseConnection"] = dbConn;
131 repParams["Scenes"] = m_scene;
132 repParams["SimStats"] = m_simstatsCounters;
133
134 concurrencyCounter++;
135
136 strOut = rep.RenderView(rep.ProcessModel(repParams));
137
138 if (regpath.EndsWith("js"))
139 {
140 contenttype = "text/javascript";
141 }
142
143 concurrencyCounter--;
144
145 response_code = 200;
146
147 }
148 else
149 {
150 strOut = m_scene[0].CommsManager.HttpServer.GetHTTP404("");
151 }
152
153
154 responsedata["int_response_code"] = response_code;
155 responsedata["content_type"] = contenttype;
156 responsedata["keepalive"] = false;
157 responsedata["str_response_string"] = strOut;
158
159 return responsedata;
160 }
161
162
163
164 public void CheckAndUpdateDatabase(SqliteConnection db)
165 {
166 lock (db)
167 {
168 // TODO: FIXME: implement stats migrations
169 const string SQL = @"SELECT * FROM migrations LIMIT 1";
170
171 SqliteCommand cmd = new SqliteCommand(SQL, db);
172
173 try
174 {
175 cmd.ExecuteNonQuery();
176 }
177 catch (SqliteSyntaxException)
178 {
179 CreateTables(db);
180 }
181 }
182
183 }
184
185 public void CreateTables(SqliteConnection db)
186 {
187 SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db);
188 createcmd.ExecuteNonQuery();
189
190 createcmd.CommandText = SQL_MIGRA_TABLE_CREATE;
191 createcmd.ExecuteNonQuery();
192 }
193
194
195
196 public virtual void PostInitialise()
197 {
198 if (!enabled)
199 {
200 return;
201 }
202 AddHandlers();
203 }
204
205 public virtual void Close()
206 {
207 if (!enabled)
208 {
209 return;
210 }
211 dbConn.Close();
212 dbConn.Dispose();
213 }
214
215 public virtual string Name
216 {
217 get { return "ViewerStatsModule"; }
218 }
219
220 public bool IsSharedModule
221 {
222 get { return true; }
223 }
224
225 public void OnRegisterCaps(UUID agentID, Caps caps)
226 {
227 m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
228 string capsPath = "/CAPS/VS/" + UUID.Random();
229 caps.RegisterHandler("ViewerStats",
230 new RestStreamHandler("POST", capsPath,
231 delegate(string request, string path, string param,
232 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
233 {
234 return ViewerStatsReport(request, path, param,
235 agentID, caps);
236 }));
237 }
238
239 public void OnDeRegisterCaps(UUID agentID, Caps caps)
240 {
241
242 }
243
244 protected virtual void AddHandlers()
245 {
246 lock (m_scene)
247 {
248 foreach (Scene scene in m_scene)
249 {
250 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
251 scene.EventManager.OnDeregisterCaps += OnDeRegisterCaps;
252 scene.EventManager.OnClientClosed += OnClientClosed;
253 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
254 scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
255 }
256 }
257 }
258
259 public void OnMakeRootAgent(ScenePresence agent)
260 {
261 UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle);
262
263 lock (m_sessions)
264 {
265 if (!m_sessions.ContainsKey(agent.UUID))
266 {
267 UserSessionData usd = UserSessionUtil.newUserSessionData();
268
269 UserSessionID uid = new UserSessionID();
270 uid.name_f = agent.Firstname;
271 uid.name_l = agent.Lastname;
272 uid.region_id = regionUUID;
273 uid.session_id = agent.ControllingClient.SessionId;
274 uid.session_data = usd;
275
276 m_sessions.Add(agent.UUID, uid);
277 }
278 else
279 {
280 UserSessionID uid = m_sessions[agent.UUID];
281 uid.region_id = regionUUID;
282 uid.session_id = agent.ControllingClient.SessionId;
283 m_sessions[agent.UUID] = uid;
284 }
285 }
286 }
287
288
289
290
291 public void OnMakeChildAgent(ScenePresence agent)
292 {
293 lock (m_sessions)
294 {
295 if (m_sessions.ContainsKey(agent.UUID))
296 {
297 if (m_sessions[agent.UUID].region_id == GetRegionUUIDFromHandle(agent.RegionHandle))
298 {
299 m_sessions.Remove(agent.UUID);
300 }
301 }
302 }
303 }
304
305
306 public void OnClientClosed(UUID agentID)
307 {
308 lock (m_sessions)
309 {
310 if (m_sessions.ContainsKey(agentID))
311 {
312 m_sessions.Remove(agentID);
313 }
314 }
315
316 }
317
318 public UUID GetRegionUUIDFromHandle(ulong regionhandle)
319 {
320 lock (m_scene)
321 {
322 foreach (Scene scene in m_scene)
323 {
324 if (scene.RegionInfo.RegionHandle == regionhandle)
325 return scene.RegionInfo.RegionID;
326 }
327 }
328 return UUID.Zero;
329 }
330 /// <summary>
331 /// Callback for a viewerstats cap
332 /// </summary>
333 /// <param name="request"></param>
334 /// <param name="path"></param>
335 /// <param name="param"></param>
336 /// <param name="agentID"></param>
337 /// <param name="caps"></param>
338 /// <returns></returns>
339 public string ViewerStatsReport(string request, string path, string param,
340 UUID agentID, Caps caps)
341 {
342 m_log.Debug(request);
343 UserSessionID uid;
344 UserSessionData usd;
345
346 lock (m_sessions)
347 {
348 if (!m_sessions.ContainsKey(agentID))
349 {
350 m_log.Warn("[VS]: no session for stat disclosure");
351 return string.Empty;
352 }
353 uid = m_sessions[agentID];
354 }
355
356 usd = uid.session_data;
357
358 OSD message = OSDParser.DeserializeLLSDXml(request);
359 if (message.Type != OSDType.Map)
360 return String.Empty;
361
362 OSDMap mmap = (OSDMap) message;
363 {
364 if (mmap["agent"].Type != OSDType.Map)
365 return String.Empty;
366 OSDMap agent_map = (OSDMap) mmap["agent"];
367 usd.agent_id = agentID;
368 usd.name_f = uid.name_f;
369 usd.name_l = uid.name_l;
370 usd.region_id = uid.region_id;
371 usd.a_language = agent_map["language"].AsString();
372 usd.mem_use = (float) agent_map["mem_use"].AsReal();
373 usd.meters_traveled = (float) agent_map["meters_traveled"].AsReal();
374 usd.regions_visited = agent_map["regions_visited"].AsInteger();
375 usd.run_time = (float) agent_map["run_time"].AsReal();
376 usd.start_time = (float) agent_map["start_time"].AsReal();
377 usd.client_version = agent_map["version"].AsString();
378
379 UserSessionUtil.UpdateMultiItems(ref usd, agent_map["agents_in_view"].AsInteger(),
380 (float) agent_map["ping"].AsReal(),
381 (float) agent_map["sim_fps"].AsReal(),
382 (float) agent_map["fps"].AsReal());
383
384 if (mmap["downloads"].Type != OSDType.Map)
385 return String.Empty;
386 OSDMap downloads_map = (OSDMap) mmap["downloads"];
387 usd.d_object_kb = (float) downloads_map["object_kbytes"].AsReal();
388 usd.d_texture_kb = (float) downloads_map["texture_kbytes"].AsReal();
389 usd.d_world_kb = (float) downloads_map["workd_kbytes"].AsReal();
390
391
392 usd.session_id = mmap["session_id"].AsUUID();
393
394 if (mmap["system"].Type != OSDType.Map)
395 return String.Empty;
396 OSDMap system_map = (OSDMap) mmap["system"];
397
398 usd.s_cpu = system_map["cpu"].AsString();
399 usd.s_gpu = system_map["gpu"].AsString();
400 usd.s_os = system_map["os"].AsString();
401 usd.s_ram = system_map["ram"].AsInteger();
402
403 if (mmap["stats"].Type != OSDType.Map)
404 return String.Empty;
405
406 OSDMap stats_map = (OSDMap) mmap["stats"];
407 {
408 if (mmap["failures"].Type != OSDType.Map)
409 return String.Empty;
410 OSDMap stats_failures = (OSDMap) stats_map["failures"];
411 usd.f_dropped = stats_failures["dropped"].AsInteger();
412 usd.f_failed_resends = stats_failures["failed_resends"].AsInteger();
413 usd.f_invalid = stats_failures["invalid"].AsInteger();
414 usd.f_resent = stats_failures["resent"].AsInteger();
415 usd.f_send_packet = stats_failures["send_packet"].AsInteger();
416
417 if (mmap["net"].Type != OSDType.Map)
418 return String.Empty;
419 OSDMap stats_net = (OSDMap) stats_map["net"];
420 {
421 if (mmap["in"].Type != OSDType.Map)
422 return String.Empty;
423
424 OSDMap net_in = (OSDMap) stats_net["in"];
425 usd.n_in_kb = (float) net_in["kbytes"].AsReal();
426 usd.n_in_pk = net_in["packets"].AsInteger();
427
428 if (mmap["out"].Type != OSDType.Map)
429 return String.Empty;
430 OSDMap net_out = (OSDMap) stats_net["out"];
431
432 usd.n_out_kb = (float) net_out["kbytes"].AsReal();
433 usd.n_out_pk = net_out["packets"].AsInteger();
434 }
435
436
437 }
438 }
439
440 uid.session_data = usd;
441 m_sessions[agentID] = uid;
442 UpdateUserStats(uid, dbConn);
443
444 return String.Empty;
445 }
446
447 public void UpdateUserStats(UserSessionID uid, SqliteConnection db)
448 {
449 lock (db)
450 {
451 SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db);
452 updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString()));
453 updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString()));
454 updatecmd.Parameters.Add(new SqliteParameter(":region_id", uid.session_data.region_id.ToString()));
455 updatecmd.Parameters.Add(new SqliteParameter(":last_updated", (int) uid.session_data.last_updated));
456 updatecmd.Parameters.Add(new SqliteParameter(":remote_ip", uid.session_data.remote_ip));
457 updatecmd.Parameters.Add(new SqliteParameter(":name_f", uid.session_data.name_f));
458 updatecmd.Parameters.Add(new SqliteParameter(":name_l", uid.session_data.name_l));
459 updatecmd.Parameters.Add(new SqliteParameter(":avg_agents_in_view", uid.session_data.avg_agents_in_view));
460 updatecmd.Parameters.Add(new SqliteParameter(":min_agents_in_view",
461 (int) uid.session_data.min_agents_in_view));
462 updatecmd.Parameters.Add(new SqliteParameter(":max_agents_in_view",
463 (int) uid.session_data.max_agents_in_view));
464 updatecmd.Parameters.Add(new SqliteParameter(":mode_agents_in_view",
465 (int) uid.session_data.mode_agents_in_view));
466 updatecmd.Parameters.Add(new SqliteParameter(":avg_fps", uid.session_data.avg_fps));
467 updatecmd.Parameters.Add(new SqliteParameter(":min_fps", uid.session_data.min_fps));
468 updatecmd.Parameters.Add(new SqliteParameter(":max_fps", uid.session_data.max_fps));
469 updatecmd.Parameters.Add(new SqliteParameter(":mode_fps", uid.session_data.mode_fps));
470 updatecmd.Parameters.Add(new SqliteParameter(":a_language", uid.session_data.a_language));
471 updatecmd.Parameters.Add(new SqliteParameter(":mem_use", uid.session_data.mem_use));
472 updatecmd.Parameters.Add(new SqliteParameter(":meters_traveled", uid.session_data.meters_traveled));
473 updatecmd.Parameters.Add(new SqliteParameter(":avg_ping", uid.session_data.avg_ping));
474 updatecmd.Parameters.Add(new SqliteParameter(":min_ping", uid.session_data.min_ping));
475 updatecmd.Parameters.Add(new SqliteParameter(":max_ping", uid.session_data.max_ping));
476 updatecmd.Parameters.Add(new SqliteParameter(":mode_ping", uid.session_data.mode_ping));
477 updatecmd.Parameters.Add(new SqliteParameter(":regions_visited", uid.session_data.regions_visited));
478 updatecmd.Parameters.Add(new SqliteParameter(":run_time", uid.session_data.run_time));
479 updatecmd.Parameters.Add(new SqliteParameter(":avg_sim_fps", uid.session_data.avg_sim_fps));
480 updatecmd.Parameters.Add(new SqliteParameter(":min_sim_fps", uid.session_data.min_sim_fps));
481 updatecmd.Parameters.Add(new SqliteParameter(":max_sim_fps", uid.session_data.max_sim_fps));
482 updatecmd.Parameters.Add(new SqliteParameter(":mode_sim_fps", uid.session_data.mode_sim_fps));
483 updatecmd.Parameters.Add(new SqliteParameter(":start_time", uid.session_data.start_time));
484 updatecmd.Parameters.Add(new SqliteParameter(":client_version", uid.session_data.client_version));
485 updatecmd.Parameters.Add(new SqliteParameter(":s_cpu", uid.session_data.s_cpu));
486 updatecmd.Parameters.Add(new SqliteParameter(":s_gpu", uid.session_data.s_gpu));
487 updatecmd.Parameters.Add(new SqliteParameter(":s_os", uid.session_data.s_os));
488 updatecmd.Parameters.Add(new SqliteParameter(":s_ram", uid.session_data.s_ram));
489 updatecmd.Parameters.Add(new SqliteParameter(":d_object_kb", uid.session_data.d_object_kb));
490 updatecmd.Parameters.Add(new SqliteParameter(":d_texture_kb", uid.session_data.d_texture_kb));
491 updatecmd.Parameters.Add(new SqliteParameter(":d_world_kb", uid.session_data.d_world_kb));
492 updatecmd.Parameters.Add(new SqliteParameter(":n_in_kb", uid.session_data.n_in_kb));
493 updatecmd.Parameters.Add(new SqliteParameter(":n_in_pk", uid.session_data.n_in_pk));
494 updatecmd.Parameters.Add(new SqliteParameter(":n_out_kb", uid.session_data.n_out_kb));
495 updatecmd.Parameters.Add(new SqliteParameter(":n_out_pk", uid.session_data.n_out_pk));
496 updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped));
497 updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends));
498 updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid));
499
500 updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit));
501 updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent));
502 updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet));
503
504 updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString()));
505 updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString()));
506 updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString()));
507 m_log.Debug("UPDATE");
508
509 int result = updatecmd.ExecuteNonQuery();
510
511 if (result == 0)
512 {
513 m_log.Debug("INSERT");
514 updatecmd.CommandText = SQL_STATS_TABLE_INSERT;
515 updatecmd.ExecuteNonQuery();
516 }
517 }
518
519 }
520
521 #region SQL
522 private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)";
523
524 private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data (
525 session_id VARCHAR(36) NOT NULL PRIMARY KEY,
526 agent_id VARCHAR(36) NOT NULL DEFAULT '',
527 region_id VARCHAR(36) NOT NULL DEFAULT '',
528 last_updated INT NOT NULL DEFAULT '0',
529 remote_ip VARCHAR(16) NOT NULL DEFAULT '',
530 name_f VARCHAR(50) NOT NULL DEFAULT '',
531 name_l VARCHAR(50) NOT NULL DEFAULT '',
532 avg_agents_in_view FLOAT NOT NULL DEFAULT '0',
533 min_agents_in_view INT NOT NULL DEFAULT '0',
534 max_agents_in_view INT NOT NULL DEFAULT '0',
535 mode_agents_in_view INT NOT NULL DEFAULT '0',
536 avg_fps FLOAT NOT NULL DEFAULT '0',
537 min_fps FLOAT NOT NULL DEFAULT '0',
538 max_fps FLOAT NOT NULL DEFAULT '0',
539 mode_fps FLOAT NOT NULL DEFAULT '0',
540 a_language VARCHAR(25) NOT NULL DEFAULT '',
541 mem_use FLOAT NOT NULL DEFAULT '0',
542 meters_traveled FLOAT NOT NULL DEFAULT '0',
543 avg_ping FLOAT NOT NULL DEFAULT '0',
544 min_ping FLOAT NOT NULL DEFAULT '0',
545 max_ping FLOAT NOT NULL DEFAULT '0',
546 mode_ping FLOAT NOT NULL DEFAULT '0',
547 regions_visited INT NOT NULL DEFAULT '0',
548 run_time FLOAT NOT NULL DEFAULT '0',
549 avg_sim_fps FLOAT NOT NULL DEFAULT '0',
550 min_sim_fps FLOAT NOT NULL DEFAULT '0',
551 max_sim_fps FLOAT NOT NULL DEFAULT '0',
552 mode_sim_fps FLOAT NOT NULL DEFAULT '0',
553 start_time FLOAT NOT NULL DEFAULT '0',
554 client_version VARCHAR(255) NOT NULL DEFAULT '',
555 s_cpu VARCHAR(255) NOT NULL DEFAULT '',
556 s_gpu VARCHAR(255) NOT NULL DEFAULT '',
557 s_os VARCHAR(2255) NOT NULL DEFAULT '',
558 s_ram INT NOT NULL DEFAULT '0',
559 d_object_kb FLOAT NOT NULL DEFAULT '0',
560 d_texture_kb FLOAT NOT NULL DEFAULT '0',
561 d_world_kb FLOAT NOT NULL DEFAULT '0',
562 n_in_kb FLOAT NOT NULL DEFAULT '0',
563 n_in_pk INT NOT NULL DEFAULT '0',
564 n_out_kb FLOAT NOT NULL DEFAULT '0',
565 n_out_pk INT NOT NULL DEFAULT '0',
566 f_dropped INT NOT NULL DEFAULT '0',
567 f_failed_resends INT NOT NULL DEFAULT '0',
568 f_invalid INT NOT NULL DEFAULT '0',
569 f_off_circuit INT NOT NULL DEFAULT '0',
570 f_resent INT NOT NULL DEFAULT '0',
571 f_send_packet INT NOT NULL DEFAULT '0'
572 );";
573
574 private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data (
575session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view,
576mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping,
577regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram,
578d_object_kb, d_texture_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_invalid, f_off_circuit,
579f_resent, f_send_packet
580)
581VALUES
582(
583:session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view,
584:mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping,
585:regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram,
586:d_object_kb, :d_texture_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_invalid, :f_off_circuit,
587:f_resent, :f_send_packet
588)
589";
590
591 private const string SQL_STATS_TABLE_UPDATE = @"
592UPDATE stats_session_data
593set session_id=:session_id,
594 agent_id=:agent_id,
595 region_id=:region_id,
596 last_updated=:last_updated,
597 remote_ip=:remote_ip,
598 name_f=:name_f,
599 name_l=:name_l,
600 avg_agents_in_view=:avg_agents_in_view,
601 min_agents_in_view=:min_agents_in_view,
602 max_agents_in_view=:max_agents_in_view,
603 mode_agents_in_view=:mode_agents_in_view,
604 avg_fps=:avg_fps,
605 min_fps=:min_fps,
606 max_fps=:max_fps,
607 mode_fps=:mode_fps,
608 a_language=:a_language,
609 mem_use=:mem_use,
610 meters_traveled=:meters_traveled,
611 avg_ping=:avg_ping,
612 min_ping=:min_ping,
613 max_ping=:max_ping,
614 mode_ping=:mode_ping,
615 regions_visited=:regions_visited,
616 run_time=:run_time,
617 avg_sim_fps=:avg_sim_fps,
618 min_sim_fps=:min_sim_fps,
619 max_sim_fps=:max_sim_fps,
620 mode_sim_fps=:mode_sim_fps,
621 start_time=:start_time,
622 client_version=:client_version,
623 s_cpu=:s_cpu,
624 s_gpu=:s_gpu,
625 s_os=:s_os,
626 s_ram=:s_ram,
627 d_object_kb=:d_object_kb,
628 d_texture_kb=:d_texture_kb,
629 d_world_kb=:d_world_kb,
630 n_in_kb=:n_in_kb,
631 n_in_pk=:n_in_pk,
632 n_out_kb=:n_out_kb,
633 n_out_pk=:n_out_pk,
634 f_dropped=:f_dropped,
635 f_failed_resends=:f_failed_resends,
636 f_invalid=:f_invalid,
637 f_off_circuit=:f_off_circuit,
638 f_resent=:f_resent,
639 f_send_packet=:f_send_packet
640WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key";
641 #endregion
642 }
643 public static class UserSessionUtil
644 {
645 public static UserSessionData newUserSessionData()
646 {
647 UserSessionData obj = ZeroSession(new UserSessionData());
648 return obj;
649 }
650
651 public static void UpdateMultiItems(ref UserSessionData s, int agents_in_view, float ping, float sim_fps, float fps)
652 {
653 // don't insert zero values here or it'll skew the statistics.
654 if (agents_in_view == 0 && fps == 0 && sim_fps == 0 && ping == 0)
655 return;
656 s._agents_in_view.Add(agents_in_view);
657 s._fps.Add(fps);
658 s._sim_fps.Add(sim_fps);
659 s._ping.Add(ping);
660
661 int[] __agents_in_view = s._agents_in_view.ToArray();
662
663 s.avg_agents_in_view = ArrayAvg_i(__agents_in_view);
664 s.min_agents_in_view = ArrayMin_i(__agents_in_view);
665 s.max_agents_in_view = ArrayMax_i(__agents_in_view);
666 s.mode_agents_in_view = ArrayMode_i(__agents_in_view);
667
668 float[] __fps = s._fps.ToArray();
669 s.avg_fps = ArrayAvg_f(__fps);
670 s.min_fps = ArrayMin_f(__fps);
671 s.max_fps = ArrayMax_f(__fps);
672 s.mode_fps = ArrayMode_f(__fps);
673
674 float[] __sim_fps = s._sim_fps.ToArray();
675 s.avg_sim_fps = ArrayAvg_f(__sim_fps);
676 s.min_sim_fps = ArrayMin_f(__sim_fps);
677 s.max_sim_fps = ArrayMax_f(__sim_fps);
678 s.mode_sim_fps = ArrayMode_f(__sim_fps);
679
680 float[] __ping = s._ping.ToArray();
681 s.avg_ping = ArrayAvg_f(__ping);
682 s.min_ping = ArrayMin_f(__ping);
683 s.max_ping = ArrayMax_f(__ping);
684 s.mode_ping = ArrayMode_f(__ping);
685
686 }
687
688 #region Statistics
689
690 public static int ArrayMin_i(int[] arr)
691 {
692 int cnt = arr.Length;
693 if (cnt == 0)
694 return 0;
695
696 Array.Sort(arr);
697 return arr[0];
698 }
699
700 public static int ArrayMax_i(int[] arr)
701 {
702 int cnt = arr.Length;
703 if (cnt == 0)
704 return 0;
705
706 Array.Sort(arr);
707 return arr[cnt-1];
708 }
709
710 public static float ArrayMin_f(float[] arr)
711 {
712 int cnt = arr.Length;
713 if (cnt == 0)
714 return 0;
715
716 Array.Sort(arr);
717 return arr[0];
718 }
719
720 public static float ArrayMax_f(float[] arr)
721 {
722 int cnt = arr.Length;
723 if (cnt == 0)
724 return 0;
725
726 Array.Sort(arr);
727 return arr[cnt - 1];
728 }
729
730 public static float ArrayAvg_i(int[] arr)
731 {
732 int cnt = arr.Length;
733
734 if (cnt == 0)
735 return 0;
736
737 float result = arr[0];
738
739 for (int i = 1; i < cnt; i++)
740 result += arr[i];
741
742 return result / cnt;
743 }
744
745 public static float ArrayAvg_f(float[] arr)
746 {
747 int cnt = arr.Length;
748
749 if (cnt == 0)
750 return 0;
751
752 float result = arr[0];
753
754 for (int i = 1; i < cnt; i++)
755 result += arr[i];
756
757 return result / cnt;
758 }
759
760
761 public static float ArrayMode_f(float[] arr)
762 {
763 List<float> mode = new List<float>();
764
765 float[] srtArr = new float[arr.Length];
766 float[,] freq = new float[arr.Length, 2];
767 Array.Copy(arr, srtArr, arr.Length);
768 Array.Sort(srtArr);
769
770 float tmp = srtArr[0];
771 int index = 0;
772 int i = 0;
773 while (i < srtArr.Length)
774 {
775 freq[index, 0] = tmp;
776
777 while (tmp == srtArr[i])
778 {
779 freq[index, 1]++;
780 i++;
781
782 if (i > srtArr.Length - 1)
783 break;
784 }
785
786 if (i < srtArr.Length)
787 {
788 tmp = srtArr[i];
789 index++;
790 }
791
792 }
793
794 Array.Clear(srtArr, 0, srtArr.Length);
795
796 for (i = 0; i < srtArr.Length; i++)
797 srtArr[i] = freq[i, 1];
798
799 Array.Sort(srtArr);
800
801 if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1)
802 return 0;
803
804 float freqtest = (float)freq.Length / freq.Rank;
805
806 for (i = 0; i < freqtest; i++)
807 {
808 if (freq[i, 1] == srtArr[index])
809 mode.Add(freq[i, 0]);
810
811 }
812
813 return mode.ToArray()[0];
814
815 }
816
817
818 public static int ArrayMode_i(int[] arr)
819 {
820 List<int> mode = new List<int>();
821
822 int[] srtArr = new int[arr.Length];
823 int[,] freq = new int[arr.Length, 2];
824 Array.Copy(arr, srtArr, arr.Length);
825 Array.Sort(srtArr);
826
827 int tmp = srtArr[0];
828 int index = 0;
829 int i = 0;
830 while (i < srtArr.Length)
831 {
832 freq[index, 0] = tmp;
833
834 while (tmp == srtArr[i])
835 {
836 freq[index, 1]++;
837 i++;
838
839 if (i > srtArr.Length - 1)
840 break;
841 }
842
843 if (i < srtArr.Length)
844 {
845 tmp = srtArr[i];
846 index++;
847 }
848
849 }
850
851 Array.Clear(srtArr, 0, srtArr.Length);
852
853 for (i = 0; i < srtArr.Length; i++)
854 srtArr[i] = freq[i, 1];
855
856 Array.Sort(srtArr);
857
858 if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1)
859 return 0;
860
861 float freqtest = (float)freq.Length / freq.Rank;
862
863 for (i = 0; i < freqtest; i++)
864 {
865 if (freq[i, 1] == srtArr[index])
866 mode.Add(freq[i, 0]);
867
868 }
869
870 return mode.ToArray()[0];
871
872 }
873
874 #endregion
875
876 private static UserSessionData ZeroSession(UserSessionData s)
877 {
878 s.session_id = UUID.Zero;
879 s.agent_id = UUID.Zero;
880 s.region_id = UUID.Zero;
881 s.last_updated = Util.UnixTimeSinceEpoch();
882 s.remote_ip = "";
883 s.name_f = "";
884 s.name_l = "";
885 s.avg_agents_in_view = 0;
886 s.min_agents_in_view = 0;
887 s.max_agents_in_view = 0;
888 s.mode_agents_in_view = 0;
889 s.avg_fps = 0;
890 s.min_fps = 0;
891 s.max_fps = 0;
892 s.mode_fps = 0;
893 s.a_language = "";
894 s.mem_use = 0;
895 s.meters_traveled = 0;
896 s.avg_ping = 0;
897 s.min_ping = 0;
898 s.max_ping = 0;
899 s.mode_ping = 0;
900 s.regions_visited = 0;
901 s.run_time = 0;
902 s.avg_sim_fps = 0;
903 s.min_sim_fps = 0;
904 s.max_sim_fps = 0;
905 s.mode_sim_fps = 0;
906 s.start_time = 0;
907 s.client_version = "";
908 s.s_cpu = "";
909 s.s_gpu = "";
910 s.s_os = "";
911 s.s_ram = 0;
912 s.d_object_kb = 0;
913 s.d_texture_kb = 0;
914 s.d_world_kb = 0;
915 s.n_in_kb = 0;
916 s.n_in_pk = 0;
917 s.n_out_kb = 0;
918 s.n_out_pk = 0;
919 s.f_dropped = 0;
920 s.f_failed_resends = 0;
921 s.f_invalid = 0;
922 s.f_off_circuit = 0;
923 s.f_resent = 0;
924 s.f_send_packet = 0;
925 s._ping = new List<float>();
926 s._fps = new List<float>();
927 s._sim_fps = new List<float>();
928 s._agents_in_view = new List<int>();
929 return s;
930 }
931 }
932 #region structs
933
934 public struct UserSessionID
935 {
936 public UUID session_id;
937 public UUID region_id;
938 public string name_f;
939 public string name_l;
940 public UserSessionData session_data;
941 }
942
943 public struct UserSessionData
944 {
945 public UUID session_id;
946 public UUID agent_id;
947 public UUID region_id;
948 public float last_updated;
949 public string remote_ip;
950 public string name_f;
951 public string name_l;
952 public float avg_agents_in_view;
953 public float min_agents_in_view;
954 public float max_agents_in_view;
955 public float mode_agents_in_view;
956 public float avg_fps;
957 public float min_fps;
958 public float max_fps;
959 public float mode_fps;
960 public string a_language;
961 public float mem_use;
962 public float meters_traveled;
963 public float avg_ping;
964 public float min_ping;
965 public float max_ping;
966 public float mode_ping;
967 public int regions_visited;
968 public float run_time;
969 public float avg_sim_fps;
970 public float min_sim_fps;
971 public float max_sim_fps;
972 public float mode_sim_fps;
973 public float start_time;
974 public string client_version;
975 public string s_cpu;
976 public string s_gpu;
977 public string s_os;
978 public int s_ram;
979 public float d_object_kb;
980 public float d_texture_kb;
981 public float d_world_kb;
982 public float n_in_kb;
983 public int n_in_pk;
984 public float n_out_kb;
985 public int n_out_pk;
986 public int f_dropped;
987 public int f_failed_resends;
988 public int f_invalid;
989 public int f_off_circuit;
990 public int f_resent;
991 public int f_send_packet;
992 public List<float> _ping;
993 public List<float> _fps;
994 public List<float> _sim_fps;
995 public List<int> _agents_in_view;
996 }
997
998
999 #endregion
1000
1001 public class USimStatsData
1002 {
1003 private UUID m_regionID = UUID.Zero;
1004 private volatile int m_statcounter = 0;
1005 private volatile float m_timeDilation;
1006 private volatile float m_simFps;
1007 private volatile float m_physicsFps;
1008 private volatile float m_agentUpdates;
1009 private volatile float m_rootAgents;
1010 private volatile float m_childAgents;
1011 private volatile float m_totalPrims;
1012 private volatile float m_activePrims;
1013 private volatile float m_totalFrameTime;
1014 private volatile float m_netFrameTime;
1015 private volatile float m_physicsFrameTime;
1016 private volatile float m_otherFrameTime;
1017 private volatile float m_imageFrameTime;
1018 private volatile float m_inPacketsPerSecond;
1019 private volatile float m_outPacketsPerSecond;
1020 private volatile float m_unackedBytes;
1021 private volatile float m_agentFrameTime;
1022 private volatile float m_pendingDownloads;
1023 private volatile float m_pendingUploads;
1024 private volatile float m_activeScripts;
1025 private volatile float m_scriptLinesPerSecond;
1026
1027 public UUID RegionId { get { return m_regionID; } }
1028 public int StatsCounter { get { return m_statcounter; } set { m_statcounter = value;}}
1029 public float TimeDilation { get { return m_timeDilation; } }
1030 public float SimFps { get { return m_simFps; } }
1031 public float PhysicsFps { get { return m_physicsFps; } }
1032 public float AgentUpdates { get { return m_agentUpdates; } }
1033 public float RootAgents { get { return m_rootAgents; } }
1034 public float ChildAgents { get { return m_childAgents; } }
1035 public float TotalPrims { get { return m_totalPrims; } }
1036 public float ActivePrims { get { return m_activePrims; } }
1037 public float TotalFrameTime { get { return m_totalFrameTime; } }
1038 public float NetFrameTime { get { return m_netFrameTime; } }
1039 public float PhysicsFrameTime { get { return m_physicsFrameTime; } }
1040 public float OtherFrameTime { get { return m_otherFrameTime; } }
1041 public float ImageFrameTime { get { return m_imageFrameTime; } }
1042 public float InPacketsPerSecond { get { return m_inPacketsPerSecond; } }
1043 public float OutPacketsPerSecond { get { return m_outPacketsPerSecond; } }
1044 public float UnackedBytes { get { return m_unackedBytes; } }
1045 public float AgentFrameTime { get { return m_agentFrameTime; } }
1046 public float PendingDownloads { get { return m_pendingDownloads; } }
1047 public float PendingUploads { get { return m_pendingUploads; } }
1048 public float ActiveScripts { get { return m_activeScripts; } }
1049 public float ScriptLinesPerSecond { get { return m_scriptLinesPerSecond; } }
1050
1051 public USimStatsData(UUID pRegionID)
1052 {
1053 m_regionID = pRegionID;
1054 }
1055
1056 public void ConsumeSimStats(SimStats stats)
1057 {
1058 m_regionID = stats.RegionUUID;
1059 m_timeDilation = stats.StatsBlock[0].StatValue;
1060 m_simFps = stats.StatsBlock[1].StatValue;
1061 m_physicsFps = stats.StatsBlock[2].StatValue;
1062 m_agentUpdates = stats.StatsBlock[3].StatValue;
1063 m_rootAgents = stats.StatsBlock[4].StatValue;
1064 m_childAgents = stats.StatsBlock[5].StatValue;
1065 m_totalPrims = stats.StatsBlock[6].StatValue;
1066 m_activePrims = stats.StatsBlock[7].StatValue;
1067 m_totalFrameTime = stats.StatsBlock[8].StatValue;
1068 m_netFrameTime = stats.StatsBlock[9].StatValue;
1069 m_physicsFrameTime = stats.StatsBlock[10].StatValue;
1070 m_otherFrameTime = stats.StatsBlock[11].StatValue;
1071 m_imageFrameTime = stats.StatsBlock[12].StatValue;
1072 m_inPacketsPerSecond = stats.StatsBlock[13].StatValue;
1073 m_outPacketsPerSecond = stats.StatsBlock[14].StatValue;
1074 m_unackedBytes = stats.StatsBlock[15].StatValue;
1075 m_agentFrameTime = stats.StatsBlock[16].StatValue;
1076 m_pendingDownloads = stats.StatsBlock[17].StatValue;
1077 m_pendingUploads = stats.StatsBlock[18].StatValue;
1078 m_activeScripts = stats.StatsBlock[19].StatValue;
1079 m_scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
1080 }
1081 }
1082
1083}