clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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 copyrightD
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;
30 using System.Collections.Generic;
31 using System.Linq;
32 using System.Reflection;
33 using System.Text;
34 using log4net;
35 using Nini.Config;
36 using Mono.Addins;
37 using OpenMetaverse;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Console;
40 using OpenSim.Framework.Servers;
41 using OpenSim.Framework.Servers.HttpServer;
42 using OpenSim.Region.Framework.Interfaces;
43 using OpenSim.Region.Framework.Scenes;
44 using Caps=OpenSim.Framework.Capabilities.Caps;
45  
46 namespace OpenSim.Region.CoreModules.Framework
47 {
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CapabilitiesModule")]
49 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52  
53 private string m_showCapsCommandFormat = " {0,-38} {1,-60}\n";
54  
55 protected Scene m_scene;
56  
57 /// <summary>
58 /// Each agent has its own capabilities handler.
59 /// </summary>
60 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>();
61  
62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
63  
64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
65 = new Dictionary<UUID, Dictionary<ulong, string>>();
66  
67 public void Initialise(IConfigSource source)
68 {
69 }
70  
71 public void AddRegion(Scene scene)
72 {
73 m_scene = scene;
74 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
75  
76 MainConsole.Instance.Commands.AddCommand(
77 "Comms", false, "show caps list",
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 by user [<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);
94 }
95  
96 public void RegionLoaded(Scene scene)
97 {
98 }
99  
100 public void RemoveRegion(Scene scene)
101 {
102 m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this);
103 }
104  
105 public void PostInitialise()
106 {
107 }
108  
109 public void Close() {}
110  
111 public string Name
112 {
113 get { return "Capabilities Module"; }
114 }
115  
116 public Type ReplaceableInterface
117 {
118 get { return null; }
119 }
120  
121 public void CreateCaps(UUID agentId)
122 {
123 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId))
124 return;
125  
126 Caps caps;
127 String capsObjectPath = GetCapsPath(agentId);
128  
129 lock (m_capsObjects)
130 {
131 if (m_capsObjects.ContainsKey(agentId))
132 {
133 Caps oldCaps = m_capsObjects[agentId];
134  
135 //m_log.WarnFormat(
136 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
137 // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
138 }
139  
140 // m_log.DebugFormat(
141 // "[CAPS]: Adding capabilities for agent {0} in {1} with path {2}",
142 // agentId, m_scene.RegionInfo.RegionName, capsObjectPath);
143  
144 caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
145 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
146 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
147  
148 m_capsObjects[agentId] = caps;
149 }
150  
151 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
152 }
153  
154 public void RemoveCaps(UUID agentId)
155 {
156 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
157 lock (m_childrenSeeds)
158 {
159 if (m_childrenSeeds.ContainsKey(agentId))
160 {
161 m_childrenSeeds.Remove(agentId);
162 }
163 }
164  
165 lock (m_capsObjects)
166 {
167 if (m_capsObjects.ContainsKey(agentId))
168 {
169 m_capsObjects[agentId].DeregisterHandlers();
170 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]);
171 m_capsObjects.Remove(agentId);
172 }
173 else
174 {
175 m_log.WarnFormat(
176 "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
177 agentId, m_scene.RegionInfo.RegionName);
178 }
179 }
180 }
181  
182 public Caps GetCapsForUser(UUID agentId)
183 {
184 lock (m_capsObjects)
185 {
186 if (m_capsObjects.ContainsKey(agentId))
187 {
188 return m_capsObjects[agentId];
189 }
190 }
191  
192 return null;
193 }
194  
195 public void SetAgentCapsSeeds(AgentCircuitData agent)
196 {
197 lock (m_capsPaths)
198 m_capsPaths[agent.AgentID] = agent.CapsPath;
199  
200 lock (m_childrenSeeds)
201 m_childrenSeeds[agent.AgentID]
202 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
203 }
204  
205 public string GetCapsPath(UUID agentId)
206 {
207 lock (m_capsPaths)
208 {
209 if (m_capsPaths.ContainsKey(agentId))
210 {
211 return m_capsPaths[agentId];
212 }
213 }
214  
215 return null;
216 }
217  
218 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
219 {
220 Dictionary<ulong, string> seeds = null;
221  
222 lock (m_childrenSeeds)
223 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
224 return seeds;
225  
226 return new Dictionary<ulong, string>();
227 }
228  
229 public void DropChildSeed(UUID agentID, ulong handle)
230 {
231 Dictionary<ulong, string> seeds;
232  
233 lock (m_childrenSeeds)
234 {
235 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
236 {
237 seeds.Remove(handle);
238 }
239 }
240 }
241  
242 public string GetChildSeed(UUID agentID, ulong handle)
243 {
244 Dictionary<ulong, string> seeds;
245 string returnval;
246  
247 lock (m_childrenSeeds)
248 {
249 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
250 {
251 if (seeds.TryGetValue(handle, out returnval))
252 return returnval;
253 }
254 }
255  
256 return null;
257 }
258  
259 public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds)
260 {
261 //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count);
262  
263 lock (m_childrenSeeds)
264 m_childrenSeeds[agentID] = seeds;
265 }
266  
267 public void DumpChildrenSeeds(UUID agentID)
268 {
269 m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================");
270  
271 lock (m_childrenSeeds)
272 {
273 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
274 {
275 uint x, y;
276 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
277 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
278 }
279 }
280 }
281  
282 private void HandleShowCapsListCommand(string module, string[] cmdParams)
283 {
284 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
285 return;
286  
287 StringBuilder capsReport = new StringBuilder();
288 capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
289  
290 lock (m_capsObjects)
291 {
292 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects)
293 {
294 capsReport.AppendFormat("** User {0}:\n", kvp.Key);
295 Caps caps = kvp.Value;
296  
297 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
298 {
299 Uri uri = new Uri(kvp2.Value.ToString());
300 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
301 }
302  
303 foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers())
304 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url);
305  
306 foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers)
307 capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
308 }
309 }
310  
311 MainConsole.Instance.Output(capsReport.ToString());
312 }
313  
314 private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
315 {
316 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
317 return;
318  
319 if (cmdParams.Length != 5 && cmdParams.Length != 6)
320 {
321 MainConsole.Instance.Output("Usage: show caps stats by cap [<cap-name>]");
322 return;
323 }
324  
325 StringBuilder sb = new StringBuilder();
326 sb.AppendFormat("Region {0}:\n", m_scene.Name);
327  
328 if (cmdParams.Length == 5)
329 {
330 BuildSummaryStatsByCapReport(sb);
331 }
332 else if (cmdParams.Length == 6)
333 {
334 BuildDetailedStatsByCapReport(sb, cmdParams[5]);
335 }
336  
337 MainConsole.Instance.Output(sb.ToString());
338 }
339  
340 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
341 {
342 sb.AppendFormat("Capability name {0}\n", capName);
343  
344 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
345 cdt.AddColumn("User Name", 34);
346 cdt.AddColumn("Req Received", 12);
347 cdt.AddColumn("Req Handled", 12);
348 cdt.Indent = 2;
349  
350 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
351 Dictionary<string, int> handledStats = new Dictionary<string, int>();
352  
353 m_scene.ForEachScenePresence(
354 sp =>
355 {
356 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
357  
358 if (caps == null)
359 return;
360  
361 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
362  
363 IRequestHandler reqHandler;
364 if (capsHandlers.TryGetValue(capName, out reqHandler))
365 {
366 receivedStats[sp.Name] = reqHandler.RequestsReceived;
367 handledStats[sp.Name] = reqHandler.RequestsHandled;
368 }
369 else
370 {
371 PollServiceEventArgs pollHandler = null;
372 if (caps.TryGetPollHandler(capName, out pollHandler))
373 {
374 receivedStats[sp.Name] = pollHandler.RequestsReceived;
375 handledStats[sp.Name] = pollHandler.RequestsHandled;
376 }
377 }
378 }
379 );
380  
381 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
382 {
383 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
384 }
385  
386 sb.Append(cdt.ToString());
387 }
388  
389 private void BuildSummaryStatsByCapReport(StringBuilder sb)
390 {
391 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
392 cdt.AddColumn("Name", 34);
393 cdt.AddColumn("Req Received", 12);
394 cdt.AddColumn("Req Handled", 12);
395 cdt.Indent = 2;
396  
397 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
398 Dictionary<string, int> handledStats = new Dictionary<string, int>();
399  
400 m_scene.ForEachScenePresence(
401 sp =>
402 {
403 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
404  
405 if (caps == null)
406 return;
407  
408 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
409 {
410 string reqName = reqHandler.Name ?? "";
411  
412 if (!receivedStats.ContainsKey(reqName))
413 {
414 receivedStats[reqName] = reqHandler.RequestsReceived;
415 handledStats[reqName] = reqHandler.RequestsHandled;
416 }
417 else
418 {
419 receivedStats[reqName] += reqHandler.RequestsReceived;
420 handledStats[reqName] += reqHandler.RequestsHandled;
421 }
422 }
423  
424 foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
425 {
426 string name = kvp.Key;
427 PollServiceEventArgs pollHandler = kvp.Value;
428  
429 if (!receivedStats.ContainsKey(name))
430 {
431 receivedStats[name] = pollHandler.RequestsReceived;
432 handledStats[name] = pollHandler.RequestsHandled;
433 }
434 else
435 {
436 receivedStats[name] += pollHandler.RequestsReceived;
437 handledStats[name] += pollHandler.RequestsHandled;
438 }
439 }
440 }
441 );
442  
443 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
444 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
445  
446 sb.Append(cdt.ToString());
447 }
448  
449 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
450 {
451 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
452 return;
453  
454 if (cmdParams.Length != 5 && cmdParams.Length != 7)
455 {
456 MainConsole.Instance.Output("Usage: show caps stats by user [<first-name> <last-name>]");
457 return;
458 }
459  
460 StringBuilder sb = new StringBuilder();
461 sb.AppendFormat("Region {0}:\n", m_scene.Name);
462  
463 if (cmdParams.Length == 5)
464 {
465 BuildSummaryStatsByUserReport(sb);
466 }
467 else if (cmdParams.Length == 7)
468 {
469 string firstName = cmdParams[5];
470 string lastName = cmdParams[6];
471  
472 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
473  
474 if (sp == null)
475 return;
476  
477 BuildDetailedStatsByUserReport(sb, sp);
478 }
479  
480 MainConsole.Instance.Output(sb.ToString());
481 }
482  
483 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
484 {
485 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
486  
487 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
488 cdt.AddColumn("Cap Name", 34);
489 cdt.AddColumn("Req Received", 12);
490 cdt.AddColumn("Req Handled", 12);
491 cdt.Indent = 2;
492  
493 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
494  
495 if (caps == null)
496 return;
497  
498 List<CapTableRow> capRows = new List<CapTableRow>();
499  
500 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
501 capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled));
502  
503 foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
504 capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
505  
506 foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
507 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
508  
509 sb.Append(cdt.ToString());
510 }
511  
512 private void BuildSummaryStatsByUserReport(StringBuilder sb)
513 {
514 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
515 cdt.AddColumn("Name", 32);
516 cdt.AddColumn("Type", 5);
517 cdt.AddColumn("Req Received", 12);
518 cdt.AddColumn("Req Handled", 12);
519 cdt.Indent = 2;
520  
521 m_scene.ForEachScenePresence(
522 sp =>
523 {
524 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
525  
526 if (caps == null)
527 return;
528  
529 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
530  
531 int totalRequestsReceived = 0;
532 int totalRequestsHandled = 0;
533  
534 foreach (IRequestHandler reqHandler in capsHandlers.Values)
535 {
536 totalRequestsReceived += reqHandler.RequestsReceived;
537 totalRequestsHandled += reqHandler.RequestsHandled;
538 }
539  
540 Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers();
541  
542 foreach (PollServiceEventArgs handler in capsPollHandlers.Values)
543 {
544 totalRequestsReceived += handler.RequestsReceived;
545 totalRequestsHandled += handler.RequestsHandled;
546 }
547  
548 cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
549 }
550 );
551  
552 sb.Append(cdt.ToString());
553 }
554  
555 private class CapTableRow
556 {
557 public string Name { get; set; }
558 public int RequestsReceived { get; set; }
559 public int RequestsHandled { get; set; }
560  
561 public CapTableRow(string name, int requestsReceived, int requestsHandled)
562 {
563 Name = name;
564 RequestsReceived = requestsReceived;
565 RequestsHandled = requestsHandled;
566 }
567 }
568 }
569 }