OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
LindenUDPInfoModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Linq;
31 using System.Reflection;
32 using System.Text;
33 using log4net;
34 using Mono.Addins;
35 using Nini.Config;
36 using OpenMetaverse;
37 using OpenSim.Framework;
38 using OpenSim.Framework.Console;
39 using OpenSim.Framework.Monitoring;
40 using OpenSim.Region.ClientStack.LindenUDP;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Region.Framework.Scenes;
43 
44 namespace OpenSim.Region.OptionalModules.UDP.Linden
45 {
52  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")]
54  {
55  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 
57  protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
58 
59  public string Name { get { return "Linden UDP Module"; } }
60 
61  public Type ReplaceableInterface { get { return null; } }
62 
63  public void Initialise(IConfigSource source)
64  {
65 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: INITIALIZED MODULE");
66  }
67 
68  public void PostInitialise()
69  {
70 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: POST INITIALIZED MODULE");
71  }
72 
73  public void Close()
74  {
75 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: CLOSED MODULE");
76  }
77 
78  public void AddRegion(Scene scene)
79  {
80 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
81 
82  lock (m_scenes)
83  m_scenes[scene.RegionInfo.RegionID] = scene;
84 
85  scene.AddCommand(
86  "Comms", this, "show pqueues",
87  "show pqueues [full]",
88  "Show priority queue data for each client",
89  "Without the 'full' option, only root agents are shown."
90  + " With the 'full' option child agents are also shown.",
91  (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
92 
93  scene.AddCommand(
94  "Comms", this, "show queues",
95  "show queues [full]",
96  "Show queue data for each client",
97  "Without the 'full' option, only root agents are shown.\n"
98  + "With the 'full' option child agents are also shown.\n\n"
99  + "Type - Rt is a root (avatar) client whilst cd is a child (neighbour interacting) client.\n"
100  + "Since Last In - Time in milliseconds since last packet received.\n"
101  + "Pkts In - Number of packets processed from the client.\n"
102  + "Pkts Out - Number of packets sent 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"
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)));
107 
108  scene.AddCommand(
109  "Comms", this, "show image queues",
110  "show image queues <first-name> <last-name>",
111  "Show the image queues (textures downloaded via UDP) for a particular client.",
112  (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
113 
114  scene.AddCommand(
115  "Comms", this, "clear image queues",
116  "clear image queues <first-name> <last-name>",
117  "Clear the image queues (textures downloaded via UDP) for a particular client.",
118  (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
119 
120  scene.AddCommand(
121  "Comms", this, "show throttles",
122  "show throttles [full]",
123  "Show throttle settings for each client and for the server overall",
124  "Without the 'full' option, only root agents are shown."
125  + " With the 'full' option child agents are also shown.",
126  (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
127 
128  scene.AddCommand(
129  "Comms", this, "emergency-monitoring",
130  "emergency-monitoring",
131  "Go on/off emergency monitoring mode",
132  "Go on/off emergency monitoring mode",
133  HandleEmergencyMonitoring);
134 
135  scene.AddCommand(
136  "Comms", this, "show client stats",
137  "show client stats [first_name last_name]",
138  "Show client request stats",
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.",
141  (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd)));
142 
143  }
144 
145  public void RemoveRegion(Scene scene)
146  {
147 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
148 
149  lock (m_scenes)
150  m_scenes.Remove(scene.RegionInfo.RegionID);
151  }
152 
153  public void RegionLoaded(Scene scene)
154  {
155 // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
156  }
157 
158  protected string HandleImageQueuesClear(string[] cmd)
159  {
160  if (cmd.Length != 5)
161  return "Usage: image queues clear <first-name> <last-name>";
162 
163  string firstName = cmd[3];
164  string lastName = cmd[4];
165 
166  List<ScenePresence> foundAgents = new List<ScenePresence>();
167 
168  lock (m_scenes)
169  {
170  foreach (Scene scene in m_scenes.Values)
171  {
172  ScenePresence sp = scene.GetScenePresence(firstName, lastName);
173  if (sp != null)
174  foundAgents.Add(sp);
175  }
176  }
177 
178  if (foundAgents.Count == 0)
179  return string.Format("No agents found for {0} {1}", firstName, lastName);
180 
181  StringBuilder report = new StringBuilder();
182 
183  foreach (ScenePresence agent in foundAgents)
184  {
185  LLClientView client = agent.ControllingClient as LLClientView;
186 
187  if (client == null)
188  return "This command is only supported for LLClientView";
189 
190  int requestsDeleted = client.ImageManager.ClearImageQueue();
191 
192  report.AppendFormat(
193  "In region {0} ({1} agent) cleared {2} requests\n",
194  agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root", requestsDeleted);
195  }
196 
197  return report.ToString();
198  }
199 
200  protected void HandleEmergencyMonitoring(string module, string[] cmd)
201  {
202  bool mode = true;
203  if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on"))
204  {
205  mode = true;
206  MainConsole.Instance.Output("Emergency Monitoring ON");
207  }
208  else
209  {
210  mode = false;
211  MainConsole.Instance.Output("Emergency Monitoring OFF");
212  }
213 
214  foreach (Scene s in m_scenes.Values)
215  s.EmergencyMonitoring = mode;
216  }
217 
218  protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
219  {
220  return string.Format(
221  "{0,-" + maxLength + "}{1,-" + columnPadding + "}",
222  entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
223  "");
224  }
225 
231  protected string GetPQueuesReport(string[] showParams)
232  {
233  bool showChildren = false;
234  string pname = "";
235 
236  if (showParams.Length > 2 && showParams[2] == "full")
237  showChildren = true;
238  else if (showParams.Length > 3)
239  pname = showParams[2] + " " + showParams[3];
240 
241  StringBuilder report = new StringBuilder();
242 
243  int columnPadding = 2;
244  int maxNameLength = 18;
245  int maxRegionNameLength = 14;
246  int maxTypeLength = 4;
247 // int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
248 
249  report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
250  report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
251  report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
252 
253  report.AppendFormat(
254  "{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7} {10,7} {11,7}\n",
255  "Pri 0",
256  "Pri 1",
257  "Pri 2",
258  "Pri 3",
259  "Pri 4",
260  "Pri 5",
261  "Pri 6",
262  "Pri 7",
263  "Pri 8",
264  "Pri 9",
265  "Pri 10",
266  "Pri 11");
267 
268  lock (m_scenes)
269  {
270  foreach (Scene scene in m_scenes.Values)
271  {
272  scene.ForEachClient(
273  delegate(IClientAPI client)
274  {
275  if (client is LLClientView)
276  {
277  bool isChild = client.SceneAgent.IsChildAgent;
278  if (isChild && !showChildren)
279  return;
280 
281  string name = client.Name;
282  if (pname != "" && name != pname)
283  return;
284 
285  string regionName = scene.RegionInfo.RegionName;
286 
287  report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
288  report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
289  report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
290  report.AppendLine(((LLClientView)client).EntityUpdateQueue.ToString());
291  }
292  });
293  }
294  }
295 
296  return report.ToString();
297  }
298 
304  private string GetImageQueuesReport(string[] showParams)
305  {
306  if (showParams.Length < 5 || showParams.Length > 6)
307  return "Usage: show image queues <first-name> <last-name> [full]";
308 
309  string firstName = showParams[3];
310  string lastName = showParams[4];
311 
312  bool showChildAgents = showParams.Length == 6;
313 
314  List<ScenePresence> foundAgents = new List<ScenePresence>();
315 
316  lock (m_scenes)
317  {
318  foreach (Scene scene in m_scenes.Values)
319  {
320  ScenePresence sp = scene.GetScenePresence(firstName, lastName);
321  if (sp != null && (showChildAgents || !sp.IsChildAgent))
322  foundAgents.Add(sp);
323  }
324  }
325 
326  if (foundAgents.Count == 0)
327  return string.Format("No agents found for {0} {1}", firstName, lastName);
328 
329  StringBuilder report = new StringBuilder();
330 
331  foreach (ScenePresence agent in foundAgents)
332  {
333  LLClientView client = agent.ControllingClient as LLClientView;
334 
335  if (client == null)
336  return "This command is only supported for LLClientView";
337 
338  J2KImage[] images = client.ImageManager.GetImages();
339 
340  report.AppendFormat(
341  "In region {0} ({1} agent)\n",
342  agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root");
343  report.AppendFormat("Images in queue: {0}\n", images.Length);
344 
345  if (images.Length > 0)
346  {
347  report.AppendFormat(
348  "{0,-36} {1,-8} {2,-10} {3,-9} {4,-9} {5,-7}\n",
349  "Texture ID",
350  "Last Seq",
351  "Priority",
352  "Start Pkt",
353  "Has Asset",
354  "Decoded");
355 
356  foreach (J2KImage image in images)
357  report.AppendFormat(
358  "{0,36} {1,8} {2,10} {3,10} {4,9} {5,7}\n",
359  image.TextureID, image.LastSequence, image.Priority, image.StartPacket, image.HasAsset, image.IsDecoded);
360  }
361  }
362 
363  return report.ToString();
364  }
365 
371  protected string GetQueuesReport(string[] showParams)
372  {
373  bool showChildren = false;
374  string pname = "";
375 
376  if (showParams.Length > 2 && showParams[2] == "full")
377  showChildren = true;
378  else if (showParams.Length > 3)
379  pname = showParams[2] + " " + showParams[3];
380 
381  StringBuilder report = new StringBuilder();
382 
383  int columnPadding = 2;
384  int maxNameLength = 18;
385  int maxRegionNameLength = 14;
386  int maxTypeLength = 4;
387 
388  int totalInfoFieldsLength
389  = maxNameLength + columnPadding
390  + maxRegionNameLength + columnPadding
391  + maxTypeLength + columnPadding;
392 
393  report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
394  report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
395  report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
396 
397  report.AppendFormat(
398  "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n",
399  "Since",
400  "Pkts",
401  "Pkts",
402  "Pkts",
403  "Bytes",
404  "Q Pkts",
405  "Q Pkts",
406  "Q Pkts",
407  "Q Pkts",
408  "Q Pkts",
409  "Q Pkts",
410  "Q Pkts");
411 
412  report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
413  report.AppendFormat(
414  "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n",
415  "Last In",
416  "In",
417  "Out",
418  "Resent",
419  "Unacked",
420  "Resend",
421  "Land",
422  "Wind",
423  "Cloud",
424  "Task",
425  "Texture",
426  "Asset");
427 
428  lock (m_scenes)
429  {
430  foreach (Scene scene in m_scenes.Values)
431  {
432  scene.ForEachClient(
433  delegate(IClientAPI client)
434  {
435  if (client is IStatsCollector)
436  {
437 
438  bool isChild = client.SceneAgent.IsChildAgent;
439  if (isChild && !showChildren)
440  return;
441 
442  string name = client.Name;
443  if (pname != "" && name != pname)
444  return;
445 
446  string regionName = scene.RegionInfo.RegionName;
447 
448  report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
449  report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
450  report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
451 
452  IStatsCollector stats = (IStatsCollector)client;
453  report.AppendLine(stats.Report());
454  }
455  });
456  }
457  }
458 
459  return report.ToString();
460  }
461 
467  protected string GetThrottlesReport(string[] showParams)
468  {
469  bool showChildren = false;
470  string pname = "";
471 
472  if (showParams.Length > 2 && showParams[2] == "full")
473  showChildren = true;
474  else if (showParams.Length > 3)
475  pname = showParams[2] + " " + showParams[3];
476 
477  StringBuilder report = new StringBuilder();
478 
479  int columnPadding = 2;
480  int maxNameLength = 18;
481  int maxRegionNameLength = 14;
482  int maxTypeLength = 4;
483  int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
484 
485  report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
486  report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
487  report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
488 
489  report.AppendFormat(
490  "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
491  "Max",
492  "Target",
493  "Actual",
494  "Resend",
495  "Land",
496  "Wind",
497  "Cloud",
498  "Task",
499  "Texture",
500  "Asset");
501 
502  report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
503  report.AppendFormat(
504  "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
505  "kb/s",
506  "kb/s",
507  "kb/s",
508  "kb/s",
509  "kb/s",
510  "kb/s",
511  "kb/s",
512  "kb/s",
513  "kb/s",
514  "kb/s");
515 
516  report.AppendLine();
517 
518  lock (m_scenes)
519  {
520  foreach (Scene scene in m_scenes.Values)
521  {
522  scene.ForEachClient(
523  delegate(IClientAPI client)
524  {
525  if (client is LLClientView)
526  {
527  LLClientView llClient = client as LLClientView;
528 
529  bool isChild = client.SceneAgent.IsChildAgent;
530  if (isChild && !showChildren)
531  return;
532 
533  string name = client.Name;
534  if (pname != "" && name != pname)
535  return;
536 
537  string regionName = scene.RegionInfo.RegionName;
538 
539  LLUDPClient llUdpClient = llClient.UDPClient;
540  ClientInfo ci = llUdpClient.GetClientInfo();
541 
542  report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
543  report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
544  report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
545 
546  report.AppendFormat(
547  "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
548  ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-",
549  llUdpClient.FlowThrottle.AdaptiveEnabled
550  ? ((ci.targetThrottle * 8) / 1000).ToString()
551  : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(),
552  (ci.totalThrottle * 8) / 1000,
553  (ci.resendThrottle * 8) / 1000,
554  (ci.landThrottle * 8) / 1000,
555  (ci.windThrottle * 8) / 1000,
556  (ci.cloudThrottle * 8) / 1000,
557  (ci.taskThrottle * 8) / 1000,
558  (ci.textureThrottle * 8) / 1000,
559  (ci.assetThrottle * 8) / 1000);
560  }
561  });
562  }
563  }
564 
565  return report.ToString();
566  }
567 
573  protected string HandleClientStatsReport(string[] showParams)
574  {
575  // NOTE: This writes to m_log on purpose. We want to store this information
576  // in case we need to analyze it later.
577  //
578  if (showParams.Length <= 4)
579  {
580  m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
581  foreach (Scene scene in m_scenes.Values)
582  {
583  scene.ForEachClient(
584  delegate(IClientAPI client)
585  {
586  if (client is LLClientView)
587  {
588  LLClientView llClient = client as LLClientView;
589  ClientInfo cinfo = llClient.UDPClient.GetClientInfo();
590  int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
591  avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
592 
593  string childAgentStatus;
594 
595  if (llClient.SceneAgent != null)
596  childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y";
597  else
598  childAgentStatus = "Off!";
599 
600  m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
601  scene.RegionInfo.RegionName, llClient.Name,
602  childAgentStatus,
603  (DateTime.Now - cinfo.StartedTime).Minutes,
604  avg_reqs,
605  string.Format(
606  "{0} ({1:0.00}%)",
607  llClient.TotalAgentUpdates,
608  cinfo.SyncRequests.ContainsKey("AgentUpdate")
609  ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100
610  : 0));
611  }
612  });
613  }
614  return string.Empty;
615  }
616 
617  string fname = "", lname = "";
618 
619  if (showParams.Length > 3)
620  fname = showParams[3];
621  if (showParams.Length > 4)
622  lname = showParams[4];
623 
624  foreach (Scene scene in m_scenes.Values)
625  {
626  scene.ForEachClient(
627  delegate(IClientAPI client)
628  {
629  if (client is LLClientView)
630  {
631  LLClientView llClient = client as LLClientView;
632 
633  if (llClient.Name == fname + " " + lname)
634  {
635 
636  ClientInfo cinfo = llClient.GetClientInfo();
637  AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode);
638  if (aCircuit == null) // create a dummy one
639  aCircuit = new AgentCircuitData();
640 
641  if (!llClient.SceneAgent.IsChildAgent)
642  m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
643 
644  int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
645  avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
646 
647  m_log.InfoFormat("[INFO]:");
648  m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName,
649  (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
650 
651  Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
652  .ToDictionary(pair => pair.Key, pair => pair.Value);
653  PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
654 
655  sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
656  .ToDictionary(pair => pair.Key, pair => pair.Value);
657  PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
658 
659  sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
660  .ToDictionary(pair => pair.Key, pair => pair.Value);
661  PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
662  }
663  }
664  });
665  }
666  return string.Empty;
667  }
668 
669  private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum)
670  {
671  m_log.InfoFormat("[INFO]:");
672  m_log.InfoFormat("[INFO]: {0,25}", type);
673  foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
674  m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value);
675  m_log.InfoFormat("[INFO]: {0,25}", "...");
676  m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
677  }
678  }
679 }
Implemented by classes which collect up non-viewer statistical information
string HandleClientStatsReport(string[] showParams)
Show client stats data
Handles new client connections Constructor takes a single Packet and authenticates everything ...
Definition: LLClientView.cs:65
bool IsChildAgent
If true, then the agent has no avatar in the scene. The agent exists to relay data from a region that...
Definition: ISceneAgent.cs:56
Dictionary< string, int > GenericRequests
Definition: ClientInfo.cs:65
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
string Name
Full name of the client (first name and last name)
string GetPQueuesReport(string[] showParams)
Generate UDP Queue data report for each client
Tracks state for a client UDP connection and provides client-specific methods
Definition: LLUDPClient.cs:66
Dictionary< string, int > SyncRequests
Definition: ClientInfo.cs:63
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Stores information about a current texture download and a reference to the texture asset ...
Definition: J2KImage.cs:43
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
string GetThrottlesReport(string[] showParams)
Show throttle data
static ICommandConsole Instance
Definition: MainConsole.cs:35
void Output(string text, string level)
Interactive OpenSim region server
Definition: OpenSim.cs:55
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
string GetQueuesReport(string[] showParams)
Generate UDP Queue data report for each client
readonly DateTime StartedTime
Definition: ClientInfo.cs:36
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
A module that just holds commands for inspecting the current state of the Linden UDP stack...
Dictionary< string, int > AsyncRequests
Definition: ClientInfo.cs:64
string GetColumnEntry(string entry, int maxLength, int columnPadding)