From 427ab219b8ecf7f039d03ed3067e183db1434fb2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 10:44:57 -0800 Subject: Add JSONification of WebStats module. Adds a '?json' query parameter to the fetch URL to return the data in JSON format. Also adds a simple 'sim.html' that uses JavaScript to display the JSON data. Not pretty but an example. --- .../Region/UserStatistics/ActiveConnectionsAJAX.cs | 84 +++++- OpenSim/Region/UserStatistics/Clients_report.cs | 27 ++ OpenSim/Region/UserStatistics/Default_Report.cs | 27 ++ OpenSim/Region/UserStatistics/IStatsReport.cs | 1 + OpenSim/Region/UserStatistics/LogLinesAJAX.cs | 29 ++ .../Region/UserStatistics/Prototype_distributor.cs | 31 ++- OpenSim/Region/UserStatistics/Sessions_Report.cs | 5 + OpenSim/Region/UserStatistics/SimStatsAJAX.cs | 59 +++++ .../Region/UserStatistics/Updater_distributor.cs | 4 + OpenSim/Region/UserStatistics/WebStatsModule.cs | 25 +- bin/data/LICENSE-README-IMPORTANT.txt | 2 +- bin/data/sim.css | 85 ++++++ bin/data/sim.html | 291 +++++++++++++++++++++ 13 files changed, 658 insertions(+), 12 deletions(-) create mode 100644 bin/data/sim.css create mode 100644 bin/data/sim.html 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; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -51,7 +52,6 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { - List<Scene> m_scene = (List<Scene>)pParams["Scenes"]; Hashtable nh = new Hashtable(); @@ -129,6 +129,86 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// <summary> + /// Convert active connections information to JSON string. Returns a structure: + /// <pre> + /// {"regionName": { + /// "presenceName": { + /// "name": "presenceName", + /// "position": "<x,y,z>", + /// "isRoot": "false", + /// "throttle": { + /// }, + /// "queue": { + /// } + /// }, + /// ... // multiple presences in the scene + /// }, + /// ... // multiple regions in the sim + /// } + /// + /// </pre> + /// </summary> + /// <param name="pModelResult"></param> + /// <returns></returns> + public string RenderJson(Hashtable pModelResult) + { + List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; + + OSDMap regionInfo = new OSDMap(); + foreach (Scene scene in all_scenes) + { + OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap(); + List<ScenePresence> avatarInScene = scene.GetScenePresences(); + foreach (ScenePresence av in avatarInScene) + { + OSDMap presenceInfo = new OSDMap(); + presenceInfo.Add("Name", new OSDString(av.Name)); + + Dictionary<string,string> queues = new Dictionary<string, string>(); + if (av.ControllingClient is IStatsCollector) + { + IStatsCollector isClient = (IStatsCollector) av.ControllingClient; + queues = decodeQueueReport(isClient.Report()); + } + OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (KeyValuePair<string, string> kvp in queues) { + queueInfo.Add(kvp.Key, new OSDString(kvp.Value)); + } + sceneInfo.Add("queues", queueInfo); + + if (av.IsChildAgent) + presenceInfo.Add("isRoot", new OSDString("false")); + else + presenceInfo.Add("isRoot", new OSDString("true")); + + if (av.AbsolutePosition == DefaultNeighborPosition) + { + presenceInfo.Add("position", new OSDString("<0, 0, 0>")); + } + else + { + presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>", + (int)av.AbsolutePosition.X, + (int) av.AbsolutePosition.Y, + (int) av.AbsolutePosition.Z)) ); + } + + Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); + OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (string throttlename in throttles.Keys) + { + throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString())); + } + presenceInfo.Add("throttle", throttleInfo); + + sceneInfo.Add(av.Name, presenceInfo); + } + regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo); + } + return regionInfo.ToString(); + } + public Dictionary<string, int> DecodeClientThrottles(byte[] throttle) { Dictionary<string, int> returndict = new Dictionary<string, int>(); @@ -203,7 +283,7 @@ namespace OpenSim.Region.UserStatistics returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; - returndic.Add("Asset", rep.Substring((7 * pos), 8)); + returndic.Add("Asset", rep.Substring((7 * pos), 8)); /* * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", 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; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.UserStatistics @@ -44,6 +45,32 @@ namespace OpenSim.Region.UserStatistics get { return "Client"; } } + /// <summary> + /// Return summar information in the form: + /// <pre> + /// {"totalUsers": "34", + /// "totalSessions": "233", + /// ... + /// } + /// </pre> + /// </summary> + /// <param name="pModelResult"></param> + /// <returns></returns> + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OpenMetaverse.StructuredData.OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } + public Hashtable ProcessModel(Hashtable pParams) { 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; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -230,6 +231,31 @@ TD.align_top { vertical-align: top; } return returnstruct; } + /// <summary> + /// Return summar information in the form: + /// <pre> + /// {"totalUsers": "34", + /// "totalSessions": "233", + /// ... + /// } + /// </pre> + /// </summary> + /// <param name="pModelResult"></param> + /// <returns></returns> + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } } public struct stats_default_page_values @@ -247,4 +273,5 @@ TD.align_top { vertical-align: top; } public Dictionary<UUID, USimStatsData> sim_stat_data; public Dictionary<string, IStatsController> stats_reports; } + } 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 string ReportName { get; } Hashtable ProcessModel(Hashtable pParams); string RenderView(Hashtable pModelResult); + string RenderJson(Hashtable pModelResult); } } 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; using System.Text.RegularExpressions; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -125,6 +126,34 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// <summary> + /// Return the last log lines. Output in the format: + /// <pre> + /// {"logLines": [ + /// "line1", + /// "line2", + /// ... + /// ] + /// } + /// </pre> + /// </summary> + /// <param name="pModelResult"></param> + /// <returns></returns> + public string RenderJson(Hashtable pModelResult) + { + OSDMap logInfo = new OpenMetaverse.StructuredData.OSDMap(); + + OSDArray logLines = new OpenMetaverse.StructuredData.OSDArray(); + string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n"); + string[] result = Regex.Split(tmp, "\n"); + for (int i = 0; i < result.Length; i++) + { + logLines.Add(new OSDString(result[i])); + } + logInfo.Add("logLines", logLines); + return logInfo.ToString(); + } + #endregion } } 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 { public class Prototype_distributor : IStatsController { - private string prototypejs=string.Empty; + private string jsFileName = "prototype.js"; + private string prototypejs = string.Empty; + + public Prototype_distributor() + { + jsFileName = "prototype.js"; + } + + public Prototype_distributor(string jsName) + { + jsFileName = jsName; + } public string ReportName { @@ -45,20 +56,24 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { Hashtable pResult = new Hashtable(); - if (prototypejs.Length == 0) + pResult["js"] = jsFileName; + return pResult; + } + + public string RenderView(Hashtable pModelResult) + { + string fileName = (string)pModelResult["js"]; + using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open))) { - StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open)); prototypejs = fs.ReadToEnd(); fs.Close(); - fs.Dispose(); } - pResult["js"] = prototypejs; - return pResult; + return prototypejs; } - public string RenderView(Hashtable pModelResult) + public string RenderJson(Hashtable pModelResult) { - return pModelResult["js"].ToString(); + return "{}"; } } 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; } public DateTime start_time; } + public string RenderJson(Hashtable pModelResult) + { + return "{}"; + } #endregion } + } 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; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -218,6 +219,64 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// <summary> + /// Return stat information for all regions in the sim. Returns data of the form: + /// <pre> + /// {"REGIONNAME": { + /// "region": "REGIONNAME", + /// "timeDilation": "101", + /// ... // the rest of the stat info + /// }, + /// ... // entries for each region + /// } + /// </pre> + /// </summary> + /// <param name="pModelResult"></param> + /// <returns></returns> + public string RenderJson(Hashtable pModelResult) + { + List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; + Dictionary<UUID, USimStatsData> sdatadic = (Dictionary<UUID,USimStatsData>)pModelResult["simstats"]; + + OSDMap allStatsInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (USimStatsData sdata in sdatadic.Values) + { + OSDMap statsInfo = new OpenMetaverse.StructuredData.OSDMap(); + string regionName = "unknown"; + foreach (Scene sn in all_scenes) + { + if (sn.RegionInfo.RegionID == sdata.RegionId) + { + regionName = sn.RegionInfo.RegionName; + break; + } + } + statsInfo.Add("region", new OSDString(regionName)); + statsInfo.Add("timeDilation", new OSDString(sdata.TimeDilation.ToString())); + statsInfo.Add("simFPS", new OSDString(sdata.SimFps.ToString())); + statsInfo.Add("physicsFPS", new OSDString(sdata.PhysicsFps.ToString())); + statsInfo.Add("agentUpdates", new OSDString(sdata.AgentUpdates.ToString())); + statsInfo.Add("rootAgents", new OSDString(sdata.RootAgents.ToString())); + statsInfo.Add("childAgents", new OSDString(sdata.ChildAgents.ToString())); + statsInfo.Add("totalPrims", new OSDString(sdata.TotalPrims.ToString())); + statsInfo.Add("activePrims", new OSDString(sdata.ActivePrims.ToString())); + statsInfo.Add("activeScripts", new OSDString(sdata.ActiveScripts.ToString())); + statsInfo.Add("scriptLinesPerSec", new OSDString(sdata.ScriptLinesPerSecond.ToString())); + statsInfo.Add("totalFrameTime", new OSDString(sdata.TotalFrameTime.ToString())); + statsInfo.Add("agentFrameTime", new OSDString(sdata.AgentFrameTime.ToString())); + statsInfo.Add("physicsFrameTime", new OSDString(sdata.PhysicsFrameTime.ToString())); + statsInfo.Add("otherFrameTime", new OSDString(sdata.OtherFrameTime.ToString())); + statsInfo.Add("outPacketsPerSec", new OSDString(sdata.OutPacketsPerSecond.ToString())); + statsInfo.Add("inPacketsPerSec", new OSDString(sdata.InPacketsPerSecond.ToString())); + statsInfo.Add("unackedByptes", new OSDString(sdata.UnackedBytes.ToString())); + statsInfo.Add("pendingDownloads", new OSDString(sdata.PendingDownloads.ToString())); + statsInfo.Add("pendingUploads", new OSDString(sdata.PendingUploads.ToString())); + + allStatsInfo.Add(regionName, statsInfo); + } + return allStatsInfo.ToString(); + } + #endregion } } 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 return pModelResult["js"].ToString(); } + public string RenderJson(Hashtable pModelResult) { + return "{}"; + } + } } \ 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 reports.Add("clients.report", clientReport); reports.Add("sessions.report", sessionsReport); + reports.Add("sim.css", new Prototype_distributor("sim.css")); + reports.Add("sim.html", new Prototype_distributor("sim.html")); + reports.Add("jquery.js", new Prototype_distributor("jquery.js")); + //// // Add Your own Reports here (Do Not Modify Lines here Devs!) //// @@ -255,9 +259,12 @@ namespace OpenSim.Region.UserStatistics string regpath = request["uri"].ToString(); int response_code = 404; string contenttype = "text/html"; + bool jsonFormatOutput = false; string strOut = string.Empty; + // The request patch should be "/SStats/reportName" where 'reportName' + // is one of the names added to the 'reports' hashmap. regpath = regpath.Remove(0, 8); if (regpath.Length == 0) regpath = "default.report"; if (reports.ContainsKey(regpath)) @@ -265,6 +272,9 @@ namespace OpenSim.Region.UserStatistics IStatsController rep = reports[regpath]; Hashtable repParams = new Hashtable(); + if (request.ContainsKey("json")) + jsonFormatOutput = true; + if (request.ContainsKey("requestvars")) repParams["RequestVars"] = request["requestvars"]; else @@ -284,13 +294,26 @@ namespace OpenSim.Region.UserStatistics concurrencyCounter++; - strOut = rep.RenderView(rep.ProcessModel(repParams)); + if (jsonFormatOutput) + { + strOut = rep.RenderJson(rep.ProcessModel(repParams)); + contenttype = "text/json"; + } + else + { + strOut = rep.RenderView(rep.ProcessModel(repParams)); + } if (regpath.EndsWith("js")) { contenttype = "text/javascript"; } + if (regpath.EndsWith("css")) + { + contenttype = "text/css"; + } + concurrencyCounter--; 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 These files are: -- avataranimations.xml (Derivative work of viewerart.ini, Creative Commons Attribution+Share-Alike v2.5 License) \ No newline at end of file +- 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 @@ +body { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 12px; + background: #4A5F6D; + color: #EEEAD6; + padding: 0px; + margin: 0px; +} +.footer { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 10px; +} +td { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-size: 12px; + padding: 4px; + margin: 4px; +} +blockquote { + font-family: Veranda,Arial,Helvetica,sans-serif; + font-style: italic; + font-size: 12px; +} +pre { + padding: 5px; + background-color: #8080B0; + color: #000000; + margin-left: 20px; + font-size: 11px; +} +:link { + color: #ffffff; +} +:visited { + color: #d0d0d0; +} +.SimSectionHeader { + font-size: 120%; +} +div.SimSectionContainer { + padding: 10px 0px 0px 20px; +} +/* SimStats ===================================== */ +#SimSimStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimSimStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* Region Stats ===================================== */ +#SimRegionStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimRegionStats table { + border: 1px; + border-style: solid; +} +#SimRegionStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* Session Stats ===================================== */ +#SimSessionStats div { + margin-left: 20px; + background: #3A4F5D; +} +#SimSessionStats table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} +/* LogFile ===================================== */ +#SimLogFile div { + margin-left: 20px; +} +#SimLogFile table td { + text-align: right; + padding: 0px 0px 0px 5px; + margin: 0px 0px 0px 0px; +} 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 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Simulator statistics</title> +<link rel="stylesheet" href="sim.css" type="text/css"/> +<!-- <script type="text/javascript" src="jquery.js"></script> --> +<!-- <script type="text/javascript" src="https://code.jquery.com/jquery-1.9.0.min.js"></script> --> +<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> +<!-- <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/libs/jQuery/jquery-1.9.0.min.js"></script> --> +<noscript> +<p color="red"> +Your browser does not support Javascript. This won't work for you. +</p> +</noscript> +<script type="text/javascript"> +$(document).ready(function() { + // Major divisions in the content accordioning + $('.SimSection').show('slow'); + $('.SimSectionHeader').click(function() { + $(this).next().slideToggle('slow'); + return false; + }); + + // Start the timed functions + TimerDataStuff(); +}); + +// One of the sections is viewer statistics. Poll for the data. +var statTimerHandle; +var graphFPS; +var lastFPS = 10; +var xxThru = 0; +function TimerDataStuff() { + statTimerHandle = setInterval('TimerStatDisplay()', 5000); +} + +// called by timer to fetch and display statistic information +var doingStatDisplay = false; +function TimerStatDisplay() { + if (doingStatDisplay) return; + doingStatDisplay = true; + if ($('#SimSimStats').is(':visible')) { + DisplaySimStats(); + } + if ($('#SimRegionStats').is(':visible')) { + DisplayPerRegionStats(); + } + if ($('#SimSessionStats').is(':visible')) { + DisplaySessionStats(); + } + if ($('#SimLogFile').is(':visible')) { + DisplayLogFile(); + } + doingStatDisplay = false; +} + +var simName = "127.0.0.1"; +var simPort = "9000"; +function DisplaySimStats() { + var statURL = "http://" + simName + ":" + simPort + "/SStats/?json=1"; + $.ajax({ + type: "GET", + url: statURL, + dataType: 'json', + timeout: 1000, + success: function(data, status) { + if (status == 'success') { + DisplaySimStatDetails(data); + } + }, + error: function(xmlHTTPRequest, errorType) { + // DebugLog('Failed fetch'); + } + }); +} + +function DisplayPerRegionStats() { + var statURL = "http://" + simName + ":" + simPort + "/SStats/simstatsajax.html?json=1"; + $.ajax({ + type: "GET", + url: statURL, + dataType: 'json', + timeout: 1000, + success: function(data, status) { + if (status == 'success') { + DisplayRegionStatDetails(data); + } + }, + error: function(xmlHTTPRequest, errorType) { + // DebugLog('Failed fetch'); + } + }); +}; + +function DisplayLogFile() { + var statURL = "http://" + simName + ":" + simPort + "/SStats/activelogajax.html?json=1"; + $.ajax({ + type: "GET", + url: statURL, + dataType: 'json', + timeout: 1000, + success: function(data, status) { + if (status == 'success') { + DisplayLogFileDetails(data); + } + }, + error: function(xmlHTTPRequest, errorType) { + // DebugLog('Failed fetch'); + } + }); +}; + +function DisplaySessionStats() { + var statURL = "http://" + simName + ":" + simPort + "/SStats/activeconnectionsajax.html?json=1"; + $.ajax({ + type: "GET", + url: statURL, + dataType: 'json', + timeout: 1000, + success: function(data, status) { + if (status == 'success') { + DisplaySessionStatsDetails(data); + } + }, + error: function(xmlHTTPRequest, errorType) { + // DebugLog('Failed fetch'); + } + }); +}; + +function DisplaySimStatDetails(data) { + var simInfo = new StringBuffer(); + simInfo.append('<table id="RegionStatsTable">'); + simInfo.append('<tr>'); + simInfo.append('<th>Total Users</th>'); + simInfo.append('<th>Total Sessions</th>'); + simInfo.append('<th>Avg client FPS</th>'); + simInfo.append('<th>Avg client Mem</th>'); + simInfo.append('<th>Avg ping time</th>'); + simInfo.append('<th>KB out</th>'); + simInfo.append('<th>KB in</th>'); + simInfo.append('</tr>'); + simInfo.append('<tr>'); + simInfo.append('<td>' + data.totalUsers + '</td>'); + simInfo.append('<td>' + data.totalSessions + '</td>'); + simInfo.append('<td>' + data.averageClientFPS + '</td>'); + simInfo.append('<td>' + data.averageClientMem + '</td>'); + simInfo.append('<td>' + data.averagePingTime + '</td>'); + simInfo.append('<td>' + data.totalKBOut + '</td>'); + simInfo.append('<td>' + data.totalKBIn + '</td>'); + simInfo.append('</tr>'); + simInfo.append('</table>'); + $('#SimSimStats').empty(); + $('#SimSimStats').append(simInfo.toString()); +} + +function DisplayRegionStatDetails(data) { + var regionInfo = new StringBuffer(); + regionInfo.append('<table id="RegionStatsTable">'); + regionInfo.append('<tr>'); + regionInfo.append('<th>Region</th>'); + regionInfo.append('<th>Agents</th>'); + regionInfo.append('<th>Child</th>'); + regionInfo.append('<th>FPS</th>'); + regionInfo.append('<th>Frame Time</th>'); + regionInfo.append('<th>Phys Time</th>'); + regionInfo.append('<th>Prims</th>'); + regionInfo.append('</tr>'); + for (region in data) { + regionInfo.append('<tr>'); + regionInfo.append('<td>' + data[region].region + '</td>'); + regionInfo.append('<td>' + data[region].rootAgents + '</td>'); + regionInfo.append('<td>' + data[region].childAgents + '</td>'); + regionInfo.append('<td>' + data[region].simFPS + '</td>'); + regionInfo.append('<td>' + data[region].totalFrameTime + '</td>'); + regionInfo.append('<td>' + data[region].physicsFrameTime + '</td>'); + regionInfo.append('<td>' + data[region].totalPrims + '</td>'); + regionInfo.append('</tr>'); + } + regionInfo.append('</table>'); + $('#SimRegionStats').empty(); + $('#SimRegionStats').append(regionInfo.toString()); +} + +function DisplayLogFileDetails(data) { + var logInfo = new StringBuffer(); + var logPattern = /^(.+),\d\d\d .* \[(.+)\]: (.+)$/; + for (logLine in data['logLines']) { + logInfo.append('<div>'); + var logPieces = logPattern.exec(data['logLines'][logLine]); + if (logPieces) { + logInfo.append(logPieces[1] + ' [' + logPieces[2] + + '] ' + logPieces[3]); + } + else { + logInfo.append(data['logLines'][logLine]); + } + + logInfo.append('</div>'); + } + $('#SimLogFile').empty(); + $('#SimLogFile').append(logInfo.toString()); +} + +function DisplaySessionStatsDetails(data) { + var userInfo = new StringBuffer(); + userInfo.append('<table>'); + userInfo.append('<tr>'); + userInfo.append('<th>region</th>'); + userInfo.append('<th>user</th>'); + userInfo.append('<th></th>'); + userInfo.append('<th>position</th>'); + userInfo.append('</tr>'); + for (region in data) { + for (user in data[region]) { + if (user != 'queues') { + userInfo.append('<tr>'); + userInfo.append('<td>' + region + '</td>'); + userInfo.append('<td>' + data[region][user].Name + '</td>'); + if (data[region][user].isRoot == 'true') { + userInfo.append('<td>root</td>'); + } + else { + userInfo.append('<td>child</td>'); + } + userInfo.append('<td>' + data[region][user].position + '</td>'); + userInfo.append('</tr>'); + } + } + } + userInfo.append('</table>'); + $('#SimSessionStats').empty(); + $('#SimSessionStats').append(userInfo.toString()); +} + +function DebugLog(msg) { + $("#DEBUG").append('<div>' + msg + '</div>'); + $("#DEBUG").show(); +} + +function StringBuffer() { + this.__strings__ = new Array; +} +StringBuffer.prototype.append = function(str) { + this.__strings__.push(str); +} +StringBuffer.prototype.toString = function() { + return this.__strings__.join(""); +} + +</script> +</head> +<body id="SimBody"> +<div id="SimHeader"></div> +<div id="SimContent"> + +<!-- ============================================== --> +<div class="SimSectionContainer"> +<a class="SimSectionHeader" href="#">Simulator Stats</a> +<div id="SimSimStats" class="SimSection"> +</div> <!-- SimSimStats --> +</div> <!-- SimSectionContainer --> + +<!-- ============================================== --> +<div class="SimSectionContainer"> +<a class="SimSectionHeader" href="#">Region Stats</a> +<div id="SimRegionStats" class="SimSection"> +</div> <!-- SimRegionStats --> +</div> <!-- SimSectionContainer --> + +<!-- ============================================== --> +<div class="SimSectionContainer"> +<a class="SimSectionHeader" href="#">Sessions</a> +<div id="SimSessionStats" class="SimSection"> +</div> <!-- SimSessionStats --> +</div> <!-- SimSectionContainer --> + +<!-- ============================================== --> +<div class="SimSectionContainer"> +<a class="SimSectionHeader" href="#">Log File</a> +<div id="SimLogFile" class="SimSection"> +</div> <!-- SimLogFile --> +</div> <!-- SimSectionContainer --> + +<!-- ============================================== --> +</div> <!-- SimContent --> +<div id="DEBUG"></div> +<div id="SimFooter"></div> +</body> +</html> -- cgit v1.1