diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Monitoring/StatsManager.cs | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 3136ee8..a6b341f 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs | |||
@@ -47,6 +47,8 @@ namespace OpenSim.Framework.Monitoring | |||
47 | // Subcommand used to list other stats. | 47 | // Subcommand used to list other stats. |
48 | public const string ListSubCommand = "list"; | 48 | public const string ListSubCommand = "list"; |
49 | 49 | ||
50 | public static string StatsPassword { get; set; } | ||
51 | |||
50 | // All subcommands | 52 | // All subcommands |
51 | public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand }; | 53 | public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand }; |
52 | 54 | ||
@@ -80,8 +82,7 @@ namespace OpenSim.Framework.Monitoring | |||
80 | + "'all' will show all statistics.\n" | 82 | + "'all' will show all statistics.\n" |
81 | + "A <category> name will show statistics from that category.\n" | 83 | + "A <category> name will show statistics from that category.\n" |
82 | + "A <category>.<container> name will show statistics from that category in that container.\n" | 84 | + "A <category>.<container> name will show statistics from that category in that container.\n" |
83 | + "More than one name can be given separated by spaces.\n" | 85 | + "More than one name can be given separated by spaces.\n", |
84 | + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS", | ||
85 | HandleShowStatsCommand); | 86 | HandleShowStatsCommand); |
86 | 87 | ||
87 | console.Commands.AddCommand( | 88 | console.Commands.AddCommand( |
@@ -91,7 +92,6 @@ namespace OpenSim.Framework.Monitoring | |||
91 | "show stats [list|all|(<category>[.<container>])+", | 92 | "show stats [list|all|(<category>[.<container>])+", |
92 | "Alias for 'stats show' command", | 93 | "Alias for 'stats show' command", |
93 | HandleShowStatsCommand); | 94 | HandleShowStatsCommand); |
94 | |||
95 | StatsLogger.RegisterConsoleCommands(console); | 95 | StatsLogger.RegisterConsoleCommands(console); |
96 | } | 96 | } |
97 | 97 | ||
@@ -262,33 +262,36 @@ namespace OpenSim.Framework.Monitoring | |||
262 | { | 262 | { |
263 | OSDMap map = new OSDMap(); | 263 | OSDMap map = new OSDMap(); |
264 | 264 | ||
265 | foreach (string catName in RegisteredStats.Keys) | 265 | lock (RegisteredStats) |
266 | { | 266 | { |
267 | // Do this category if null spec, "all" subcommand or category name matches passed parameter. | 267 | foreach (string catName in RegisteredStats.Keys) |
268 | // Skip category if none of the above. | ||
269 | if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName)) | ||
270 | continue; | ||
271 | |||
272 | OSDMap contMap = new OSDMap(); | ||
273 | foreach (string contName in RegisteredStats[catName].Keys) | ||
274 | { | 268 | { |
275 | if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName)) | 269 | // Do this category if null spec, "all" subcommand or category name matches passed parameter. |
270 | // Skip category if none of the above. | ||
271 | if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName)) | ||
276 | continue; | 272 | continue; |
277 | |||
278 | OSDMap statMap = new OSDMap(); | ||
279 | 273 | ||
280 | SortedDictionary<string, Stat> theStats = RegisteredStats[catName][contName]; | 274 | OSDMap contMap = new OSDMap(); |
281 | foreach (string statName in theStats.Keys) | 275 | foreach (string contName in RegisteredStats[catName].Keys) |
282 | { | 276 | { |
283 | if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) | 277 | if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName)) |
284 | continue; | 278 | continue; |
285 | 279 | ||
286 | statMap.Add(statName, theStats[statName].ToOSDMap()); | 280 | OSDMap statMap = new OSDMap(); |
287 | } | 281 | |
282 | SortedDictionary<string, Stat> theStats = RegisteredStats[catName][contName]; | ||
283 | foreach (string statName in theStats.Keys) | ||
284 | { | ||
285 | if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) | ||
286 | continue; | ||
287 | |||
288 | statMap.Add(statName, theStats[statName].ToBriefOSDMap()); | ||
289 | } | ||
288 | 290 | ||
289 | contMap.Add(contName, statMap); | 291 | contMap.Add(contName, statMap); |
292 | } | ||
293 | map.Add(catName, contMap); | ||
290 | } | 294 | } |
291 | map.Add(catName, contMap); | ||
292 | } | 295 | } |
293 | 296 | ||
294 | return map; | 297 | return map; |
@@ -301,6 +304,17 @@ namespace OpenSim.Framework.Monitoring | |||
301 | int response_code = 200; | 304 | int response_code = 200; |
302 | string contenttype = "text/json"; | 305 | string contenttype = "text/json"; |
303 | 306 | ||
307 | if (StatsPassword != String.Empty && (!request.ContainsKey("pass") || request["pass"].ToString() != StatsPassword)) | ||
308 | { | ||
309 | responsedata["int_response_code"] = response_code; | ||
310 | responsedata["content_type"] = "text/plain"; | ||
311 | responsedata["keepalive"] = false; | ||
312 | responsedata["str_response_string"] = "Access denied"; | ||
313 | responsedata["access_control_allow_origin"] = "*"; | ||
314 | |||
315 | return responsedata; | ||
316 | } | ||
317 | |||
304 | string pCategoryName = StatsManager.AllSubCommand; | 318 | string pCategoryName = StatsManager.AllSubCommand; |
305 | string pContainerName = StatsManager.AllSubCommand; | 319 | string pContainerName = StatsManager.AllSubCommand; |
306 | string pStatName = StatsManager.AllSubCommand; | 320 | string pStatName = StatsManager.AllSubCommand; |
@@ -358,8 +372,8 @@ namespace OpenSim.Framework.Monitoring | |||
358 | /// <returns></returns> | 372 | /// <returns></returns> |
359 | public static bool RegisterStat(Stat stat) | 373 | public static bool RegisterStat(Stat stat) |
360 | { | 374 | { |
361 | SortedDictionary<string, SortedDictionary<string, Stat>> category = null, newCategory; | 375 | SortedDictionary<string, SortedDictionary<string, Stat>> category = null; |
362 | SortedDictionary<string, Stat> container = null, newContainer; | 376 | SortedDictionary<string, Stat> container = null; |
363 | 377 | ||
364 | lock (RegisteredStats) | 378 | lock (RegisteredStats) |
365 | { | 379 | { |
@@ -369,22 +383,15 @@ namespace OpenSim.Framework.Monitoring | |||
369 | if (TryGetStatParents(stat, out category, out container)) | 383 | if (TryGetStatParents(stat, out category, out container)) |
370 | return false; | 384 | return false; |
371 | 385 | ||
372 | // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. | 386 | if (container == null) |
373 | // This means that we don't need to lock or copy them on iteration, which will be a much more | 387 | container = new SortedDictionary<string, Stat>(); |
374 | // common operation after startup. | ||
375 | if (container != null) | ||
376 | newContainer = new SortedDictionary<string, Stat>(container); | ||
377 | else | ||
378 | newContainer = new SortedDictionary<string, Stat>(); | ||
379 | 388 | ||
380 | if (category != null) | 389 | if (category == null) |
381 | newCategory = new SortedDictionary<string, SortedDictionary<string, Stat>>(category); | 390 | category = new SortedDictionary<string, SortedDictionary<string, Stat>>(); |
382 | else | ||
383 | newCategory = new SortedDictionary<string, SortedDictionary<string, Stat>>(); | ||
384 | 391 | ||
385 | newContainer[stat.ShortName] = stat; | 392 | container[stat.ShortName] = stat; |
386 | newCategory[stat.Container] = newContainer; | 393 | category[stat.Container] = container; |
387 | RegisteredStats[stat.Category] = newCategory; | 394 | RegisteredStats[stat.Category] = category; |
388 | } | 395 | } |
389 | 396 | ||
390 | return true; | 397 | return true; |
@@ -397,23 +404,24 @@ namespace OpenSim.Framework.Monitoring | |||
397 | /// <returns></returns> | 404 | /// <returns></returns> |
398 | public static bool DeregisterStat(Stat stat) | 405 | public static bool DeregisterStat(Stat stat) |
399 | { | 406 | { |
400 | SortedDictionary<string, SortedDictionary<string, Stat>> category = null, newCategory; | 407 | SortedDictionary<string, SortedDictionary<string, Stat>> category = null; |
401 | SortedDictionary<string, Stat> container = null, newContainer; | 408 | SortedDictionary<string, Stat> container = null; |
402 | 409 | ||
403 | lock (RegisteredStats) | 410 | lock (RegisteredStats) |
404 | { | 411 | { |
405 | if (!TryGetStatParents(stat, out category, out container)) | 412 | if (!TryGetStatParents(stat, out category, out container)) |
406 | return false; | 413 | return false; |
407 | 414 | ||
408 | newContainer = new SortedDictionary<string, Stat>(container); | 415 | if(container != null) |
409 | newContainer.Remove(stat.ShortName); | 416 | { |
410 | 417 | container.Remove(stat.ShortName); | |
411 | newCategory = new SortedDictionary<string, SortedDictionary<string, Stat>>(category); | 418 | if(category != null && container.Count == 0) |
412 | newCategory.Remove(stat.Container); | 419 | { |
413 | 420 | category.Remove(stat.Container); | |
414 | newCategory[stat.Container] = newContainer; | 421 | if(category.Count == 0) |
415 | RegisteredStats[stat.Category] = newCategory; | 422 | RegisteredStats.Remove(stat.Category); |
416 | 423 | } | |
424 | } | ||
417 | return true; | 425 | return true; |
418 | } | 426 | } |
419 | } | 427 | } |
@@ -554,4 +562,4 @@ namespace OpenSim.Framework.Monitoring | |||
554 | Debug, | 562 | Debug, |
555 | Info | 563 | Info |
556 | } | 564 | } |
557 | } \ No newline at end of file | 565 | } |