aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/Caps
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-07-08 22:03:07 +0100
committerJustin Clark-Casey (justincc)2013-07-08 22:03:07 +0100
commite19defde36ddbd5ff90d8304c6fe3b57110f8078 (patch)
tree63b349551f341f00a8a9c598a76343d7b453c328 /OpenSim/Region/CoreModules/Framework/Caps
parentMake dictionary read/write locking consistent in CapabilitiesModule, rename t... (diff)
downloadopensim-SC_OLD-e19defde36ddbd5ff90d8304c6fe3b57110f8078.zip
opensim-SC_OLD-e19defde36ddbd5ff90d8304c6fe3b57110f8078.tar.gz
opensim-SC_OLD-e19defde36ddbd5ff90d8304c6fe3b57110f8078.tar.bz2
opensim-SC_OLD-e19defde36ddbd5ff90d8304c6fe3b57110f8078.tar.xz
Add "show caps stats by user" and "show caps stats by cap" console commands to print various counts of capability invocation by user and by cap
This currently prints caps requests received and handled, so that overload of received compared to handled or deadlock can be detected. This involves making BaseStreamHandler and BaseOutputStream record the ints, which means inheritors should subclass ProcessRequest() instead of Handle() However, existing inheriting classes overriding Handle() will still work, albeit without stats recording. "show caps" becomes "show caps list" to disambiguate between show caps commands
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/Caps')
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs234
1 files changed, 230 insertions, 4 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index c8b341b..bd60611 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq;
31using System.Reflection; 32using System.Reflection;
32using System.Text; 33using System.Text;
33using log4net; 34using log4net;
@@ -37,6 +38,7 @@ using OpenMetaverse;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Framework.Console; 39using OpenSim.Framework.Console;
39using OpenSim.Framework.Servers; 40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
42using Caps=OpenSim.Framework.Capabilities.Caps; 44using Caps=OpenSim.Framework.Capabilities.Caps;
@@ -58,6 +60,7 @@ namespace OpenSim.Region.CoreModules.Framework
58 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 60 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>();
59 61
60 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>(); 62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
63
61 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds 64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
62 = new Dictionary<UUID, Dictionary<ulong, string>>(); 65 = new Dictionary<UUID, Dictionary<ulong, string>>();
63 66
@@ -70,9 +73,24 @@ namespace OpenSim.Region.CoreModules.Framework
70 m_scene = scene; 73 m_scene = scene;
71 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); 74 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
72 75
73 MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps", 76 MainConsole.Instance.Commands.AddCommand(
74 "show caps", 77 "Comms", false, "show caps list",
75 "Shows all registered capabilities for users", HandleShowCapsCommand); 78 "show caps list",
79 "Shows list of registered capabilities for users.", HandleShowCapsListCommand);
80
81 MainConsole.Instance.Commands.AddCommand(
82 "Comms", false, "show caps stats by user",
83 "show caps stats [<first-name> <last-name>]",
84 "Shows statistics on capabilities use by user.",
85 "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
86 HandleShowCapsStatsByUserCommand);
87
88 MainConsole.Instance.Commands.AddCommand(
89 "Comms", false, "show caps stats by cap",
90 "show caps stats by cap [<cap-name>]",
91 "Shows statistics on capabilities use by capability.",
92 "If a capability name is given, then prints a detailed breakdown of use by each user.",
93 HandleShowCapsStatsByCapCommand);
76 } 94 }
77 95
78 public void RegionLoaded(Scene scene) 96 public void RegionLoaded(Scene scene)
@@ -262,8 +280,11 @@ namespace OpenSim.Region.CoreModules.Framework
262 } 280 }
263 } 281 }
264 282
265 private void HandleShowCapsCommand(string module, string[] cmdparams) 283 private void HandleShowCapsListCommand(string module, string[] cmdParams)
266 { 284 {
285 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
286 return;
287
267 StringBuilder caps = new StringBuilder(); 288 StringBuilder caps = new StringBuilder();
268 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 289 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
269 290
@@ -286,5 +307,210 @@ namespace OpenSim.Region.CoreModules.Framework
286 307
287 MainConsole.Instance.Output(caps.ToString()); 308 MainConsole.Instance.Output(caps.ToString());
288 } 309 }
310
311 private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
312 {
313 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
314 return;
315
316 if (cmdParams.Length != 5 && cmdParams.Length != 6)
317 {
318 MainConsole.Instance.Output("Usage: show caps stats by cap [<cap-name>]");
319 return;
320 }
321
322 StringBuilder sb = new StringBuilder();
323 sb.AppendFormat("Region {0}:\n", m_scene.Name);
324
325 if (cmdParams.Length == 5)
326 {
327 BuildSummaryStatsByCapReport(sb);
328 }
329 else if (cmdParams.Length == 6)
330 {
331 BuildDetailedStatsByCapReport(sb, cmdParams[5]);
332 }
333
334 MainConsole.Instance.Output(sb.ToString());
335 }
336
337 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
338 {
339 sb.AppendFormat("Capability name {0}\n", capName);
340
341 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
342 cdt.AddColumn("User Name", 34);
343 cdt.AddColumn("Req Received", 12);
344 cdt.AddColumn("Req Handled", 12);
345 cdt.Indent = 2;
346
347 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
348 Dictionary<string, int> handledStats = new Dictionary<string, int>();
349
350 m_scene.ForEachScenePresence(
351 sp =>
352 {
353 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
354
355 if (caps == null)
356 return;
357
358 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
359
360 IRequestHandler reqHandler;
361 if (capsHandlers.TryGetValue(capName, out reqHandler))
362 {
363 receivedStats[sp.Name] = reqHandler.RequestsReceived;
364 handledStats[sp.Name] = reqHandler.RequestsHandled;
365 }
366 }
367 );
368
369 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
370 {
371 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
372 }
373
374 sb.Append(cdt.ToString());
375 }
376
377 private void BuildSummaryStatsByCapReport(StringBuilder sb)
378 {
379 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
380 cdt.AddColumn("Name", 34);
381 cdt.AddColumn("Req Received", 12);
382 cdt.AddColumn("Req Handled", 12);
383 cdt.Indent = 2;
384
385 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
386 Dictionary<string, int> handledStats = new Dictionary<string, int>();
387
388 m_scene.ForEachScenePresence(
389 sp =>
390 {
391 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
392
393 if (caps == null)
394 return;
395
396 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
397
398 foreach (IRequestHandler reqHandler in capsHandlers.Values)
399 {
400 string reqName = reqHandler.Name ?? "";
401
402 if (!receivedStats.ContainsKey(reqName))
403 {
404 receivedStats[reqName] = reqHandler.RequestsReceived;
405 handledStats[reqName] = reqHandler.RequestsHandled;
406 }
407 else
408 {
409 receivedStats[reqName] += reqHandler.RequestsReceived;
410 handledStats[reqName] += reqHandler.RequestsHandled;
411 }
412 }
413 }
414 );
415
416 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
417 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
418
419 sb.Append(cdt.ToString());
420 }
421
422 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
423 {
424 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
425 return;
426
427 if (cmdParams.Length != 5 && cmdParams.Length != 7)
428 {
429 MainConsole.Instance.Output("Usage: show caps stats by user [<first-name> <last-name>]");
430 return;
431 }
432
433 StringBuilder sb = new StringBuilder();
434 sb.AppendFormat("Region {0}:\n", m_scene.Name);
435
436 if (cmdParams.Length == 5)
437 {
438 BuildSummaryStatsByUserReport(sb);
439 }
440 else if (cmdParams.Length == 7)
441 {
442 string firstName = cmdParams[5];
443 string lastName = cmdParams[6];
444
445 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
446
447 if (sp == null)
448 return;
449
450 BuildDetailedStatsByUserReport(sb, sp);
451 }
452
453 MainConsole.Instance.Output(sb.ToString());
454 }
455
456 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
457 {
458 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
459
460 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
461 cdt.AddColumn("Cap Name", 34);
462 cdt.AddColumn("Req Received", 12);
463 cdt.AddColumn("Req Handled", 12);
464 cdt.Indent = 2;
465
466 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
467
468 if (caps == null)
469 return;
470
471 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
472
473 foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived))
474 {
475 cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled);
476 }
477
478 sb.Append(cdt.ToString());
479 }
480
481 private void BuildSummaryStatsByUserReport(StringBuilder sb)
482 {
483 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
484 cdt.AddColumn("Name", 32);
485 cdt.AddColumn("Type", 5);
486 cdt.AddColumn("Req Received", 12);
487 cdt.AddColumn("Req Handled", 12);
488 cdt.Indent = 2;
489
490 m_scene.ForEachScenePresence(
491 sp =>
492 {
493 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
494
495 if (caps == null)
496 return;
497
498 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
499
500 int totalRequestsReceived = 0;
501 int totalRequestsHandled = 0;
502
503 foreach (IRequestHandler reqHandler in capsHandlers.Values)
504 {
505 totalRequestsReceived += reqHandler.RequestsReceived;
506 totalRequestsHandled += reqHandler.RequestsHandled;
507 }
508
509 cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
510 }
511 );
512
513 sb.Append(cdt.ToString());
514 }
289 } 515 }
290} \ No newline at end of file 516} \ No newline at end of file