From 5d534127663899cd5592c865b1d00855fce25854 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Sun, 29 Jun 2014 16:40:11 +0300 Subject: [PATCH] Write UDP statistics to the log, not just the console (e.g., "show queues") --- OpenSim/Framework/Monitoring/StatsManager.cs | 53 ++++++-------- .../Agent/UDP/Linden/LindenUDPInfoModule.cs | 69 ++++++++++--------- 2 files changed, 59 insertions(+), 63 deletions(-) diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 0bac2470f5..5c8d934e6d 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -30,6 +30,8 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Reflection; +using log4net; using OpenSim.Framework; using OpenMetaverse.StructuredData; @@ -41,6 +43,8 @@ namespace OpenSim.Framework.Monitoring /// public static class StatsManager { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // Subcommand used to list other stats. public const string AllSubCommand = "all"; @@ -98,6 +102,7 @@ namespace OpenSim.Framework.Monitoring public static void HandleShowStatsCommand(string module, string[] cmd) { ICommandConsole con = MainConsole.Instance; + StringBuilder report = new StringBuilder(); if (cmd.Length > 2) { @@ -111,7 +116,8 @@ namespace OpenSim.Framework.Monitoring if (categoryName == AllSubCommand) { - OutputAllStatsToConsole(con); + foreach (string report2 in GetAllStatsReports()) + report.AppendLine(report2); } else if (categoryName == ListSubCommand) { @@ -130,7 +136,8 @@ namespace OpenSim.Framework.Monitoring { if (String.IsNullOrEmpty(containerName)) { - OutputCategoryStatsToConsole(con, category); + foreach (string report2 in GetCategoryStatsReports(category)) + report.AppendLine(report2); } else { @@ -139,14 +146,15 @@ namespace OpenSim.Framework.Monitoring { if (String.IsNullOrEmpty(statName)) { - OutputContainerStatsToConsole(con, container); + foreach (string report2 in GetContainerStatsReports(container)) + report.AppendLine(report2); } else { Stat stat; if (container.TryGetValue(statName, out stat)) { - OutputStatToConsole(con, stat); + report.AppendLine(stat.ToConsoleString()); } else { @@ -168,10 +176,18 @@ namespace OpenSim.Framework.Monitoring { // Legacy if (SimExtraStats != null) - con.Output(SimExtraStats.Report()); + { + report.Append(SimExtraStats.Report()); + } 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 GetAllStatsReports() @@ -184,12 +200,6 @@ namespace OpenSim.Framework.Monitoring return reports; } - private static void OutputAllStatsToConsole(ICommandConsole con) - { - foreach (string report in GetAllStatsReports()) - con.Output(report); - } - private static List GetCategoryStatsReports( SortedDictionary> category) { @@ -201,13 +211,6 @@ namespace OpenSim.Framework.Monitoring return reports; } - private static void OutputCategoryStatsToConsole( - ICommandConsole con, SortedDictionary> category) - { - foreach (string report in GetCategoryStatsReports(category)) - con.Output(report); - } - private static List GetContainerStatsReports(SortedDictionary container) { List reports = new List(); @@ -218,18 +221,6 @@ namespace OpenSim.Framework.Monitoring return reports; } - private static void OutputContainerStatsToConsole( - ICommandConsole con, SortedDictionary 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: // { categoryName: { // containerName: { diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 44d4e93466..2637b00e1e 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs @@ -87,8 +87,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden "show pqueues [full]", "Show priority queue data for each client", "Without the 'full' option, only root agents are shown." - + " With the 'full' option child agents are also shown.", - (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd))); + + " With the 'full' option child agents are also shown.", + (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetPQueuesReport(cmd))); scene.AddCommand( "Comms", this, "show queues", @@ -103,27 +103,27 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden + "Pkts Resent - Number of packets resent to the client.\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", - (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd))); + (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetQueuesReport(cmd))); scene.AddCommand( "Comms", this, "show image queues", "show image queues ", "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( "Comms", this, "clear image queues", "clear image queues ", "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( "Comms", this, "show throttles", "show throttles [full]", "Show throttle settings for each client and for the server overall", "Without the 'full' option, only root agents are shown." - + " With the 'full' option child agents are also shown.", - (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd))); + + " With the 'full' option child agents are also shown.", + (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetThrottlesReport(cmd))); scene.AddCommand( "Comms", this, "emergency-monitoring", @@ -138,7 +138,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden "Show client request stats", "Without the 'first_name last_name' option, all clients are 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; string name = client.Name; - if (pname != "" && name != pname) + if (pname != "" && name.ToLower() != pname.ToLower()) return; string regionName = scene.RegionInfo.RegionName; @@ -440,7 +440,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden return; string name = client.Name; - if (pname != "" && name != pname) + if (pname != "" && name.ToLower() != pname.ToLower()) return; string regionName = scene.RegionInfo.RegionName; @@ -535,7 +535,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden return; string name = client.Name; - if (pname != "" && name != pname) + if (pname != "" && name.ToLower() != pname.ToLower()) return; string regionName = scene.RegionInfo.RegionName; @@ -604,12 +604,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden /// protected string HandleClientStatsReport(string[] showParams) { - // NOTE: This writes to m_log on purpose. We want to store this information - // in case we need to analyze it later. - // + StringBuilder report = new StringBuilder(); + 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) { scene.ForEachClient( @@ -629,7 +629,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden else 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, childAgentStatus, (DateTime.Now - cinfo.StartedTime).Minutes, @@ -637,11 +640,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden string.Format( "{0} ({1:0.00}%)", llClient.TotalAgentUpdates, - (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100)); + ((float)agentUpdates) / llClient.TotalAgentUpdates * 100)); } }); } - return string.Empty; + + return report.ToString(); } string fname = "", lname = ""; @@ -660,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden { LLClientView llClient = client as LLClientView; - if (llClient.Name == fname + " " + lname) + if (llClient.Name.ToLower() == (fname + " " + lname).ToLower()) { ClientInfo cinfo = llClient.GetClientInfo(); @@ -669,41 +673,42 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden aCircuit = new AgentCircuitData(); 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(); avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); - m_log.InfoFormat("[INFO]:"); - m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName, + report.AppendLine(); + 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); Dictionary sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) .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) .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) .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 sortedDict, int sum) + private void PrintRequests(StringBuilder report, string type, Dictionary sortedDict, int sum) { - m_log.InfoFormat("[INFO]:"); - m_log.InfoFormat("[INFO]: {0,25}", type); + report.AppendLine(); + report.AppendFormat("{0,25}\n", type); foreach (KeyValuePair kvp in sortedDict.Take(12)) - m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); - m_log.InfoFormat("[INFO]: {0,25}", "..."); - m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum); + report.AppendFormat("{0,25} {1,-6}\n", kvp.Key, kvp.Value); + report.AppendFormat("{0,25}\n", "..."); + report.AppendFormat("{0,25} {1,-6}\n", "Total", sum); } } }