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.user_profiles
parent
d5b950633d
commit
427ab219b8
|
@ -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>();
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,5 +34,6 @@ namespace OpenSim.Region.UserStatistics
|
|||
string ReportName { get; }
|
||||
Hashtable ProcessModel(Hashtable pParams);
|
||||
string RenderView(Hashtable pModelResult);
|
||||
string RenderJson(Hashtable pModelResult);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open));
|
||||
prototypejs = fs.ReadToEnd();
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
pResult["js"] = prototypejs;
|
||||
pResult["js"] = jsFileName;
|
||||
return pResult;
|
||||
}
|
||||
|
||||
public string RenderView(Hashtable pModelResult)
|
||||
{
|
||||
return pModelResult["js"].ToString();
|
||||
string fileName = (string)pModelResult["js"];
|
||||
using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open)))
|
||||
{
|
||||
prototypejs = fs.ReadToEnd();
|
||||
fs.Close();
|
||||
}
|
||||
return prototypejs;
|
||||
}
|
||||
|
||||
public string RenderJson(Hashtable pModelResult)
|
||||
{
|
||||
return "{}";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -278,6 +278,11 @@ TD.align_top { vertical-align: top; }
|
|||
public DateTime start_time;
|
||||
}
|
||||
|
||||
public string RenderJson(Hashtable pModelResult)
|
||||
{
|
||||
return "{}";
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,5 +62,9 @@ namespace OpenSim.Region.UserStatistics
|
|||
return pModelResult["js"].ToString();
|
||||
}
|
||||
|
||||
public string RenderJson(Hashtable pModelResult) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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++;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
Loading…
Reference in New Issue