diff options
-rw-r--r-- | OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs | 84 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/Clients_report.cs | 27 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/Default_Report.cs | 27 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/IStatsReport.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/LogLinesAJAX.cs | 29 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/Prototype_distributor.cs | 31 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/Sessions_Report.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/SimStatsAJAX.cs | 59 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/Updater_distributor.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/UserStatistics/WebStatsModule.cs | 25 | ||||
-rw-r--r-- | bin/data/LICENSE-README-IMPORTANT.txt | 2 | ||||
-rw-r--r-- | bin/data/sim.css | 85 | ||||
-rw-r--r-- | bin/data/sim.html | 291 |
13 files changed, 658 insertions, 12 deletions
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs index 3243a9a..6a1112c 100644 --- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs +++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Framework.Monitoring; | 38 | using OpenSim.Framework.Monitoring; |
@@ -51,7 +52,6 @@ namespace OpenSim.Region.UserStatistics | |||
51 | 52 | ||
52 | public Hashtable ProcessModel(Hashtable pParams) | 53 | public Hashtable ProcessModel(Hashtable pParams) |
53 | { | 54 | { |
54 | |||
55 | List<Scene> m_scene = (List<Scene>)pParams["Scenes"]; | 55 | List<Scene> m_scene = (List<Scene>)pParams["Scenes"]; |
56 | 56 | ||
57 | Hashtable nh = new Hashtable(); | 57 | Hashtable nh = new Hashtable(); |
@@ -129,6 +129,86 @@ namespace OpenSim.Region.UserStatistics | |||
129 | return output.ToString(); | 129 | return output.ToString(); |
130 | } | 130 | } |
131 | 131 | ||
132 | /// <summary> | ||
133 | /// Convert active connections information to JSON string. Returns a structure: | ||
134 | /// <pre> | ||
135 | /// {"regionName": { | ||
136 | /// "presenceName": { | ||
137 | /// "name": "presenceName", | ||
138 | /// "position": "<x,y,z>", | ||
139 | /// "isRoot": "false", | ||
140 | /// "throttle": { | ||
141 | /// }, | ||
142 | /// "queue": { | ||
143 | /// } | ||
144 | /// }, | ||
145 | /// ... // multiple presences in the scene | ||
146 | /// }, | ||
147 | /// ... // multiple regions in the sim | ||
148 | /// } | ||
149 | /// | ||
150 | /// </pre> | ||
151 | /// </summary> | ||
152 | /// <param name="pModelResult"></param> | ||
153 | /// <returns></returns> | ||
154 | public string RenderJson(Hashtable pModelResult) | ||
155 | { | ||
156 | List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; | ||
157 | |||
158 | OSDMap regionInfo = new OSDMap(); | ||
159 | foreach (Scene scene in all_scenes) | ||
160 | { | ||
161 | OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
162 | List<ScenePresence> avatarInScene = scene.GetScenePresences(); | ||
163 | foreach (ScenePresence av in avatarInScene) | ||
164 | { | ||
165 | OSDMap presenceInfo = new OSDMap(); | ||
166 | presenceInfo.Add("Name", new OSDString(av.Name)); | ||
167 | |||
168 | Dictionary<string,string> queues = new Dictionary<string, string>(); | ||
169 | if (av.ControllingClient is IStatsCollector) | ||
170 | { | ||
171 | IStatsCollector isClient = (IStatsCollector) av.ControllingClient; | ||
172 | queues = decodeQueueReport(isClient.Report()); | ||
173 | } | ||
174 | OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
175 | foreach (KeyValuePair<string, string> kvp in queues) { | ||
176 | queueInfo.Add(kvp.Key, new OSDString(kvp.Value)); | ||
177 | } | ||
178 | sceneInfo.Add("queues", queueInfo); | ||
179 | |||
180 | if (av.IsChildAgent) | ||
181 | presenceInfo.Add("isRoot", new OSDString("false")); | ||
182 | else | ||
183 | presenceInfo.Add("isRoot", new OSDString("true")); | ||
184 | |||
185 | if (av.AbsolutePosition == DefaultNeighborPosition) | ||
186 | { | ||
187 | presenceInfo.Add("position", new OSDString("<0, 0, 0>")); | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>", | ||
192 | (int)av.AbsolutePosition.X, | ||
193 | (int) av.AbsolutePosition.Y, | ||
194 | (int) av.AbsolutePosition.Z)) ); | ||
195 | } | ||
196 | |||
197 | Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); | ||
198 | OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
199 | foreach (string throttlename in throttles.Keys) | ||
200 | { | ||
201 | throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString())); | ||
202 | } | ||
203 | presenceInfo.Add("throttle", throttleInfo); | ||
204 | |||
205 | sceneInfo.Add(av.Name, presenceInfo); | ||
206 | } | ||
207 | regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo); | ||
208 | } | ||
209 | return regionInfo.ToString(); | ||
210 | } | ||
211 | |||
132 | public Dictionary<string, int> DecodeClientThrottles(byte[] throttle) | 212 | public Dictionary<string, int> DecodeClientThrottles(byte[] throttle) |
133 | { | 213 | { |
134 | Dictionary<string, int> returndict = new Dictionary<string, int>(); | 214 | Dictionary<string, int> returndict = new Dictionary<string, int>(); |
@@ -203,7 +283,7 @@ namespace OpenSim.Region.UserStatistics | |||
203 | returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; | 283 | returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; |
204 | returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; | 284 | returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; |
205 | returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; | 285 | returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; |
206 | returndic.Add("Asset", rep.Substring((7 * pos), 8)); | 286 | returndic.Add("Asset", rep.Substring((7 * pos), 8)); |
207 | /* | 287 | /* |
208 | * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", | 288 | * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", |
209 | SendQueue.Count(), | 289 | SendQueue.Count(), |
diff --git a/OpenSim/Region/UserStatistics/Clients_report.cs b/OpenSim/Region/UserStatistics/Clients_report.cs index b2bb33b..4a6f7be 100644 --- a/OpenSim/Region/UserStatistics/Clients_report.cs +++ b/OpenSim/Region/UserStatistics/Clients_report.cs | |||
@@ -31,6 +31,7 @@ using System.Collections.Generic; | |||
31 | using System.Text; | 31 | using System.Text; |
32 | using Mono.Data.SqliteClient; | 32 | using Mono.Data.SqliteClient; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.StructuredData; | ||
34 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
35 | 36 | ||
36 | namespace OpenSim.Region.UserStatistics | 37 | namespace OpenSim.Region.UserStatistics |
@@ -44,6 +45,32 @@ namespace OpenSim.Region.UserStatistics | |||
44 | get { return "Client"; } | 45 | get { return "Client"; } |
45 | } | 46 | } |
46 | 47 | ||
48 | /// <summary> | ||
49 | /// Return summar information in the form: | ||
50 | /// <pre> | ||
51 | /// {"totalUsers": "34", | ||
52 | /// "totalSessions": "233", | ||
53 | /// ... | ||
54 | /// } | ||
55 | /// </pre> | ||
56 | /// </summary> | ||
57 | /// <param name="pModelResult"></param> | ||
58 | /// <returns></returns> | ||
59 | public string RenderJson(Hashtable pModelResult) { | ||
60 | stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; | ||
61 | |||
62 | OSDMap summaryInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
63 | summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); | ||
64 | summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); | ||
65 | summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); | ||
66 | summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); | ||
67 | summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); | ||
68 | summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); | ||
69 | summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); | ||
70 | summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); | ||
71 | return summaryInfo.ToString(); | ||
72 | } | ||
73 | |||
47 | public Hashtable ProcessModel(Hashtable pParams) | 74 | public Hashtable ProcessModel(Hashtable pParams) |
48 | { | 75 | { |
49 | SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; | 76 | SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; |
diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs index cdc615c..fabe3d4 100644 --- a/OpenSim/Region/UserStatistics/Default_Report.cs +++ b/OpenSim/Region/UserStatistics/Default_Report.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Framework.Monitoring; | 37 | using OpenSim.Framework.Monitoring; |
37 | 38 | ||
@@ -230,6 +231,31 @@ TD.align_top { vertical-align: top; } | |||
230 | return returnstruct; | 231 | return returnstruct; |
231 | } | 232 | } |
232 | 233 | ||
234 | /// <summary> | ||
235 | /// Return summar information in the form: | ||
236 | /// <pre> | ||
237 | /// {"totalUsers": "34", | ||
238 | /// "totalSessions": "233", | ||
239 | /// ... | ||
240 | /// } | ||
241 | /// </pre> | ||
242 | /// </summary> | ||
243 | /// <param name="pModelResult"></param> | ||
244 | /// <returns></returns> | ||
245 | public string RenderJson(Hashtable pModelResult) { | ||
246 | stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; | ||
247 | |||
248 | OSDMap summaryInfo = new OSDMap(); | ||
249 | summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); | ||
250 | summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); | ||
251 | summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); | ||
252 | summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); | ||
253 | summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); | ||
254 | summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); | ||
255 | summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); | ||
256 | summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); | ||
257 | return summaryInfo.ToString(); | ||
258 | } | ||
233 | } | 259 | } |
234 | 260 | ||
235 | public struct stats_default_page_values | 261 | public struct stats_default_page_values |
@@ -247,4 +273,5 @@ TD.align_top { vertical-align: top; } | |||
247 | public Dictionary<UUID, USimStatsData> sim_stat_data; | 273 | public Dictionary<UUID, USimStatsData> sim_stat_data; |
248 | public Dictionary<string, IStatsController> stats_reports; | 274 | public Dictionary<string, IStatsController> stats_reports; |
249 | } | 275 | } |
276 | |||
250 | } | 277 | } |
diff --git a/OpenSim/Region/UserStatistics/IStatsReport.cs b/OpenSim/Region/UserStatistics/IStatsReport.cs index e0ecce4..80c4487 100644 --- a/OpenSim/Region/UserStatistics/IStatsReport.cs +++ b/OpenSim/Region/UserStatistics/IStatsReport.cs | |||
@@ -34,5 +34,6 @@ namespace OpenSim.Region.UserStatistics | |||
34 | string ReportName { get; } | 34 | string ReportName { get; } |
35 | Hashtable ProcessModel(Hashtable pParams); | 35 | Hashtable ProcessModel(Hashtable pParams); |
36 | string RenderView(Hashtable pModelResult); | 36 | string RenderView(Hashtable pModelResult); |
37 | string RenderJson(Hashtable pModelResult); | ||
37 | } | 38 | } |
38 | } | 39 | } |
diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs index 74de46b..4d45b80 100644 --- a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs +++ b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs | |||
@@ -33,6 +33,7 @@ using System.Text; | |||
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using Mono.Data.SqliteClient; | 34 | using Mono.Data.SqliteClient; |
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Framework.Monitoring; | 38 | using OpenSim.Framework.Monitoring; |
38 | 39 | ||
@@ -125,6 +126,34 @@ namespace OpenSim.Region.UserStatistics | |||
125 | return output.ToString(); | 126 | return output.ToString(); |
126 | } | 127 | } |
127 | 128 | ||
129 | /// <summary> | ||
130 | /// Return the last log lines. Output in the format: | ||
131 | /// <pre> | ||
132 | /// {"logLines": [ | ||
133 | /// "line1", | ||
134 | /// "line2", | ||
135 | /// ... | ||
136 | /// ] | ||
137 | /// } | ||
138 | /// </pre> | ||
139 | /// </summary> | ||
140 | /// <param name="pModelResult"></param> | ||
141 | /// <returns></returns> | ||
142 | public string RenderJson(Hashtable pModelResult) | ||
143 | { | ||
144 | OSDMap logInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
145 | |||
146 | OSDArray logLines = new OpenMetaverse.StructuredData.OSDArray(); | ||
147 | string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n"); | ||
148 | string[] result = Regex.Split(tmp, "\n"); | ||
149 | for (int i = 0; i < result.Length; i++) | ||
150 | { | ||
151 | logLines.Add(new OSDString(result[i])); | ||
152 | } | ||
153 | logInfo.Add("logLines", logLines); | ||
154 | return logInfo.ToString(); | ||
155 | } | ||
156 | |||
128 | #endregion | 157 | #endregion |
129 | } | 158 | } |
130 | } | 159 | } |
diff --git a/OpenSim/Region/UserStatistics/Prototype_distributor.cs b/OpenSim/Region/UserStatistics/Prototype_distributor.cs index 53ae557..6f8b2aa 100644 --- a/OpenSim/Region/UserStatistics/Prototype_distributor.cs +++ b/OpenSim/Region/UserStatistics/Prototype_distributor.cs | |||
@@ -36,7 +36,18 @@ namespace OpenSim.Region.UserStatistics | |||
36 | { | 36 | { |
37 | public class Prototype_distributor : IStatsController | 37 | public class Prototype_distributor : IStatsController |
38 | { | 38 | { |
39 | private string prototypejs=string.Empty; | 39 | private string jsFileName = "prototype.js"; |
40 | private string prototypejs = string.Empty; | ||
41 | |||
42 | public Prototype_distributor() | ||
43 | { | ||
44 | jsFileName = "prototype.js"; | ||
45 | } | ||
46 | |||
47 | public Prototype_distributor(string jsName) | ||
48 | { | ||
49 | jsFileName = jsName; | ||
50 | } | ||
40 | 51 | ||
41 | public string ReportName | 52 | public string ReportName |
42 | { | 53 | { |
@@ -45,20 +56,24 @@ namespace OpenSim.Region.UserStatistics | |||
45 | public Hashtable ProcessModel(Hashtable pParams) | 56 | public Hashtable ProcessModel(Hashtable pParams) |
46 | { | 57 | { |
47 | Hashtable pResult = new Hashtable(); | 58 | Hashtable pResult = new Hashtable(); |
48 | if (prototypejs.Length == 0) | 59 | pResult["js"] = jsFileName; |
60 | return pResult; | ||
61 | } | ||
62 | |||
63 | public string RenderView(Hashtable pModelResult) | ||
64 | { | ||
65 | string fileName = (string)pModelResult["js"]; | ||
66 | using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open))) | ||
49 | { | 67 | { |
50 | StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open)); | ||
51 | prototypejs = fs.ReadToEnd(); | 68 | prototypejs = fs.ReadToEnd(); |
52 | fs.Close(); | 69 | fs.Close(); |
53 | fs.Dispose(); | ||
54 | } | 70 | } |
55 | pResult["js"] = prototypejs; | 71 | return prototypejs; |
56 | return pResult; | ||
57 | } | 72 | } |
58 | 73 | ||
59 | public string RenderView(Hashtable pModelResult) | 74 | public string RenderJson(Hashtable pModelResult) |
60 | { | 75 | { |
61 | return pModelResult["js"].ToString(); | 76 | return "{}"; |
62 | } | 77 | } |
63 | 78 | ||
64 | } | 79 | } |
diff --git a/OpenSim/Region/UserStatistics/Sessions_Report.cs b/OpenSim/Region/UserStatistics/Sessions_Report.cs index 1a2d460..0e94912 100644 --- a/OpenSim/Region/UserStatistics/Sessions_Report.cs +++ b/OpenSim/Region/UserStatistics/Sessions_Report.cs | |||
@@ -278,6 +278,11 @@ TD.align_top { vertical-align: top; } | |||
278 | public DateTime start_time; | 278 | public DateTime start_time; |
279 | } | 279 | } |
280 | 280 | ||
281 | public string RenderJson(Hashtable pModelResult) | ||
282 | { | ||
283 | return "{}"; | ||
284 | } | ||
281 | #endregion | 285 | #endregion |
282 | } | 286 | } |
287 | |||
283 | } | 288 | } |
diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs index 28051fb..ad848a1 100644 --- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs +++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Framework.Monitoring; | 37 | using OpenSim.Framework.Monitoring; |
37 | 38 | ||
@@ -218,6 +219,64 @@ namespace OpenSim.Region.UserStatistics | |||
218 | return output.ToString(); | 219 | return output.ToString(); |
219 | } | 220 | } |
220 | 221 | ||
222 | /// <summary> | ||
223 | /// Return stat information for all regions in the sim. Returns data of the form: | ||
224 | /// <pre> | ||
225 | /// {"REGIONNAME": { | ||
226 | /// "region": "REGIONNAME", | ||
227 | /// "timeDilation": "101", | ||
228 | /// ... // the rest of the stat info | ||
229 | /// }, | ||
230 | /// ... // entries for each region | ||
231 | /// } | ||
232 | /// </pre> | ||
233 | /// </summary> | ||
234 | /// <param name="pModelResult"></param> | ||
235 | /// <returns></returns> | ||
236 | public string RenderJson(Hashtable pModelResult) | ||
237 | { | ||
238 | List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; | ||
239 | Dictionary<UUID, USimStatsData> sdatadic = (Dictionary<UUID,USimStatsData>)pModelResult["simstats"]; | ||
240 | |||
241 | OSDMap allStatsInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
242 | foreach (USimStatsData sdata in sdatadic.Values) | ||
243 | { | ||
244 | OSDMap statsInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
245 | string regionName = "unknown"; | ||
246 | foreach (Scene sn in all_scenes) | ||
247 | { | ||
248 | if (sn.RegionInfo.RegionID == sdata.RegionId) | ||
249 | { | ||
250 | regionName = sn.RegionInfo.RegionName; | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | statsInfo.Add("region", new OSDString(regionName)); | ||
255 | statsInfo.Add("timeDilation", new OSDString(sdata.TimeDilation.ToString())); | ||
256 | statsInfo.Add("simFPS", new OSDString(sdata.SimFps.ToString())); | ||
257 | statsInfo.Add("physicsFPS", new OSDString(sdata.PhysicsFps.ToString())); | ||
258 | statsInfo.Add("agentUpdates", new OSDString(sdata.AgentUpdates.ToString())); | ||
259 | statsInfo.Add("rootAgents", new OSDString(sdata.RootAgents.ToString())); | ||
260 | statsInfo.Add("childAgents", new OSDString(sdata.ChildAgents.ToString())); | ||
261 | statsInfo.Add("totalPrims", new OSDString(sdata.TotalPrims.ToString())); | ||
262 | statsInfo.Add("activePrims", new OSDString(sdata.ActivePrims.ToString())); | ||
263 | statsInfo.Add("activeScripts", new OSDString(sdata.ActiveScripts.ToString())); | ||
264 | statsInfo.Add("scriptLinesPerSec", new OSDString(sdata.ScriptLinesPerSecond.ToString())); | ||
265 | statsInfo.Add("totalFrameTime", new OSDString(sdata.TotalFrameTime.ToString())); | ||
266 | statsInfo.Add("agentFrameTime", new OSDString(sdata.AgentFrameTime.ToString())); | ||
267 | statsInfo.Add("physicsFrameTime", new OSDString(sdata.PhysicsFrameTime.ToString())); | ||
268 | statsInfo.Add("otherFrameTime", new OSDString(sdata.OtherFrameTime.ToString())); | ||
269 | statsInfo.Add("outPacketsPerSec", new OSDString(sdata.OutPacketsPerSecond.ToString())); | ||
270 | statsInfo.Add("inPacketsPerSec", new OSDString(sdata.InPacketsPerSecond.ToString())); | ||
271 | statsInfo.Add("unackedByptes", new OSDString(sdata.UnackedBytes.ToString())); | ||
272 | statsInfo.Add("pendingDownloads", new OSDString(sdata.PendingDownloads.ToString())); | ||
273 | statsInfo.Add("pendingUploads", new OSDString(sdata.PendingUploads.ToString())); | ||
274 | |||
275 | allStatsInfo.Add(regionName, statsInfo); | ||
276 | } | ||
277 | return allStatsInfo.ToString(); | ||
278 | } | ||
279 | |||
221 | #endregion | 280 | #endregion |
222 | } | 281 | } |
223 | } | 282 | } |
diff --git a/OpenSim/Region/UserStatistics/Updater_distributor.cs b/OpenSim/Region/UserStatistics/Updater_distributor.cs index 9593cc9..601e06b 100644 --- a/OpenSim/Region/UserStatistics/Updater_distributor.cs +++ b/OpenSim/Region/UserStatistics/Updater_distributor.cs | |||
@@ -62,5 +62,9 @@ namespace OpenSim.Region.UserStatistics | |||
62 | return pModelResult["js"].ToString(); | 62 | return pModelResult["js"].ToString(); |
63 | } | 63 | } |
64 | 64 | ||
65 | public string RenderJson(Hashtable pModelResult) { | ||
66 | return "{}"; | ||
67 | } | ||
68 | |||
65 | } | 69 | } |
66 | } \ No newline at end of file | 70 | } \ No newline at end of file |
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 64cb577..438ef48 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs | |||
@@ -121,6 +121,10 @@ namespace OpenSim.Region.UserStatistics | |||
121 | reports.Add("clients.report", clientReport); | 121 | reports.Add("clients.report", clientReport); |
122 | reports.Add("sessions.report", sessionsReport); | 122 | reports.Add("sessions.report", sessionsReport); |
123 | 123 | ||
124 | reports.Add("sim.css", new Prototype_distributor("sim.css")); | ||
125 | reports.Add("sim.html", new Prototype_distributor("sim.html")); | ||
126 | reports.Add("jquery.js", new Prototype_distributor("jquery.js")); | ||
127 | |||
124 | //// | 128 | //// |
125 | // Add Your own Reports here (Do Not Modify Lines here Devs!) | 129 | // Add Your own Reports here (Do Not Modify Lines here Devs!) |
126 | //// | 130 | //// |
@@ -255,9 +259,12 @@ namespace OpenSim.Region.UserStatistics | |||
255 | string regpath = request["uri"].ToString(); | 259 | string regpath = request["uri"].ToString(); |
256 | int response_code = 404; | 260 | int response_code = 404; |
257 | string contenttype = "text/html"; | 261 | string contenttype = "text/html"; |
262 | bool jsonFormatOutput = false; | ||
258 | 263 | ||
259 | string strOut = string.Empty; | 264 | string strOut = string.Empty; |
260 | 265 | ||
266 | // The request patch should be "/SStats/reportName" where 'reportName' | ||
267 | // is one of the names added to the 'reports' hashmap. | ||
261 | regpath = regpath.Remove(0, 8); | 268 | regpath = regpath.Remove(0, 8); |
262 | if (regpath.Length == 0) regpath = "default.report"; | 269 | if (regpath.Length == 0) regpath = "default.report"; |
263 | if (reports.ContainsKey(regpath)) | 270 | if (reports.ContainsKey(regpath)) |
@@ -265,6 +272,9 @@ namespace OpenSim.Region.UserStatistics | |||
265 | IStatsController rep = reports[regpath]; | 272 | IStatsController rep = reports[regpath]; |
266 | Hashtable repParams = new Hashtable(); | 273 | Hashtable repParams = new Hashtable(); |
267 | 274 | ||
275 | if (request.ContainsKey("json")) | ||
276 | jsonFormatOutput = true; | ||
277 | |||
268 | if (request.ContainsKey("requestvars")) | 278 | if (request.ContainsKey("requestvars")) |
269 | repParams["RequestVars"] = request["requestvars"]; | 279 | repParams["RequestVars"] = request["requestvars"]; |
270 | else | 280 | else |
@@ -284,13 +294,26 @@ namespace OpenSim.Region.UserStatistics | |||
284 | 294 | ||
285 | concurrencyCounter++; | 295 | concurrencyCounter++; |
286 | 296 | ||
287 | strOut = rep.RenderView(rep.ProcessModel(repParams)); | 297 | if (jsonFormatOutput) |
298 | { | ||
299 | strOut = rep.RenderJson(rep.ProcessModel(repParams)); | ||
300 | contenttype = "text/json"; | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | strOut = rep.RenderView(rep.ProcessModel(repParams)); | ||
305 | } | ||
288 | 306 | ||
289 | if (regpath.EndsWith("js")) | 307 | if (regpath.EndsWith("js")) |
290 | { | 308 | { |
291 | contenttype = "text/javascript"; | 309 | contenttype = "text/javascript"; |
292 | } | 310 | } |
293 | 311 | ||
312 | if (regpath.EndsWith("css")) | ||
313 | { | ||
314 | contenttype = "text/css"; | ||
315 | } | ||
316 | |||
294 | concurrencyCounter--; | 317 | concurrencyCounter--; |
295 | 318 | ||
296 | response_code = 200; | 319 | response_code = 200; |
diff --git a/bin/data/LICENSE-README-IMPORTANT.txt b/bin/data/LICENSE-README-IMPORTANT.txt index 86e401f..a1ac20c 100644 --- a/bin/data/LICENSE-README-IMPORTANT.txt +++ b/bin/data/LICENSE-README-IMPORTANT.txt | |||
@@ -2,4 +2,4 @@ Not all of the files in this directory are licensed under the BSD license. Some | |||
2 | 2 | ||
3 | These files are: | 3 | These files are: |
4 | 4 | ||
5 | - avataranimations.xml (Derivative work of viewerart.ini, Creative Commons Attribution+Share-Alike v2.5 License) \ No newline at end of file | 5 | - avataranimations.xml (Derivative work of viewerart.ini, Creative Commons Attribution+Share-Alike v2.5 License) |
diff --git a/bin/data/sim.css b/bin/data/sim.css new file mode 100644 index 0000000..e584a1a --- /dev/null +++ b/bin/data/sim.css | |||
@@ -0,0 +1,85 @@ | |||
1 | body { | ||
2 | font-family: Veranda,Arial,Helvetica,sans-serif; | ||
3 | font-size: 12px; | ||
4 | background: #4A5F6D; | ||
5 | color: #EEEAD6; | ||
6 | padding: 0px; | ||
7 | margin: 0px; | ||
8 | } | ||
9 | .footer { | ||
10 | font-family: Veranda,Arial,Helvetica,sans-serif; | ||
11 | font-size: 10px; | ||
12 | } | ||
13 | td { | ||
14 | font-family: Veranda,Arial,Helvetica,sans-serif; | ||
15 | font-size: 12px; | ||
16 | padding: 4px; | ||
17 | margin: 4px; | ||
18 | } | ||
19 | blockquote { | ||
20 | font-family: Veranda,Arial,Helvetica,sans-serif; | ||
21 | font-style: italic; | ||
22 | font-size: 12px; | ||
23 | } | ||
24 | pre { | ||
25 | padding: 5px; | ||
26 | background-color: #8080B0; | ||
27 | color: #000000; | ||
28 | margin-left: 20px; | ||
29 | font-size: 11px; | ||
30 | } | ||
31 | :link { | ||
32 | color: #ffffff; | ||
33 | } | ||
34 | :visited { | ||
35 | color: #d0d0d0; | ||
36 | } | ||
37 | .SimSectionHeader { | ||
38 | font-size: 120%; | ||
39 | } | ||
40 | div.SimSectionContainer { | ||
41 | padding: 10px 0px 0px 20px; | ||
42 | } | ||
43 | /* SimStats ===================================== */ | ||
44 | #SimSimStats div { | ||
45 | margin-left: 20px; | ||
46 | background: #3A4F5D; | ||
47 | } | ||
48 | #SimSimStats table td { | ||
49 | text-align: right; | ||
50 | padding: 0px 0px 0px 5px; | ||
51 | margin: 0px 0px 0px 0px; | ||
52 | } | ||
53 | /* Region Stats ===================================== */ | ||
54 | #SimRegionStats div { | ||
55 | margin-left: 20px; | ||
56 | background: #3A4F5D; | ||
57 | } | ||
58 | #SimRegionStats table { | ||
59 | border: 1px; | ||
60 | border-style: solid; | ||
61 | } | ||
62 | #SimRegionStats table td { | ||
63 | text-align: right; | ||
64 | padding: 0px 0px 0px 5px; | ||
65 | margin: 0px 0px 0px 0px; | ||
66 | } | ||
67 | /* Session Stats ===================================== */ | ||
68 | #SimSessionStats div { | ||
69 | margin-left: 20px; | ||
70 | background: #3A4F5D; | ||
71 | } | ||
72 | #SimSessionStats table td { | ||
73 | text-align: right; | ||
74 | padding: 0px 0px 0px 5px; | ||
75 | margin: 0px 0px 0px 0px; | ||
76 | } | ||
77 | /* LogFile ===================================== */ | ||
78 | #SimLogFile div { | ||
79 | margin-left: 20px; | ||
80 | } | ||
81 | #SimLogFile table td { | ||
82 | text-align: right; | ||
83 | padding: 0px 0px 0px 5px; | ||
84 | margin: 0px 0px 0px 0px; | ||
85 | } | ||
diff --git a/bin/data/sim.html b/bin/data/sim.html new file mode 100644 index 0000000..82d4789 --- /dev/null +++ b/bin/data/sim.html | |||
@@ -0,0 +1,291 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
3 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
4 | <head> | ||
5 | <title>Simulator statistics</title> | ||
6 | <link rel="stylesheet" href="sim.css" type="text/css"/> | ||
7 | <!-- <script type="text/javascript" src="jquery.js"></script> --> | ||
8 | <!-- <script type="text/javascript" src="https://code.jquery.com/jquery-1.9.0.min.js"></script> --> | ||
9 | <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> | ||
10 | <!-- <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/libs/jQuery/jquery-1.9.0.min.js"></script> --> | ||
11 | <noscript> | ||
12 | <p color="red"> | ||
13 | Your browser does not support Javascript. This won't work for you. | ||
14 | </p> | ||
15 | </noscript> | ||
16 | <script type="text/javascript"> | ||
17 | $(document).ready(function() { | ||
18 | // Major divisions in the content accordioning | ||
19 | $('.SimSection').show('slow'); | ||
20 | $('.SimSectionHeader').click(function() { | ||
21 | $(this).next().slideToggle('slow'); | ||
22 | return false; | ||
23 | }); | ||
24 | |||
25 | // Start the timed functions | ||
26 | TimerDataStuff(); | ||
27 | }); | ||
28 | |||
29 | // One of the sections is viewer statistics. Poll for the data. | ||
30 | var statTimerHandle; | ||
31 | var graphFPS; | ||
32 | var lastFPS = 10; | ||
33 | var xxThru = 0; | ||
34 | function TimerDataStuff() { | ||
35 | statTimerHandle = setInterval('TimerStatDisplay()', 5000); | ||
36 | } | ||
37 | |||
38 | // called by timer to fetch and display statistic information | ||
39 | var doingStatDisplay = false; | ||
40 | function TimerStatDisplay() { | ||
41 | if (doingStatDisplay) return; | ||
42 | doingStatDisplay = true; | ||
43 | if ($('#SimSimStats').is(':visible')) { | ||
44 | DisplaySimStats(); | ||
45 | } | ||
46 | if ($('#SimRegionStats').is(':visible')) { | ||
47 | DisplayPerRegionStats(); | ||
48 | } | ||
49 | if ($('#SimSessionStats').is(':visible')) { | ||
50 | DisplaySessionStats(); | ||
51 | } | ||
52 | if ($('#SimLogFile').is(':visible')) { | ||
53 | DisplayLogFile(); | ||
54 | } | ||
55 | doingStatDisplay = false; | ||
56 | } | ||
57 | |||
58 | var simName = "127.0.0.1"; | ||
59 | var simPort = "9000"; | ||
60 | function DisplaySimStats() { | ||
61 | var statURL = "http://" + simName + ":" + simPort + "/SStats/?json=1"; | ||
62 | $.ajax({ | ||
63 | type: "GET", | ||
64 | url: statURL, | ||
65 | dataType: 'json', | ||
66 | timeout: 1000, | ||
67 | success: function(data, status) { | ||
68 | if (status == 'success') { | ||
69 | DisplaySimStatDetails(data); | ||
70 | } | ||
71 | }, | ||
72 | error: function(xmlHTTPRequest, errorType) { | ||
73 | // DebugLog('Failed fetch'); | ||
74 | } | ||
75 | }); | ||
76 | } | ||
77 | |||
78 | function DisplayPerRegionStats() { | ||
79 | var statURL = "http://" + simName + ":" + simPort + "/SStats/simstatsajax.html?json=1"; | ||
80 | $.ajax({ | ||
81 | type: "GET", | ||
82 | url: statURL, | ||
83 | dataType: 'json', | ||
84 | timeout: 1000, | ||
85 | success: function(data, status) { | ||
86 | if (status == 'success') { | ||
87 | DisplayRegionStatDetails(data); | ||
88 | } | ||
89 | }, | ||
90 | error: function(xmlHTTPRequest, errorType) { | ||
91 | // DebugLog('Failed fetch'); | ||
92 | } | ||
93 | }); | ||
94 | }; | ||
95 | |||
96 | function DisplayLogFile() { | ||
97 | var statURL = "http://" + simName + ":" + simPort + "/SStats/activelogajax.html?json=1"; | ||
98 | $.ajax({ | ||
99 | type: "GET", | ||
100 | url: statURL, | ||
101 | dataType: 'json', | ||
102 | timeout: 1000, | ||
103 | success: function(data, status) { | ||
104 | if (status == 'success') { | ||
105 | DisplayLogFileDetails(data); | ||
106 | } | ||
107 | }, | ||
108 | error: function(xmlHTTPRequest, errorType) { | ||
109 | // DebugLog('Failed fetch'); | ||
110 | } | ||
111 | }); | ||
112 | }; | ||
113 | |||
114 | function DisplaySessionStats() { | ||
115 | var statURL = "http://" + simName + ":" + simPort + "/SStats/activeconnectionsajax.html?json=1"; | ||
116 | $.ajax({ | ||
117 | type: "GET", | ||
118 | url: statURL, | ||
119 | dataType: 'json', | ||
120 | timeout: 1000, | ||
121 | success: function(data, status) { | ||
122 | if (status == 'success') { | ||
123 | DisplaySessionStatsDetails(data); | ||
124 | } | ||
125 | }, | ||
126 | error: function(xmlHTTPRequest, errorType) { | ||
127 | // DebugLog('Failed fetch'); | ||
128 | } | ||
129 | }); | ||
130 | }; | ||
131 | |||
132 | function DisplaySimStatDetails(data) { | ||
133 | var simInfo = new StringBuffer(); | ||
134 | simInfo.append('<table id="RegionStatsTable">'); | ||
135 | simInfo.append('<tr>'); | ||
136 | simInfo.append('<th>Total Users</th>'); | ||
137 | simInfo.append('<th>Total Sessions</th>'); | ||
138 | simInfo.append('<th>Avg client FPS</th>'); | ||
139 | simInfo.append('<th>Avg client Mem</th>'); | ||
140 | simInfo.append('<th>Avg ping time</th>'); | ||
141 | simInfo.append('<th>KB out</th>'); | ||
142 | simInfo.append('<th>KB in</th>'); | ||
143 | simInfo.append('</tr>'); | ||
144 | simInfo.append('<tr>'); | ||
145 | simInfo.append('<td>' + data.totalUsers + '</td>'); | ||
146 | simInfo.append('<td>' + data.totalSessions + '</td>'); | ||
147 | simInfo.append('<td>' + data.averageClientFPS + '</td>'); | ||
148 | simInfo.append('<td>' + data.averageClientMem + '</td>'); | ||
149 | simInfo.append('<td>' + data.averagePingTime + '</td>'); | ||
150 | simInfo.append('<td>' + data.totalKBOut + '</td>'); | ||
151 | simInfo.append('<td>' + data.totalKBIn + '</td>'); | ||
152 | simInfo.append('</tr>'); | ||
153 | simInfo.append('</table>'); | ||
154 | $('#SimSimStats').empty(); | ||
155 | $('#SimSimStats').append(simInfo.toString()); | ||
156 | } | ||
157 | |||
158 | function DisplayRegionStatDetails(data) { | ||
159 | var regionInfo = new StringBuffer(); | ||
160 | regionInfo.append('<table id="RegionStatsTable">'); | ||
161 | regionInfo.append('<tr>'); | ||
162 | regionInfo.append('<th>Region</th>'); | ||
163 | regionInfo.append('<th>Agents</th>'); | ||
164 | regionInfo.append('<th>Child</th>'); | ||
165 | regionInfo.append('<th>FPS</th>'); | ||
166 | regionInfo.append('<th>Frame Time</th>'); | ||
167 | regionInfo.append('<th>Phys Time</th>'); | ||
168 | regionInfo.append('<th>Prims</th>'); | ||
169 | regionInfo.append('</tr>'); | ||
170 | for (region in data) { | ||
171 | regionInfo.append('<tr>'); | ||
172 | regionInfo.append('<td>' + data[region].region + '</td>'); | ||
173 | regionInfo.append('<td>' + data[region].rootAgents + '</td>'); | ||
174 | regionInfo.append('<td>' + data[region].childAgents + '</td>'); | ||
175 | regionInfo.append('<td>' + data[region].simFPS + '</td>'); | ||
176 | regionInfo.append('<td>' + data[region].totalFrameTime + '</td>'); | ||
177 | regionInfo.append('<td>' + data[region].physicsFrameTime + '</td>'); | ||
178 | regionInfo.append('<td>' + data[region].totalPrims + '</td>'); | ||
179 | regionInfo.append('</tr>'); | ||
180 | } | ||
181 | regionInfo.append('</table>'); | ||
182 | $('#SimRegionStats').empty(); | ||
183 | $('#SimRegionStats').append(regionInfo.toString()); | ||
184 | } | ||
185 | |||
186 | function DisplayLogFileDetails(data) { | ||
187 | var logInfo = new StringBuffer(); | ||
188 | var logPattern = /^(.+),\d\d\d .* \[(.+)\]: (.+)$/; | ||
189 | for (logLine in data['logLines']) { | ||
190 | logInfo.append('<div>'); | ||
191 | var logPieces = logPattern.exec(data['logLines'][logLine]); | ||
192 | if (logPieces) { | ||
193 | logInfo.append(logPieces[1] + ' [' + logPieces[2] | ||
194 | + '] ' + logPieces[3]); | ||
195 | } | ||
196 | else { | ||
197 | logInfo.append(data['logLines'][logLine]); | ||
198 | } | ||
199 | |||
200 | logInfo.append('</div>'); | ||
201 | } | ||
202 | $('#SimLogFile').empty(); | ||
203 | $('#SimLogFile').append(logInfo.toString()); | ||
204 | } | ||
205 | |||
206 | function DisplaySessionStatsDetails(data) { | ||
207 | var userInfo = new StringBuffer(); | ||
208 | userInfo.append('<table>'); | ||
209 | userInfo.append('<tr>'); | ||
210 | userInfo.append('<th>region</th>'); | ||
211 | userInfo.append('<th>user</th>'); | ||
212 | userInfo.append('<th></th>'); | ||
213 | userInfo.append('<th>position</th>'); | ||
214 | userInfo.append('</tr>'); | ||
215 | for (region in data) { | ||
216 | for (user in data[region]) { | ||
217 | if (user != 'queues') { | ||
218 | userInfo.append('<tr>'); | ||
219 | userInfo.append('<td>' + region + '</td>'); | ||
220 | userInfo.append('<td>' + data[region][user].Name + '</td>'); | ||
221 | if (data[region][user].isRoot == 'true') { | ||
222 | userInfo.append('<td>root</td>'); | ||
223 | } | ||
224 | else { | ||
225 | userInfo.append('<td>child</td>'); | ||
226 | } | ||
227 | userInfo.append('<td>' + data[region][user].position + '</td>'); | ||
228 | userInfo.append('</tr>'); | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | userInfo.append('</table>'); | ||
233 | $('#SimSessionStats').empty(); | ||
234 | $('#SimSessionStats').append(userInfo.toString()); | ||
235 | } | ||
236 | |||
237 | function DebugLog(msg) { | ||
238 | $("#DEBUG").append('<div>' + msg + '</div>'); | ||
239 | $("#DEBUG").show(); | ||
240 | } | ||
241 | |||
242 | function StringBuffer() { | ||
243 | this.__strings__ = new Array; | ||
244 | } | ||
245 | StringBuffer.prototype.append = function(str) { | ||
246 | this.__strings__.push(str); | ||
247 | } | ||
248 | StringBuffer.prototype.toString = function() { | ||
249 | return this.__strings__.join(""); | ||
250 | } | ||
251 | |||
252 | </script> | ||
253 | </head> | ||
254 | <body id="SimBody"> | ||
255 | <div id="SimHeader"></div> | ||
256 | <div id="SimContent"> | ||
257 | |||
258 | <!-- ============================================== --> | ||
259 | <div class="SimSectionContainer"> | ||
260 | <a class="SimSectionHeader" href="#">Simulator Stats</a> | ||
261 | <div id="SimSimStats" class="SimSection"> | ||
262 | </div> <!-- SimSimStats --> | ||
263 | </div> <!-- SimSectionContainer --> | ||
264 | |||
265 | <!-- ============================================== --> | ||
266 | <div class="SimSectionContainer"> | ||
267 | <a class="SimSectionHeader" href="#">Region Stats</a> | ||
268 | <div id="SimRegionStats" class="SimSection"> | ||
269 | </div> <!-- SimRegionStats --> | ||
270 | </div> <!-- SimSectionContainer --> | ||
271 | |||
272 | <!-- ============================================== --> | ||
273 | <div class="SimSectionContainer"> | ||
274 | <a class="SimSectionHeader" href="#">Sessions</a> | ||
275 | <div id="SimSessionStats" class="SimSection"> | ||
276 | </div> <!-- SimSessionStats --> | ||
277 | </div> <!-- SimSectionContainer --> | ||
278 | |||
279 | <!-- ============================================== --> | ||
280 | <div class="SimSectionContainer"> | ||
281 | <a class="SimSectionHeader" href="#">Log File</a> | ||
282 | <div id="SimLogFile" class="SimSection"> | ||
283 | </div> <!-- SimLogFile --> | ||
284 | </div> <!-- SimSectionContainer --> | ||
285 | |||
286 | <!-- ============================================== --> | ||
287 | </div> <!-- SimContent --> | ||
288 | <div id="DEBUG"></div> | ||
289 | <div id="SimFooter"></div> | ||
290 | </body> | ||
291 | </html> | ||