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
Justin Clark-Casey (justincc) 2012-10-11 23:28:53 +01:00
parent 0afc43eed7
commit 6c3eceb197
6 changed files with 330 additions and 167 deletions

View File

@ -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))
{
foreach (KeyValuePair<string, Dictionary<string, Stat>> kvp in sceneStats)
{ {
sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value); 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);
}
}
} }
} }

View File

@ -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)
{ {
} }
} }

View File

@ -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);
} }
} }

View File

@ -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,51 +232,51 @@ namespace OpenSim
plugin.PostInitialise(); plugin.PostInitialise();
} }
AddPluginCommands();
}
protected virtual void AddPluginCommands()
{
// If console exists add plugin commands.
if (m_console != null) if (m_console != null)
{ {
List<string> topics = GetHelpTopics(); StatsManager.RegisterConsoleCommands(m_console);
AddPluginCommands(m_console);
}
}
foreach (string topic in topics) protected virtual void AddPluginCommands(CommandConsole console)
{
List<string> topics = GetHelpTopics();
foreach (string topic in topics)
{
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
ICommander commander = null;
Scene s = SceneManager.CurrentOrFirstScene;
if (s != null && s.GetCommanders() != null)
{ {
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); if (s.GetCommanders().ContainsKey(topic))
commander = s.GetCommanders()[topic];
}
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go if (commander == null)
// away at some point. continue;
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
ICommander commander = null; foreach (string command in commander.Commands.Keys)
{
Scene s = SceneManager.CurrentOrFirstScene; console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command,
if (s != null && s.GetCommanders() != null) topic + " " + commander.Commands[command].ShortHelp(),
{ String.Empty, HandleCommanderCommand);
if (s.GetCommanders().ContainsKey(topic))
commander = s.GetCommanders()[topic];
}
if (commander == null)
continue;
foreach (string command in commander.Commands.Keys)
{
m_console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command,
topic + " " + commander.Commands[command].ShortHelp(),
String.Empty, HandleCommanderCommand);
}
} }
} }
} }

View File

@ -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,16 +233,21 @@ 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
{ {
@ -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;

View File

@ -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>