Write UDP statistics to the log, not just the console (e.g., "show queues")
parent
0d70033a5d
commit
5d53412766
|
@ -30,6 +30,8 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
@ -41,6 +43,8 @@ namespace OpenSim.Framework.Monitoring
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class StatsManager
|
public static class StatsManager
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
// Subcommand used to list other stats.
|
// Subcommand used to list other stats.
|
||||||
public const string AllSubCommand = "all";
|
public const string AllSubCommand = "all";
|
||||||
|
|
||||||
|
@ -98,6 +102,7 @@ namespace OpenSim.Framework.Monitoring
|
||||||
public static void HandleShowStatsCommand(string module, string[] cmd)
|
public static void HandleShowStatsCommand(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
ICommandConsole con = MainConsole.Instance;
|
ICommandConsole con = MainConsole.Instance;
|
||||||
|
StringBuilder report = new StringBuilder();
|
||||||
|
|
||||||
if (cmd.Length > 2)
|
if (cmd.Length > 2)
|
||||||
{
|
{
|
||||||
|
@ -111,7 +116,8 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
if (categoryName == AllSubCommand)
|
if (categoryName == AllSubCommand)
|
||||||
{
|
{
|
||||||
OutputAllStatsToConsole(con);
|
foreach (string report2 in GetAllStatsReports())
|
||||||
|
report.AppendLine(report2);
|
||||||
}
|
}
|
||||||
else if (categoryName == ListSubCommand)
|
else if (categoryName == ListSubCommand)
|
||||||
{
|
{
|
||||||
|
@ -130,7 +136,8 @@ namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(containerName))
|
if (String.IsNullOrEmpty(containerName))
|
||||||
{
|
{
|
||||||
OutputCategoryStatsToConsole(con, category);
|
foreach (string report2 in GetCategoryStatsReports(category))
|
||||||
|
report.AppendLine(report2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -139,14 +146,15 @@ namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(statName))
|
if (String.IsNullOrEmpty(statName))
|
||||||
{
|
{
|
||||||
OutputContainerStatsToConsole(con, container);
|
foreach (string report2 in GetContainerStatsReports(container))
|
||||||
|
report.AppendLine(report2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stat stat;
|
Stat stat;
|
||||||
if (container.TryGetValue(statName, out stat))
|
if (container.TryGetValue(statName, out stat))
|
||||||
{
|
{
|
||||||
OutputStatToConsole(con, stat);
|
report.AppendLine(stat.ToConsoleString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -168,10 +176,18 @@ namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
// Legacy
|
// Legacy
|
||||||
if (SimExtraStats != null)
|
if (SimExtraStats != null)
|
||||||
con.Output(SimExtraStats.Report());
|
{
|
||||||
|
report.Append(SimExtraStats.Report());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
OutputAllStatsToConsole(con);
|
{
|
||||||
|
foreach (string report2 in GetAllStatsReports())
|
||||||
|
report.AppendLine(report2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (report.Length > 0)
|
||||||
|
m_log.Debug(string.Join(" ", cmd) + "\n" + report.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetAllStatsReports()
|
public static List<string> GetAllStatsReports()
|
||||||
|
@ -184,12 +200,6 @@ namespace OpenSim.Framework.Monitoring
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OutputAllStatsToConsole(ICommandConsole con)
|
|
||||||
{
|
|
||||||
foreach (string report in GetAllStatsReports())
|
|
||||||
con.Output(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<string> GetCategoryStatsReports(
|
private static List<string> GetCategoryStatsReports(
|
||||||
SortedDictionary<string, SortedDictionary<string, Stat>> category)
|
SortedDictionary<string, SortedDictionary<string, Stat>> category)
|
||||||
{
|
{
|
||||||
|
@ -201,13 +211,6 @@ namespace OpenSim.Framework.Monitoring
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OutputCategoryStatsToConsole(
|
|
||||||
ICommandConsole con, SortedDictionary<string, SortedDictionary<string, Stat>> category)
|
|
||||||
{
|
|
||||||
foreach (string report in GetCategoryStatsReports(category))
|
|
||||||
con.Output(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<string> GetContainerStatsReports(SortedDictionary<string, Stat> container)
|
private static List<string> GetContainerStatsReports(SortedDictionary<string, Stat> container)
|
||||||
{
|
{
|
||||||
List<string> reports = new List<string>();
|
List<string> reports = new List<string>();
|
||||||
|
@ -218,18 +221,6 @@ namespace OpenSim.Framework.Monitoring
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OutputContainerStatsToConsole(
|
|
||||||
ICommandConsole con, SortedDictionary<string, Stat> container)
|
|
||||||
{
|
|
||||||
foreach (string report in GetContainerStatsReports(container))
|
|
||||||
con.Output(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OutputStatToConsole(ICommandConsole con, Stat stat)
|
|
||||||
{
|
|
||||||
con.Output(stat.ToConsoleString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates an OSDMap of the format:
|
// Creates an OSDMap of the format:
|
||||||
// { categoryName: {
|
// { categoryName: {
|
||||||
// containerName: {
|
// containerName: {
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
"Show priority queue data for each client",
|
"Show priority queue data for each client",
|
||||||
"Without the 'full' option, only root agents are shown."
|
"Without the 'full' option, only root agents are shown."
|
||||||
+ " With the 'full' option child agents are also shown.",
|
+ " With the 'full' option child agents are also shown.",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetPQueuesReport(cmd)));
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
"Comms", this, "show queues",
|
"Comms", this, "show queues",
|
||||||
|
@ -103,19 +103,19 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
+ "Pkts Resent - Number of packets resent to the client.\n"
|
+ "Pkts Resent - Number of packets resent to the client.\n"
|
||||||
+ "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
|
+ "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
|
||||||
+ "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
|
+ "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetQueuesReport(cmd)));
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
"Comms", this, "show image queues",
|
"Comms", this, "show image queues",
|
||||||
"show image queues <first-name> <last-name>",
|
"show image queues <first-name> <last-name>",
|
||||||
"Show the image queues (textures downloaded via UDP) for a particular client.",
|
"Show the image queues (textures downloaded via UDP) for a particular client.",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetImageQueuesReport(cmd)));
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
"Comms", this, "clear image queues",
|
"Comms", this, "clear image queues",
|
||||||
"clear image queues <first-name> <last-name>",
|
"clear image queues <first-name> <last-name>",
|
||||||
"Clear the image queues (textures downloaded via UDP) for a particular client.",
|
"Clear the image queues (textures downloaded via UDP) for a particular client.",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + HandleImageQueuesClear(cmd)));
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
"Comms", this, "show throttles",
|
"Comms", this, "show throttles",
|
||||||
|
@ -123,7 +123,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
"Show throttle settings for each client and for the server overall",
|
"Show throttle settings for each client and for the server overall",
|
||||||
"Without the 'full' option, only root agents are shown."
|
"Without the 'full' option, only root agents are shown."
|
||||||
+ " With the 'full' option child agents are also shown.",
|
+ " With the 'full' option child agents are also shown.",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetThrottlesReport(cmd)));
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
"Comms", this, "emergency-monitoring",
|
"Comms", this, "emergency-monitoring",
|
||||||
|
@ -138,7 +138,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
"Show client request stats",
|
"Show client request stats",
|
||||||
"Without the 'first_name last_name' option, all clients are shown."
|
"Without the 'first_name last_name' option, all clients are shown."
|
||||||
+ " With the 'first_name last_name' option only a specific client is shown.",
|
+ " With the 'first_name last_name' option only a specific client is shown.",
|
||||||
(mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd)));
|
(mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + HandleClientStatsReport(cmd)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = client.Name;
|
string name = client.Name;
|
||||||
if (pname != "" && name != pname)
|
if (pname != "" && name.ToLower() != pname.ToLower())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string regionName = scene.RegionInfo.RegionName;
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
@ -440,7 +440,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = client.Name;
|
string name = client.Name;
|
||||||
if (pname != "" && name != pname)
|
if (pname != "" && name.ToLower() != pname.ToLower())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string regionName = scene.RegionInfo.RegionName;
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
@ -535,7 +535,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = client.Name;
|
string name = client.Name;
|
||||||
if (pname != "" && name != pname)
|
if (pname != "" && name.ToLower() != pname.ToLower())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string regionName = scene.RegionInfo.RegionName;
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
@ -604,12 +604,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected string HandleClientStatsReport(string[] showParams)
|
protected string HandleClientStatsReport(string[] showParams)
|
||||||
{
|
{
|
||||||
// NOTE: This writes to m_log on purpose. We want to store this information
|
StringBuilder report = new StringBuilder();
|
||||||
// in case we need to analyze it later.
|
|
||||||
//
|
|
||||||
if (showParams.Length <= 4)
|
if (showParams.Length <= 4)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
|
report.AppendFormat("{0,-30} {1,-30} {2,-6} {3,-11} {4,-11} {5,-16}\n", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
|
||||||
|
|
||||||
foreach (Scene scene in m_scenes.Values)
|
foreach (Scene scene in m_scenes.Values)
|
||||||
{
|
{
|
||||||
scene.ForEachClient(
|
scene.ForEachClient(
|
||||||
|
@ -629,7 +629,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
else
|
else
|
||||||
childAgentStatus = "Off!";
|
childAgentStatus = "Off!";
|
||||||
|
|
||||||
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
|
int agentUpdates = 0;
|
||||||
|
cinfo.SyncRequests.TryGetValue("AgentUpdate", out agentUpdates);
|
||||||
|
|
||||||
|
report.AppendFormat("{0,-30} {1,-30} {2,-6} {3,-11} {4,-11} {5,-16}\n",
|
||||||
scene.RegionInfo.RegionName, llClient.Name,
|
scene.RegionInfo.RegionName, llClient.Name,
|
||||||
childAgentStatus,
|
childAgentStatus,
|
||||||
(DateTime.Now - cinfo.StartedTime).Minutes,
|
(DateTime.Now - cinfo.StartedTime).Minutes,
|
||||||
|
@ -637,11 +640,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
string.Format(
|
string.Format(
|
||||||
"{0} ({1:0.00}%)",
|
"{0} ({1:0.00}%)",
|
||||||
llClient.TotalAgentUpdates,
|
llClient.TotalAgentUpdates,
|
||||||
(float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100));
|
((float)agentUpdates) / llClient.TotalAgentUpdates * 100));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return string.Empty;
|
|
||||||
|
return report.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
string fname = "", lname = "";
|
string fname = "", lname = "";
|
||||||
|
@ -660,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
{
|
{
|
||||||
LLClientView llClient = client as LLClientView;
|
LLClientView llClient = client as LLClientView;
|
||||||
|
|
||||||
if (llClient.Name == fname + " " + lname)
|
if (llClient.Name.ToLower() == (fname + " " + lname).ToLower())
|
||||||
{
|
{
|
||||||
|
|
||||||
ClientInfo cinfo = llClient.GetClientInfo();
|
ClientInfo cinfo = llClient.GetClientInfo();
|
||||||
|
@ -669,41 +673,42 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
aCircuit = new AgentCircuitData();
|
aCircuit = new AgentCircuitData();
|
||||||
|
|
||||||
if (!llClient.SceneAgent.IsChildAgent)
|
if (!llClient.SceneAgent.IsChildAgent)
|
||||||
m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
|
report.AppendFormat("{0} # {1} # {2}\n", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
|
||||||
|
|
||||||
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
|
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
|
||||||
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
|
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
|
||||||
|
|
||||||
m_log.InfoFormat("[INFO]:");
|
report.AppendLine();
|
||||||
m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName,
|
report.AppendFormat("{0} # {1} # Time: {2}min # Avg Reqs/min: {3}\n", scene.RegionInfo.RegionName,
|
||||||
(llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
|
(llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
|
||||||
|
|
||||||
Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
|
Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
|
||||||
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
|
PrintRequests(report, "TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
|
||||||
|
|
||||||
sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
|
sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
|
||||||
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
|
PrintRequests(report, "TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
|
||||||
|
|
||||||
sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
|
sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
|
||||||
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
|
PrintRequests(report, "TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return string.Empty;
|
|
||||||
|
return report.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum)
|
private void PrintRequests(StringBuilder report, string type, Dictionary<string, int> sortedDict, int sum)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[INFO]:");
|
report.AppendLine();
|
||||||
m_log.InfoFormat("[INFO]: {0,25}", type);
|
report.AppendFormat("{0,25}\n", type);
|
||||||
foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
|
foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
|
||||||
m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value);
|
report.AppendFormat("{0,25} {1,-6}\n", kvp.Key, kvp.Value);
|
||||||
m_log.InfoFormat("[INFO]: {0,25}", "...");
|
report.AppendFormat("{0,25}\n", "...");
|
||||||
m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
|
report.AppendFormat("{0,25} {1,-6}\n", "Total", sum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue