aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs53
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs69
2 files changed, 59 insertions, 63 deletions
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 0bac247..5c8d934 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -30,6 +30,8 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq; 31using System.Linq;
32using System.Text; 32using System.Text;
33using System.Reflection;
34using log4net;
33 35
34using OpenSim.Framework; 36using OpenSim.Framework;
35using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
@@ -41,6 +43,8 @@ namespace OpenSim.Framework.Monitoring
41 /// </summary> 43 /// </summary>
42 public static class StatsManager 44 public static class StatsManager
43 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
44 // Subcommand used to list other stats. 48 // Subcommand used to list other stats.
45 public const string AllSubCommand = "all"; 49 public const string AllSubCommand = "all";
46 50
@@ -98,6 +102,7 @@ namespace OpenSim.Framework.Monitoring
98 public static void HandleShowStatsCommand(string module, string[] cmd) 102 public static void HandleShowStatsCommand(string module, string[] cmd)
99 { 103 {
100 ICommandConsole con = MainConsole.Instance; 104 ICommandConsole con = MainConsole.Instance;
105 StringBuilder report = new StringBuilder();
101 106
102 if (cmd.Length > 2) 107 if (cmd.Length > 2)
103 { 108 {
@@ -111,7 +116,8 @@ namespace OpenSim.Framework.Monitoring
111 116
112 if (categoryName == AllSubCommand) 117 if (categoryName == AllSubCommand)
113 { 118 {
114 OutputAllStatsToConsole(con); 119 foreach (string report2 in GetAllStatsReports())
120 report.AppendLine(report2);
115 } 121 }
116 else if (categoryName == ListSubCommand) 122 else if (categoryName == ListSubCommand)
117 { 123 {
@@ -130,7 +136,8 @@ namespace OpenSim.Framework.Monitoring
130 { 136 {
131 if (String.IsNullOrEmpty(containerName)) 137 if (String.IsNullOrEmpty(containerName))
132 { 138 {
133 OutputCategoryStatsToConsole(con, category); 139 foreach (string report2 in GetCategoryStatsReports(category))
140 report.AppendLine(report2);
134 } 141 }
135 else 142 else
136 { 143 {
@@ -139,14 +146,15 @@ namespace OpenSim.Framework.Monitoring
139 { 146 {
140 if (String.IsNullOrEmpty(statName)) 147 if (String.IsNullOrEmpty(statName))
141 { 148 {
142 OutputContainerStatsToConsole(con, container); 149 foreach (string report2 in GetContainerStatsReports(container))
150 report.AppendLine(report2);
143 } 151 }
144 else 152 else
145 { 153 {
146 Stat stat; 154 Stat stat;
147 if (container.TryGetValue(statName, out stat)) 155 if (container.TryGetValue(statName, out stat))
148 { 156 {
149 OutputStatToConsole(con, stat); 157 report.AppendLine(stat.ToConsoleString());
150 } 158 }
151 else 159 else
152 { 160 {
@@ -168,10 +176,18 @@ namespace OpenSim.Framework.Monitoring
168 { 176 {
169 // Legacy 177 // Legacy
170 if (SimExtraStats != null) 178 if (SimExtraStats != null)
171 con.Output(SimExtraStats.Report()); 179 {
180 report.Append(SimExtraStats.Report());
181 }
172 else 182 else
173 OutputAllStatsToConsole(con); 183 {
184 foreach (string report2 in GetAllStatsReports())
185 report.AppendLine(report2);
186 }
174 } 187 }
188
189 if (report.Length > 0)
190 m_log.Debug(string.Join(" ", cmd) + "\n" + report.ToString());
175 } 191 }
176 192
177 public static List<string> GetAllStatsReports() 193 public static List<string> GetAllStatsReports()
@@ -184,12 +200,6 @@ namespace OpenSim.Framework.Monitoring
184 return reports; 200 return reports;
185 } 201 }
186 202
187 private static void OutputAllStatsToConsole(ICommandConsole con)
188 {
189 foreach (string report in GetAllStatsReports())
190 con.Output(report);
191 }
192
193 private static List<string> GetCategoryStatsReports( 203 private static List<string> GetCategoryStatsReports(
194 SortedDictionary<string, SortedDictionary<string, Stat>> category) 204 SortedDictionary<string, SortedDictionary<string, Stat>> category)
195 { 205 {
@@ -201,13 +211,6 @@ namespace OpenSim.Framework.Monitoring
201 return reports; 211 return reports;
202 } 212 }
203 213
204 private static void OutputCategoryStatsToConsole(
205 ICommandConsole con, SortedDictionary<string, SortedDictionary<string, Stat>> category)
206 {
207 foreach (string report in GetCategoryStatsReports(category))
208 con.Output(report);
209 }
210
211 private static List<string> GetContainerStatsReports(SortedDictionary<string, Stat> container) 214 private static List<string> GetContainerStatsReports(SortedDictionary<string, Stat> container)
212 { 215 {
213 List<string> reports = new List<string>(); 216 List<string> reports = new List<string>();
@@ -218,18 +221,6 @@ namespace OpenSim.Framework.Monitoring
218 return reports; 221 return reports;
219 } 222 }
220 223
221 private static void OutputContainerStatsToConsole(
222 ICommandConsole con, SortedDictionary<string, Stat> container)
223 {
224 foreach (string report in GetContainerStatsReports(container))
225 con.Output(report);
226 }
227
228 private static void OutputStatToConsole(ICommandConsole con, Stat stat)
229 {
230 con.Output(stat.ToConsoleString());
231 }
232
233 // Creates an OSDMap of the format: 224 // Creates an OSDMap of the format:
234 // { categoryName: { 225 // { categoryName: {
235 // containerName: { 226 // containerName: {
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index 44d4e93..2637b00 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
87 "show pqueues [full]", 87 "show pqueues [full]",
88 "Show priority queue data for each client", 88 "Show priority queue data for each client",
89 "Without the 'full' option, only root agents are shown." 89 "Without the 'full' option, only root agents are shown."
90 + " With the 'full' option child agents are also shown.", 90 + " With the 'full' option child agents are also shown.",
91 (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd))); 91 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetPQueuesReport(cmd)));
92 92
93 scene.AddCommand( 93 scene.AddCommand(
94 "Comms", this, "show queues", 94 "Comms", this, "show queues",
@@ -103,27 +103,27 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
103 + "Pkts Resent - Number of packets resent to the client.\n" 103 + "Pkts Resent - Number of packets resent to the client.\n"
104 + "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n" 104 + "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
105 + "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n", 105 + "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
106 (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd))); 106 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetQueuesReport(cmd)));
107 107
108 scene.AddCommand( 108 scene.AddCommand(
109 "Comms", this, "show image queues", 109 "Comms", this, "show image queues",
110 "show image queues <first-name> <last-name>", 110 "show image queues <first-name> <last-name>",
111 "Show the image queues (textures downloaded via UDP) for a particular client.", 111 "Show the image queues (textures downloaded via UDP) for a particular client.",
112 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); 112 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetImageQueuesReport(cmd)));
113 113
114 scene.AddCommand( 114 scene.AddCommand(
115 "Comms", this, "clear image queues", 115 "Comms", this, "clear image queues",
116 "clear image queues <first-name> <last-name>", 116 "clear image queues <first-name> <last-name>",
117 "Clear the image queues (textures downloaded via UDP) for a particular client.", 117 "Clear the image queues (textures downloaded via UDP) for a particular client.",
118 (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd))); 118 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + HandleImageQueuesClear(cmd)));
119 119
120 scene.AddCommand( 120 scene.AddCommand(
121 "Comms", this, "show throttles", 121 "Comms", this, "show throttles",
122 "show throttles [full]", 122 "show throttles [full]",
123 "Show throttle settings for each client and for the server overall", 123 "Show throttle settings for each client and for the server overall",
124 "Without the 'full' option, only root agents are shown." 124 "Without the 'full' option, only root agents are shown."
125 + " With the 'full' option child agents are also shown.", 125 + " With the 'full' option child agents are also shown.",
126 (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd))); 126 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + GetThrottlesReport(cmd)));
127 127
128 scene.AddCommand( 128 scene.AddCommand(
129 "Comms", this, "emergency-monitoring", 129 "Comms", this, "emergency-monitoring",
@@ -138,7 +138,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
138 "Show client request stats", 138 "Show client request stats",
139 "Without the 'first_name last_name' option, all clients are shown." 139 "Without the 'first_name last_name' option, all clients are shown."
140 + " With the 'first_name last_name' option only a specific client is shown.", 140 + " With the 'first_name last_name' option only a specific client is shown.",
141 (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd))); 141 (mod, cmd) => m_log.Debug(string.Join(" ", cmd) + "\n" + HandleClientStatsReport(cmd)));
142 142
143 } 143 }
144 144
@@ -279,7 +279,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
279 return; 279 return;
280 280
281 string name = client.Name; 281 string name = client.Name;
282 if (pname != "" && name != pname) 282 if (pname != "" && name.ToLower() != pname.ToLower())
283 return; 283 return;
284 284
285 string regionName = scene.RegionInfo.RegionName; 285 string regionName = scene.RegionInfo.RegionName;
@@ -440,7 +440,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
440 return; 440 return;
441 441
442 string name = client.Name; 442 string name = client.Name;
443 if (pname != "" && name != pname) 443 if (pname != "" && name.ToLower() != pname.ToLower())
444 return; 444 return;
445 445
446 string regionName = scene.RegionInfo.RegionName; 446 string regionName = scene.RegionInfo.RegionName;
@@ -535,7 +535,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
535 return; 535 return;
536 536
537 string name = client.Name; 537 string name = client.Name;
538 if (pname != "" && name != pname) 538 if (pname != "" && name.ToLower() != pname.ToLower())
539 return; 539 return;
540 540
541 string regionName = scene.RegionInfo.RegionName; 541 string regionName = scene.RegionInfo.RegionName;
@@ -604,12 +604,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
604 /// <returns></returns> 604 /// <returns></returns>
605 protected string HandleClientStatsReport(string[] showParams) 605 protected string HandleClientStatsReport(string[] showParams)
606 { 606 {
607 // NOTE: This writes to m_log on purpose. We want to store this information 607 StringBuilder report = new StringBuilder();
608 // in case we need to analyze it later. 608
609 //
610 if (showParams.Length <= 4) 609 if (showParams.Length <= 4)
611 { 610 {
612 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates"); 611 report.AppendFormat("{0,-30} {1,-30} {2,-6} {3,-11} {4,-11} {5,-16}\n", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
612
613 foreach (Scene scene in m_scenes.Values) 613 foreach (Scene scene in m_scenes.Values)
614 { 614 {
615 scene.ForEachClient( 615 scene.ForEachClient(
@@ -629,7 +629,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
629 else 629 else
630 childAgentStatus = "Off!"; 630 childAgentStatus = "Off!";
631 631
632 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", 632 int agentUpdates = 0;
633 cinfo.SyncRequests.TryGetValue("AgentUpdate", out agentUpdates);
634
635 report.AppendFormat("{0,-30} {1,-30} {2,-6} {3,-11} {4,-11} {5,-16}\n",
633 scene.RegionInfo.RegionName, llClient.Name, 636 scene.RegionInfo.RegionName, llClient.Name,
634 childAgentStatus, 637 childAgentStatus,
635 (DateTime.Now - cinfo.StartedTime).Minutes, 638 (DateTime.Now - cinfo.StartedTime).Minutes,
@@ -637,11 +640,12 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
637 string.Format( 640 string.Format(
638 "{0} ({1:0.00}%)", 641 "{0} ({1:0.00}%)",
639 llClient.TotalAgentUpdates, 642 llClient.TotalAgentUpdates,
640 (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100)); 643 ((float)agentUpdates) / llClient.TotalAgentUpdates * 100));
641 } 644 }
642 }); 645 });
643 } 646 }
644 return string.Empty; 647
648 return report.ToString();
645 } 649 }
646 650
647 string fname = "", lname = ""; 651 string fname = "", lname = "";
@@ -660,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
660 { 664 {
661 LLClientView llClient = client as LLClientView; 665 LLClientView llClient = client as LLClientView;
662 666
663 if (llClient.Name == fname + " " + lname) 667 if (llClient.Name.ToLower() == (fname + " " + lname).ToLower())
664 { 668 {
665 669
666 ClientInfo cinfo = llClient.GetClientInfo(); 670 ClientInfo cinfo = llClient.GetClientInfo();
@@ -669,41 +673,42 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
669 aCircuit = new AgentCircuitData(); 673 aCircuit = new AgentCircuitData();
670 674
671 if (!llClient.SceneAgent.IsChildAgent) 675 if (!llClient.SceneAgent.IsChildAgent)
672 m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0); 676 report.AppendFormat("{0} # {1} # {2}\n", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
673 677
674 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); 678 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
675 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); 679 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
676 680
677 m_log.InfoFormat("[INFO]:"); 681 report.AppendLine();
678 m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName, 682 report.AppendFormat("{0} # {1} # Time: {2}min # Avg Reqs/min: {3}\n", scene.RegionInfo.RegionName,
679 (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs); 683 (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
680 684
681 Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) 685 Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
682 .ToDictionary(pair => pair.Key, pair => pair.Value); 686 .ToDictionary(pair => pair.Key, pair => pair.Value);
683 PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum()); 687 PrintRequests(report, "TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
684 688
685 sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry) 689 sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
686 .ToDictionary(pair => pair.Key, pair => pair.Value); 690 .ToDictionary(pair => pair.Key, pair => pair.Value);
687 PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum()); 691 PrintRequests(report, "TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
688 692
689 sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry) 693 sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
690 .ToDictionary(pair => pair.Key, pair => pair.Value); 694 .ToDictionary(pair => pair.Key, pair => pair.Value);
691 PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum()); 695 PrintRequests(report, "TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
692 } 696 }
693 } 697 }
694 }); 698 });
695 } 699 }
696 return string.Empty; 700
701 return report.ToString();
697 } 702 }
698 703
699 private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum) 704 private void PrintRequests(StringBuilder report, string type, Dictionary<string, int> sortedDict, int sum)
700 { 705 {
701 m_log.InfoFormat("[INFO]:"); 706 report.AppendLine();
702 m_log.InfoFormat("[INFO]: {0,25}", type); 707 report.AppendFormat("{0,25}\n", type);
703 foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12)) 708 foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
704 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); 709 report.AppendFormat("{0,25} {1,-6}\n", kvp.Key, kvp.Value);
705 m_log.InfoFormat("[INFO]: {0,25}", "..."); 710 report.AppendFormat("{0,25}\n", "...");
706 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum); 711 report.AppendFormat("{0,25} {1,-6}\n", "Total", sum);
707 } 712 }
708 } 713 }
709} 714}