Extend "show stats" command to "show stats [list|all|<category name>]"
This allows different categories of stats to be shown, with options to list categories or show all stats. Currently categories are scene and simulator and only a very few stats are currently registered via this mechanism. This commit also adds percentage stats for packets and blocks reused from the packet pool.0.7.4-extended
parent
0afc43eed7
commit
6c3eceb197
|
@ -359,13 +359,19 @@ Asset service request failures: {3}" + Environment.NewLine,
|
||||||
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
|
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
|
||||||
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
|
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
|
||||||
|
|
||||||
foreach (KeyValuePair<string, Stat> kvp in StatsManager.RegisteredStats)
|
Dictionary<string, Dictionary<string, Stat>> sceneStats;
|
||||||
{
|
|
||||||
Stat stat = kvp.Value;
|
|
||||||
|
|
||||||
if (stat.Category == "scene" && stat.Verbosity == StatVerbosity.Info)
|
if (StatsManager.TryGetStats("scene", out sceneStats))
|
||||||
{
|
{
|
||||||
sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value);
|
foreach (KeyValuePair<string, Dictionary<string, Stat>> kvp in sceneStats)
|
||||||
|
{
|
||||||
|
foreach (Stat stat in kvp.Value.Values)
|
||||||
|
{
|
||||||
|
if (stat.Verbosity == StatVerbosity.Info)
|
||||||
|
{
|
||||||
|
sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Monitoring
|
namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
|
@ -35,13 +36,23 @@ namespace OpenSim.Framework.Monitoring
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StatsManager
|
public class StatsManager
|
||||||
{
|
{
|
||||||
|
// Subcommand used to list other stats.
|
||||||
|
public const string AllSubCommand = "all";
|
||||||
|
|
||||||
|
// Subcommand used to list other stats.
|
||||||
|
public const string ListSubCommand = "list";
|
||||||
|
|
||||||
|
// All subcommands
|
||||||
|
public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registered stats.
|
/// Registered stats categorized by category/container/shortname
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Do not add or remove from this dictionary.
|
/// Do not add or remove directly from this dictionary.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>();
|
public static Dictionary<string, Dictionary<string, Dictionary<string, Stat>>> RegisteredStats
|
||||||
|
= new Dictionary<string, Dictionary<string, Dictionary<string, Stat>>>();
|
||||||
|
|
||||||
private static AssetStatsCollector assetStats;
|
private static AssetStatsCollector assetStats;
|
||||||
private static UserStatsCollector userStats;
|
private static UserStatsCollector userStats;
|
||||||
|
@ -51,6 +62,76 @@ namespace OpenSim.Framework.Monitoring
|
||||||
public static UserStatsCollector UserStats { get { return userStats; } }
|
public static UserStatsCollector UserStats { get { return userStats; } }
|
||||||
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
||||||
|
|
||||||
|
public static void RegisterConsoleCommands(CommandConsole console)
|
||||||
|
{
|
||||||
|
console.Commands.AddCommand(
|
||||||
|
"General",
|
||||||
|
false,
|
||||||
|
"show stats",
|
||||||
|
"show stats [list|all|<category>]",
|
||||||
|
"Show statistical information for this server",
|
||||||
|
"If no final argument is specified then legacy statistics information is currently shown.\n"
|
||||||
|
+ "If list is specified then statistic categories are shown.\n"
|
||||||
|
+ "If all is specified then all registered statistics are shown.\n"
|
||||||
|
+ "If a category name is specified then only statistics from that category are shown.\n"
|
||||||
|
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
|
||||||
|
HandleShowStatsCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleShowStatsCommand(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
ICommandConsole con = MainConsole.Instance;
|
||||||
|
|
||||||
|
if (cmd.Length > 2)
|
||||||
|
{
|
||||||
|
var categoryName = cmd[2];
|
||||||
|
|
||||||
|
if (categoryName == AllSubCommand)
|
||||||
|
{
|
||||||
|
foreach (var category in RegisteredStats.Values)
|
||||||
|
{
|
||||||
|
OutputCategoryStatsToConsole(con, category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (categoryName == ListSubCommand)
|
||||||
|
{
|
||||||
|
con.Output("Statistic categories available are:");
|
||||||
|
foreach (string category in RegisteredStats.Keys)
|
||||||
|
con.OutputFormat(" {0}", category);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dictionary<string, Dictionary<string, Stat>> category;
|
||||||
|
if (!RegisteredStats.TryGetValue(categoryName, out category))
|
||||||
|
{
|
||||||
|
con.OutputFormat("No such category as {0}", categoryName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutputCategoryStatsToConsole(con, category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Legacy
|
||||||
|
con.Output(SimExtraStats.Report());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OutputCategoryStatsToConsole(
|
||||||
|
ICommandConsole con, Dictionary<string, Dictionary<string, Stat>> category)
|
||||||
|
{
|
||||||
|
foreach (var container in category.Values)
|
||||||
|
{
|
||||||
|
foreach (Stat stat in container.Values)
|
||||||
|
{
|
||||||
|
con.OutputFormat(
|
||||||
|
"{0}.{1}.{2} : {3}{4}", stat.Category, stat.Container, stat.ShortName, stat.Value, stat.UnitName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start collecting statistics related to assets.
|
/// Start collecting statistics related to assets.
|
||||||
/// Should only be called once.
|
/// Should only be called once.
|
||||||
|
@ -73,43 +154,100 @@ namespace OpenSim.Framework.Monitoring
|
||||||
return userStats;
|
return userStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a statistic.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='stat'></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static bool RegisterStat(Stat stat)
|
public static bool RegisterStat(Stat stat)
|
||||||
{
|
{
|
||||||
|
Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
|
||||||
|
Dictionary<string, Stat> container = null, newContainer;
|
||||||
|
|
||||||
lock (RegisteredStats)
|
lock (RegisteredStats)
|
||||||
{
|
{
|
||||||
if (RegisteredStats.ContainsKey(stat.UniqueName))
|
// Stat name is not unique across category/container/shortname key.
|
||||||
{
|
|
||||||
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
|
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
|
||||||
// in a class are run in the same instance of the VM.
|
// in a class are run in the same instance of the VM.
|
||||||
|
if (TryGetStat(stat, out category, out container))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// throw new Exception(
|
// We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
|
||||||
// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category);
|
// This means that we don't need to lock or copy them on iteration, which will be a much more
|
||||||
}
|
// common operation after startup.
|
||||||
|
if (container != null)
|
||||||
|
newContainer = new Dictionary<string, Stat>(container);
|
||||||
|
else
|
||||||
|
newContainer = new Dictionary<string, Stat>();
|
||||||
|
|
||||||
// We take a replace-on-write approach here so that we don't need to generate a new Dictionary
|
if (category != null)
|
||||||
Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
|
newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
|
||||||
newRegisteredStats[stat.UniqueName] = stat;
|
else
|
||||||
RegisteredStats = newRegisteredStats;
|
newCategory = new Dictionary<string, Dictionary<string, Stat>>();
|
||||||
|
|
||||||
|
newContainer[stat.ShortName] = stat;
|
||||||
|
newCategory[stat.Container] = newContainer;
|
||||||
|
RegisteredStats[stat.Category] = newCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deregister a statistic
|
||||||
|
/// </summary>>
|
||||||
|
/// <param name='stat'></param>
|
||||||
|
/// <returns></returns
|
||||||
public static bool DeregisterStat(Stat stat)
|
public static bool DeregisterStat(Stat stat)
|
||||||
{
|
{
|
||||||
|
Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
|
||||||
|
Dictionary<string, Stat> container = null, newContainer;
|
||||||
|
|
||||||
lock (RegisteredStats)
|
lock (RegisteredStats)
|
||||||
{
|
{
|
||||||
if (!RegisteredStats.ContainsKey(stat.UniqueName))
|
if (!TryGetStat(stat, out category, out container))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
|
newContainer = new Dictionary<string, Stat>(container);
|
||||||
newRegisteredStats.Remove(stat.UniqueName);
|
newContainer.Remove(stat.UniqueName);
|
||||||
RegisteredStats = newRegisteredStats;
|
|
||||||
|
newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
|
||||||
|
newCategory.Remove(stat.Container);
|
||||||
|
|
||||||
|
newCategory[stat.Container] = newContainer;
|
||||||
|
RegisteredStats[stat.Category] = newCategory;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryGetStats(string category, out Dictionary<string, Dictionary<string, Stat>> stats)
|
||||||
|
{
|
||||||
|
return RegisteredStats.TryGetValue(category, out stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetStat(
|
||||||
|
Stat stat,
|
||||||
|
out Dictionary<string, Dictionary<string, Stat>> category,
|
||||||
|
out Dictionary<string, Stat> container)
|
||||||
|
{
|
||||||
|
category = null;
|
||||||
|
container = null;
|
||||||
|
|
||||||
|
lock (RegisteredStats)
|
||||||
|
{
|
||||||
|
if (RegisteredStats.TryGetValue(stat.Category, out category))
|
||||||
|
{
|
||||||
|
if (category.TryGetValue(stat.Container, out container))
|
||||||
|
{
|
||||||
|
if (container.ContainsKey(stat.ShortName))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -157,9 +295,26 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
public virtual double Value { get; set; }
|
public virtual double Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
|
||||||
|
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
|
||||||
|
/// <param name='unitName'>
|
||||||
|
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
|
||||||
|
/// e.g. " frames"
|
||||||
|
/// </param>
|
||||||
|
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
|
||||||
|
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
|
||||||
|
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
|
||||||
|
/// <param name='description'>Description of stat</param>
|
||||||
public Stat(
|
public Stat(
|
||||||
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
|
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
|
||||||
{
|
{
|
||||||
|
if (StatsManager.SubCommands.Contains(category))
|
||||||
|
throw new Exception(
|
||||||
|
string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
|
||||||
|
|
||||||
ShortName = shortName;
|
ShortName = shortName;
|
||||||
Name = name;
|
Name = name;
|
||||||
UnitName = unitName;
|
UnitName = unitName;
|
||||||
|
@ -203,7 +358,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
public PercentageStat(
|
public PercentageStat(
|
||||||
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
|
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
|
||||||
: base(shortName, name, " %", category, container, verbosity, description)
|
: base(shortName, name, "%", category, container, verbosity, description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,11 +96,6 @@ namespace OpenSim.Framework.Servers
|
||||||
get { return m_httpServer; }
|
get { return m_httpServer; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Holds the non-viewer statistics collection object for this service/server
|
|
||||||
/// </summary>
|
|
||||||
protected IStatsCollector m_stats;
|
|
||||||
|
|
||||||
public BaseOpenSimServer()
|
public BaseOpenSimServer()
|
||||||
{
|
{
|
||||||
m_startuptime = DateTime.Now;
|
m_startuptime = DateTime.Now;
|
||||||
|
@ -177,10 +172,6 @@ namespace OpenSim.Framework.Servers
|
||||||
"show info",
|
"show info",
|
||||||
"Show general information about the server", HandleShow);
|
"Show general information about the server", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("General", false, "show stats",
|
|
||||||
"show stats",
|
|
||||||
"Show statistics", HandleShow);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("General", false, "show threads",
|
m_console.Commands.AddCommand("General", false, "show threads",
|
||||||
"show threads",
|
"show threads",
|
||||||
"Show thread status", HandleShow);
|
"Show thread status", HandleShow);
|
||||||
|
@ -226,12 +217,7 @@ namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
|
StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
|
||||||
sb.Append(GetUptimeReport());
|
sb.Append(GetUptimeReport());
|
||||||
|
sb.Append(StatsManager.SimExtraStats.Report());
|
||||||
if (m_stats != null)
|
|
||||||
{
|
|
||||||
sb.Append(m_stats.Report());
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(Environment.NewLine);
|
sb.Append(Environment.NewLine);
|
||||||
sb.Append(GetThreadsReport());
|
sb.Append(GetThreadsReport());
|
||||||
|
|
||||||
|
@ -382,10 +368,6 @@ namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
|
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
|
||||||
Notice("show info - show server information (e.g. startup path).");
|
Notice("show info - show server information (e.g. startup path).");
|
||||||
|
|
||||||
if (m_stats != null)
|
|
||||||
Notice("show stats - show statistical information for this server");
|
|
||||||
|
|
||||||
Notice("show threads - list tracked threads");
|
Notice("show threads - list tracked threads");
|
||||||
Notice("show uptime - show server startup time and uptime.");
|
Notice("show uptime - show server startup time and uptime.");
|
||||||
Notice("show version - show server version.");
|
Notice("show version - show server version.");
|
||||||
|
@ -409,11 +391,6 @@ namespace OpenSim.Framework.Servers
|
||||||
ShowInfo();
|
ShowInfo();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "stats":
|
|
||||||
if (m_stats != null)
|
|
||||||
Notice(m_stats.Report());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "threads":
|
case "threads":
|
||||||
Notice(GetThreadsReport());
|
Notice(GetThreadsReport());
|
||||||
break;
|
break;
|
||||||
|
@ -605,7 +582,6 @@ namespace OpenSim.Framework.Servers
|
||||||
public string osSecret {
|
public string osSecret {
|
||||||
// Secret uuid for the simulator
|
// Secret uuid for the simulator
|
||||||
get { return m_osSecret; }
|
get { return m_osSecret; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string StatReport(IOSHttpRequest httpRequest)
|
public string StatReport(IOSHttpRequest httpRequest)
|
||||||
|
@ -613,11 +589,11 @@ namespace OpenSim.Framework.Servers
|
||||||
// If we catch a request for "callback", wrap the response in the value for jsonp
|
// If we catch a request for "callback", wrap the response in the value for jsonp
|
||||||
if (httpRequest.Query.ContainsKey("callback"))
|
if (httpRequest.Query.ContainsKey("callback"))
|
||||||
{
|
{
|
||||||
return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
|
return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
|
return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,8 +223,6 @@ namespace OpenSim
|
||||||
|
|
||||||
base.StartupSpecific();
|
base.StartupSpecific();
|
||||||
|
|
||||||
m_stats = StatsManager.SimExtraStats;
|
|
||||||
|
|
||||||
// Create a ModuleLoader instance
|
// Create a ModuleLoader instance
|
||||||
m_moduleLoader = new ModuleLoader(m_config.Source);
|
m_moduleLoader = new ModuleLoader(m_config.Source);
|
||||||
|
|
||||||
|
@ -234,13 +232,14 @@ namespace OpenSim
|
||||||
plugin.PostInitialise();
|
plugin.PostInitialise();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddPluginCommands();
|
if (m_console != null)
|
||||||
|
{
|
||||||
|
StatsManager.RegisterConsoleCommands(m_console);
|
||||||
|
AddPluginCommands(m_console);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddPluginCommands()
|
protected virtual void AddPluginCommands(CommandConsole console)
|
||||||
{
|
|
||||||
// If console exists add plugin commands.
|
|
||||||
if (m_console != null)
|
|
||||||
{
|
{
|
||||||
List<string> topics = GetHelpTopics();
|
List<string> topics = GetHelpTopics();
|
||||||
|
|
||||||
|
@ -250,11 +249,11 @@ namespace OpenSim
|
||||||
|
|
||||||
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
|
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
|
||||||
// away at some point.
|
// away at some point.
|
||||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
|
console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
|
||||||
"help " + capitalizedTopic,
|
"help " + capitalizedTopic,
|
||||||
"Get help on plugin command '" + topic + "'",
|
"Get help on plugin command '" + topic + "'",
|
||||||
HandleCommanderHelp);
|
HandleCommanderHelp);
|
||||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||||
"help " + capitalizedTopic,
|
"help " + capitalizedTopic,
|
||||||
"Get help on plugin command '" + topic + "'",
|
"Get help on plugin command '" + topic + "'",
|
||||||
HandleCommanderHelp);
|
HandleCommanderHelp);
|
||||||
|
@ -274,14 +273,13 @@ namespace OpenSim
|
||||||
|
|
||||||
foreach (string command in commander.Commands.Keys)
|
foreach (string command in commander.Commands.Keys)
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand(capitalizedTopic, false,
|
console.Commands.AddCommand(capitalizedTopic, false,
|
||||||
topic + " " + command,
|
topic + " " + command,
|
||||||
topic + " " + commander.Commands[command].ShortHelp(),
|
topic + " " + commander.Commands[command].ShortHelp(),
|
||||||
String.Empty, HandleCommanderCommand);
|
String.Empty, HandleCommanderCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleCommanderCommand(string module, string[] cmd)
|
private void HandleCommanderCommand(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Reflection;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using OpenSim.Framework.Monitoring;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
|
@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private bool packetPoolEnabled = true;
|
private bool packetPoolEnabled = true;
|
||||||
private bool dataBlockPoolEnabled = true;
|
private bool dataBlockPoolEnabled = true;
|
||||||
|
|
||||||
|
private PercentageStat m_packetsReusedStat = new PercentageStat(
|
||||||
|
"PacketsReused",
|
||||||
|
"Packets reused",
|
||||||
|
"simulator",
|
||||||
|
"simulator",
|
||||||
|
StatVerbosity.Debug,
|
||||||
|
"Number of packets reused out of all requests to the packet pool");
|
||||||
|
|
||||||
|
private PercentageStat m_blocksReusedStat = new PercentageStat(
|
||||||
|
"BlocksReused",
|
||||||
|
"Blocks reused",
|
||||||
|
"simulator",
|
||||||
|
"simulator",
|
||||||
|
StatVerbosity.Debug,
|
||||||
|
"Number of data blocks reused out of all requests to the packet pool");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pool of packets available for reuse.
|
/// Pool of packets available for reuse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
|
private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
|
||||||
|
|
||||||
private static Dictionary<Type, Stack<Object>> DataBlocks =
|
private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
|
||||||
new Dictionary<Type, Stack<Object>>();
|
|
||||||
|
|
||||||
static PacketPool()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketPool Instance
|
public static PacketPool Instance
|
||||||
{
|
{
|
||||||
|
@ -72,8 +84,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
get { return dataBlockPoolEnabled; }
|
get { return dataBlockPoolEnabled; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PacketPool()
|
||||||
|
{
|
||||||
|
StatsManager.RegisterStat(m_packetsReusedStat);
|
||||||
|
StatsManager.RegisterStat(m_blocksReusedStat);
|
||||||
|
}
|
||||||
|
|
||||||
public Packet GetPacket(PacketType type)
|
public Packet GetPacket(PacketType type)
|
||||||
{
|
{
|
||||||
|
m_packetsReusedStat.Consequent++;
|
||||||
|
|
||||||
Packet packet;
|
Packet packet;
|
||||||
|
|
||||||
if (!packetPoolEnabled)
|
if (!packetPoolEnabled)
|
||||||
|
@ -89,6 +109,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Recycle old packages
|
// Recycle old packages
|
||||||
|
m_packetsReusedStat.Antecedent++;
|
||||||
|
|
||||||
packet = (pool[type]).Pop();
|
packet = (pool[type]).Pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,17 +233,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T GetDataBlock<T>() where T: new()
|
public T GetDataBlock<T>() where T: new()
|
||||||
{
|
{
|
||||||
lock (DataBlocks)
|
lock (DataBlocks)
|
||||||
{
|
{
|
||||||
|
m_blocksReusedStat.Consequent++;
|
||||||
|
|
||||||
Stack<Object> s;
|
Stack<Object> s;
|
||||||
|
|
||||||
if (DataBlocks.TryGetValue(typeof(T), out s))
|
if (DataBlocks.TryGetValue(typeof(T), out s))
|
||||||
{
|
{
|
||||||
if (s.Count > 0)
|
if (s.Count > 0)
|
||||||
|
{
|
||||||
|
m_blocksReusedStat.Antecedent++;
|
||||||
return (T)s.Pop();
|
return (T)s.Pop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DataBlocks[typeof(T)] = new Stack<Object>();
|
DataBlocks[typeof(T)] = new Stack<Object>();
|
||||||
|
@ -231,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ReturnDataBlock<T>(T block) where T: new()
|
public void ReturnDataBlock<T>(T block) where T: new()
|
||||||
{
|
{
|
||||||
if (block == null)
|
if (block == null)
|
||||||
return;
|
return;
|
||||||
|
|
133
prebuild.xml
133
prebuild.xml
|
@ -112,72 +112,6 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Monitoring" path="OpenSim/Framework/Monitoring" type="Library">
|
|
||||||
<Configuration name="Debug">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../bin/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration name="Release">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../bin/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
|
|
||||||
<ReferencePath>../../../bin/</ReferencePath>
|
|
||||||
<Reference name="System"/>
|
|
||||||
<Reference name="System.Core"/>
|
|
||||||
<Reference name="log4net" path="../../../bin/"/>
|
|
||||||
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
|
|
||||||
<Reference name="OpenMetaverse" path="../../../bin/"/>
|
|
||||||
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
|
||||||
<Reference name="OpenSim.Framework"/>
|
|
||||||
|
|
||||||
<Files>
|
|
||||||
<Match pattern="*.cs" recurse="true"/>
|
|
||||||
</Files>
|
|
||||||
</Project>
|
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer" path="OpenSim/Framework/Servers/HttpServer" type="Library">
|
|
||||||
<Configuration name="Debug">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration name="Release">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
|
|
||||||
<ReferencePath>../../../../bin/</ReferencePath>
|
|
||||||
<Reference name="System"/>
|
|
||||||
<Reference name="System.Core"/>
|
|
||||||
<Reference name="System.Xml"/>
|
|
||||||
<Reference name="System.Web"/>
|
|
||||||
<Reference name="OpenSim.Framework"/>
|
|
||||||
<Reference name="OpenSim.Framework.Monitoring"/>
|
|
||||||
<Reference name="OpenMetaverse.StructuredData" path="../../../../bin/"/>
|
|
||||||
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
|
|
||||||
<Reference name="XMLRPC" path="../../../../bin/"/>
|
|
||||||
<Reference name="log4net" path="../../../../bin/"/>
|
|
||||||
<Reference name="HttpServer_OpenSim" path="../../../../bin/"/>
|
|
||||||
|
|
||||||
<Files>
|
|
||||||
<Match pattern="*.cs" recurse="true">
|
|
||||||
<Exclude pattern="Tests"/>
|
|
||||||
|
|
||||||
<!-- on temporary suspension -->
|
|
||||||
<Exclude pattern="OSHttpHandler\.cs"/>
|
|
||||||
<Exclude pattern="OSHttpHttpHandler\.cs"/>
|
|
||||||
<Exclude pattern="OSHttpRequestPump\.cs"/>
|
|
||||||
<Exclude pattern="OSHttpRequestQueue\.cs"/>
|
|
||||||
<Exclude pattern="OSHttpServer.*\.cs"/>
|
|
||||||
<Exclude pattern="OSHttpXmlRpcHandler.*\.cs"/>
|
|
||||||
</Match>
|
|
||||||
</Files>
|
|
||||||
</Project>
|
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Console" path="OpenSim/Framework/Console" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Console" path="OpenSim/Framework/Console" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
@ -233,6 +167,73 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Monitoring" path="OpenSim/Framework/Monitoring" type="Library">
|
||||||
|
<Configuration name="Debug">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
|
||||||
|
<ReferencePath>../../../bin/</ReferencePath>
|
||||||
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
|
<Reference name="log4net" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverse" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenSim.Framework"/>
|
||||||
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
|
|
||||||
|
<Files>
|
||||||
|
<Match pattern="*.cs" recurse="true"/>
|
||||||
|
</Files>
|
||||||
|
</Project>
|
||||||
|
|
||||||
|
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer" path="OpenSim/Framework/Servers/HttpServer" type="Library">
|
||||||
|
<Configuration name="Debug">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
|
||||||
|
<ReferencePath>../../../../bin/</ReferencePath>
|
||||||
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
|
<Reference name="System.Xml"/>
|
||||||
|
<Reference name="System.Web"/>
|
||||||
|
<Reference name="OpenSim.Framework"/>
|
||||||
|
<Reference name="OpenSim.Framework.Monitoring"/>
|
||||||
|
<Reference name="OpenMetaverse.StructuredData" path="../../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
|
||||||
|
<Reference name="XMLRPC" path="../../../../bin/"/>
|
||||||
|
<Reference name="log4net" path="../../../../bin/"/>
|
||||||
|
<Reference name="HttpServer_OpenSim" path="../../../../bin/"/>
|
||||||
|
|
||||||
|
<Files>
|
||||||
|
<Match pattern="*.cs" recurse="true">
|
||||||
|
<Exclude pattern="Tests"/>
|
||||||
|
|
||||||
|
<!-- on temporary suspension -->
|
||||||
|
<Exclude pattern="OSHttpHandler\.cs"/>
|
||||||
|
<Exclude pattern="OSHttpHttpHandler\.cs"/>
|
||||||
|
<Exclude pattern="OSHttpRequestPump\.cs"/>
|
||||||
|
<Exclude pattern="OSHttpRequestQueue\.cs"/>
|
||||||
|
<Exclude pattern="OSHttpServer.*\.cs"/>
|
||||||
|
<Exclude pattern="OSHttpXmlRpcHandler.*\.cs"/>
|
||||||
|
</Match>
|
||||||
|
</Files>
|
||||||
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Serialization" path="OpenSim/Framework/Serialization" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Serialization" path="OpenSim/Framework/Serialization" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
|
Loading…
Reference in New Issue