From 35efa88c26d249d315837fdca0faf643511e1a4e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 23:11:50 +0100
Subject: Rename OpenSim.Framework.Statistics to OpenSim.Framework.Monitoring.
This better reflects the long-term purpose of that project and matches Monitoring modules.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 65 ++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
create mode 100644 OpenSim/Framework/Monitoring/StatsManager.cs
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
new file mode 100644
index 0000000..d78fa6a
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Singleton used to provide access to statistics reporters
+ ///
+ public class StatsManager
+ {
+ private static AssetStatsCollector assetStats;
+ private static UserStatsCollector userStats;
+ private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
+
+ public static AssetStatsCollector AssetStats { get { return assetStats; } }
+ public static UserStatsCollector UserStats { get { return userStats; } }
+ public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
+
+ ///
+ /// Start collecting statistics related to assets.
+ /// Should only be called once.
+ ///
+ public static AssetStatsCollector StartCollectingAssetStats()
+ {
+ assetStats = new AssetStatsCollector();
+
+ return assetStats;
+ }
+
+ ///
+ /// Start collecting statistics related to users.
+ /// Should only be called once.
+ ///
+ public static UserStatsCollector StartCollectingUserStats()
+ {
+ userStats = new UserStatsCollector();
+
+ return userStats;
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.1
From e717398f6c72bdb30e59468462f3a5f589c1bb35 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 4 Oct 2012 00:32:42 +0100
Subject: Add experimental "slow frames" stat, available in "show stats" and
via the monitoring module.
This increments a SlowFrames counter if a frame takes over 120% of maximum time.
This commit also introduces a generic OpenSim.Framework.Monitoring.Stat which is available to any code that wants to register a statistic.
This is more granualar than asking objects to create their own reports.
At some point this will supersede earlier IMonitor and IAlert facilities in MonitoringModule which are only available to scene code.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 114 +++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index d78fa6a..02df0ac 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -25,6 +25,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+using System;
+using System.Collections.Generic;
+
namespace OpenSim.Framework.Monitoring
{
///
@@ -32,6 +35,14 @@ namespace OpenSim.Framework.Monitoring
///
public class StatsManager
{
+ ///
+ /// Registered stats.
+ ///
+ ///
+ /// Do not add or remove from this dictionary.
+ ///
+ public static Dictionary RegisteredStats = new Dictionary();
+
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
@@ -61,5 +72,108 @@ namespace OpenSim.Framework.Monitoring
return userStats;
}
+
+ public static bool RegisterStat(Stat stat)
+ {
+ lock (RegisteredStats)
+ {
+ if (RegisteredStats.ContainsKey(stat.UniqueName))
+ {
+ // XXX: For now just return false. This is to avoid problems in regression tests where all tests
+ // in a class are run in the same instance of the VM.
+ return false;
+
+// throw new Exception(
+// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category);
+ }
+
+ // We take a replace-on-write approach here so that we don't need to generate a new Dictionary
+ Dictionary newRegisteredStats = new Dictionary(RegisteredStats);
+ newRegisteredStats[stat.UniqueName] = stat;
+ RegisteredStats = newRegisteredStats;
+ }
+
+ return true;
+ }
+
+ public static bool DeregisterStat(Stat stat)
+ {
+ lock (RegisteredStats)
+ {
+ if (!RegisteredStats.ContainsKey(stat.UniqueName))
+ return false;
+
+ Dictionary newRegisteredStats = new Dictionary(RegisteredStats);
+ newRegisteredStats.Remove(stat.UniqueName);
+ RegisteredStats = newRegisteredStats;
+
+ return true;
+ }
+ }
+ }
+
+ ///
+ /// Verbosity of stat.
+ ///
+ ///
+ /// Info will always be displayed.
+ ///
+ public enum StatVerbosity
+ {
+ Debug,
+ Info
+ }
+
+ ///
+ /// Holds individual static details
+ ///
+ public class Stat
+ {
+ ///
+ /// Unique stat name used for indexing. Each ShortName in a Category must be unique.
+ ///
+ public string UniqueName { get; private set; }
+
+ ///
+ /// Category of this stat (e.g. cache, scene, etc).
+ ///
+ public string Category { get; private set; }
+
+ ///
+ /// Containing name for this stat.
+ /// FIXME: In the case of a scene, this is currently the scene name (though this leaves
+ /// us with a to-be-resolved problem of non-unique region names).
+ ///
+ ///
+ /// The container.
+ ///
+ public string Container { get; private set; }
+
+ public StatVerbosity Verbosity { get; private set; }
+ public string ShortName { get; private set; }
+ public string Name { get; private set; }
+ public string Description { get; private set; }
+ public string UnitName { get; private set; }
+
+ public double Value { get; set; }
+
+ public Stat(
+ string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
+ {
+ ShortName = shortName;
+ Name = name;
+ UnitName = unitName;
+ Category = category;
+ Container = container;
+ Verbosity = verbosity;
+ Description = description;
+
+ UniqueName = GenUniqueName(Container, Category, ShortName);
+ }
+
+ public static string GenUniqueName(string container, string category, string shortName)
+ {
+ return string.Format("{0}+{1}+{2}", container, category, shortName);
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 3d36a6d55cb0bba408f5447d4596c12564366030 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 4 Oct 2012 01:27:40 +0100
Subject: Add generic PercentageStat.
Not yet used.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 35 ++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 02df0ac..b5dc24f 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -153,9 +153,9 @@ namespace OpenSim.Framework.Monitoring
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
- public string UnitName { get; private set; }
+ public virtual string UnitName { get; private set; }
- public double Value { get; set; }
+ public virtual double Value { get; set; }
public Stat(
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
@@ -176,4 +176,35 @@ namespace OpenSim.Framework.Monitoring
return string.Format("{0}+{1}+{2}", container, category, shortName);
}
}
+
+ public class PercentageStat : Stat
+ {
+ public int Antecedent { get; set; }
+ public int Consequent { get; set; }
+
+ public override double Value
+ {
+ get
+ {
+ int c = Consequent;
+
+ // Avoid any chance of a multi-threaded divide-by-zero
+ if (c == 0)
+ return 0;
+
+ return (double)Antecedent / c;
+ }
+
+ set
+ {
+ throw new Exception("Cannot set value on a PercentageStat");
+ }
+ }
+
+ public PercentageStat(
+ string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
+ : base(shortName, name, " %", category, container, verbosity, description)
+ {
+ }
+ }
}
\ No newline at end of file
--
cgit v1.1
From 1f2472d0fcd86a7ae09c01ecb3508eab001ce033 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Oct 2012 23:28:53 +0100
Subject: Extend "show stats" command to "show stats [list|all|]"
This allows different categories of stats to be shown, with options to list categories or show all stats.
Currently categories are scene and simulator and only a very few stats are currently registered via this mechanism.
This commit also adds percentage stats for packets and blocks reused from the packet pool.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 193 ++++++++++++++++++++++++---
1 file changed, 174 insertions(+), 19 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index b5dc24f..a67c5f8 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using OpenSim.Framework.Console;
namespace OpenSim.Framework.Monitoring
{
@@ -35,13 +36,23 @@ namespace OpenSim.Framework.Monitoring
///
public class StatsManager
{
+ // Subcommand used to list other stats.
+ public const string AllSubCommand = "all";
+
+ // Subcommand used to list other stats.
+ public const string ListSubCommand = "list";
+
+ // All subcommands
+ public static HashSet SubCommands = new HashSet { AllSubCommand, ListSubCommand };
+
///
- /// Registered stats.
+ /// Registered stats categorized by category/container/shortname
///
///
- /// Do not add or remove from this dictionary.
+ /// Do not add or remove directly from this dictionary.
///
- public static Dictionary RegisteredStats = new Dictionary();
+ public static Dictionary>> RegisteredStats
+ = new Dictionary>>();
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
@@ -51,6 +62,76 @@ namespace OpenSim.Framework.Monitoring
public static UserStatsCollector UserStats { get { return userStats; } }
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
+ public static void RegisterConsoleCommands(CommandConsole console)
+ {
+ console.Commands.AddCommand(
+ "General",
+ false,
+ "show stats",
+ "show stats [list|all|]",
+ "Show statistical information for this server",
+ "If no final argument is specified then legacy statistics information is currently shown.\n"
+ + "If list is specified then statistic categories are shown.\n"
+ + "If all is specified then all registered statistics are shown.\n"
+ + "If a category name is specified then only statistics from that category are shown.\n"
+ + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
+ HandleShowStatsCommand);
+ }
+
+ public static void HandleShowStatsCommand(string module, string[] cmd)
+ {
+ ICommandConsole con = MainConsole.Instance;
+
+ if (cmd.Length > 2)
+ {
+ var categoryName = cmd[2];
+
+ if (categoryName == AllSubCommand)
+ {
+ foreach (var category in RegisteredStats.Values)
+ {
+ OutputCategoryStatsToConsole(con, category);
+ }
+ }
+ else if (categoryName == ListSubCommand)
+ {
+ con.Output("Statistic categories available are:");
+ foreach (string category in RegisteredStats.Keys)
+ con.OutputFormat(" {0}", category);
+ }
+ else
+ {
+ Dictionary> category;
+ if (!RegisteredStats.TryGetValue(categoryName, out category))
+ {
+ con.OutputFormat("No such category as {0}", categoryName);
+ }
+ else
+ {
+ OutputCategoryStatsToConsole(con, category);
+ }
+ }
+ }
+ else
+ {
+ // Legacy
+ con.Output(SimExtraStats.Report());
+ }
+ }
+
+ private static void OutputCategoryStatsToConsole(
+ ICommandConsole con, Dictionary> category)
+ {
+ foreach (var container in category.Values)
+ {
+ foreach (Stat stat in container.Values)
+ {
+ con.OutputFormat(
+ "{0}.{1}.{2} : {3}{4}", stat.Category, stat.Container, stat.ShortName, stat.Value, stat.UnitName);
+ }
+ }
+ }
+
///
/// Start collecting statistics related to assets.
/// Should only be called once.
@@ -73,43 +154,100 @@ namespace OpenSim.Framework.Monitoring
return userStats;
}
+ ///
+ /// Registers a statistic.
+ ///
+ ///
+ ///
public static bool RegisterStat(Stat stat)
{
+ Dictionary> category = null, newCategory;
+ Dictionary container = null, newContainer;
+
lock (RegisteredStats)
{
- if (RegisteredStats.ContainsKey(stat.UniqueName))
- {
- // XXX: For now just return false. This is to avoid problems in regression tests where all tests
- // in a class are run in the same instance of the VM.
+ // Stat name is not unique across category/container/shortname key.
+ // XXX: For now just return false. This is to avoid problems in regression tests where all tests
+ // in a class are run in the same instance of the VM.
+ if (TryGetStat(stat, out category, out container))
return false;
-// throw new Exception(
-// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category);
- }
+ // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
+ // This means that we don't need to lock or copy them on iteration, which will be a much more
+ // common operation after startup.
+ if (container != null)
+ newContainer = new Dictionary(container);
+ else
+ newContainer = new Dictionary();
+
+ if (category != null)
+ newCategory = new Dictionary>(category);
+ else
+ newCategory = new Dictionary>();
- // We take a replace-on-write approach here so that we don't need to generate a new Dictionary
- Dictionary newRegisteredStats = new Dictionary(RegisteredStats);
- newRegisteredStats[stat.UniqueName] = stat;
- RegisteredStats = newRegisteredStats;
+ newContainer[stat.ShortName] = stat;
+ newCategory[stat.Container] = newContainer;
+ RegisteredStats[stat.Category] = newCategory;
}
return true;
}
+ ///
+ /// Deregister a statistic
+ /// >
+ ///
+ /// > category = null, newCategory;
+ Dictionary container = null, newContainer;
+
lock (RegisteredStats)
{
- if (!RegisteredStats.ContainsKey(stat.UniqueName))
+ if (!TryGetStat(stat, out category, out container))
return false;
- Dictionary newRegisteredStats = new Dictionary(RegisteredStats);
- newRegisteredStats.Remove(stat.UniqueName);
- RegisteredStats = newRegisteredStats;
+ newContainer = new Dictionary(container);
+ newContainer.Remove(stat.UniqueName);
+
+ newCategory = new Dictionary>(category);
+ newCategory.Remove(stat.Container);
+
+ newCategory[stat.Container] = newContainer;
+ RegisteredStats[stat.Category] = newCategory;
return true;
}
}
+
+ public static bool TryGetStats(string category, out Dictionary> stats)
+ {
+ return RegisteredStats.TryGetValue(category, out stats);
+ }
+
+ public static bool TryGetStat(
+ Stat stat,
+ out Dictionary> category,
+ out Dictionary container)
+ {
+ category = null;
+ container = null;
+
+ lock (RegisteredStats)
+ {
+ if (RegisteredStats.TryGetValue(stat.Category, out category))
+ {
+ if (category.TryGetValue(stat.Container, out container))
+ {
+ if (container.ContainsKey(stat.ShortName))
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
///
@@ -157,9 +295,26 @@ namespace OpenSim.Framework.Monitoring
public virtual double Value { get; set; }
+ ///
+ /// Constructor
+ ///
+ /// Short name for the stat. Must not contain spaces. e.g. "LongFrames"
+ /// Human readable name for the stat. e.g. "Long frames"
+ ///
+ /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
+ /// e.g. " frames"
+ ///
+ /// Category under which this stat should appear, e.g. "scene". Do not capitalize.
+ /// Entity to which this stat relates. e.g. scene name if this is a per scene stat.
+ /// Verbosity of stat. Controls whether it will appear in short stat display or only full display.
+ /// Description of stat
public Stat(
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
{
+ if (StatsManager.SubCommands.Contains(category))
+ throw new Exception(
+ string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
+
ShortName = shortName;
Name = name;
UnitName = unitName;
@@ -203,7 +358,7 @@ namespace OpenSim.Framework.Monitoring
public PercentageStat(
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
- : base(shortName, name, " %", category, container, verbosity, description)
+ : base(shortName, name, "%", category, container, verbosity, description)
{
}
}
--
cgit v1.1
From 2e9ef015f7b73a3942011a36a9f94ce59d848dc0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Oct 2012 23:58:37 +0100
Subject: Fix packetpool for ImprovedTerseObjectUpdate packets.
These were neither being returned or in many places reused.
Getting packets from a pool rather than deallocating and reallocating reduces memory churn which in turn reduces garbage collection time and frequency.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index a67c5f8..d365190 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -126,8 +126,7 @@ namespace OpenSim.Framework.Monitoring
{
foreach (Stat stat in container.Values)
{
- con.OutputFormat(
- "{0}.{1}.{2} : {3}{4}", stat.Category, stat.Container, stat.ShortName, stat.Value, stat.UnitName);
+ con.Output(stat.ToConsoleString());
}
}
}
@@ -330,6 +329,12 @@ namespace OpenSim.Framework.Monitoring
{
return string.Format("{0}+{1}+{2}", container, category, shortName);
}
+
+ public virtual string ToConsoleString()
+ {
+ return string.Format(
+ "{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
+ }
}
public class PercentageStat : Stat
@@ -358,8 +363,13 @@ namespace OpenSim.Framework.Monitoring
public PercentageStat(
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
- : base(shortName, name, "%", category, container, verbosity, description)
+ : base(shortName, name, "%", category, container, verbosity, description) {}
+
+ public override string ToConsoleString()
{
+ return string.Format(
+ "{0}.{1}.{2} : {3:0.###}{4} ({5}/{6})",
+ Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
}
}
}
\ No newline at end of file
--
cgit v1.1
From 387ce8ef35e7084895524507d6bba987b8c4a5d0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 00:10:51 +0100
Subject: Fix build break by moving OpenSim.Framework.Console back below
HttpServer in the build order.
Luckily, it turns out Framework.Monitoring doesn't need to reference Console directly.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index d365190..d7aff03 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,7 +27,6 @@
using System;
using System.Collections.Generic;
-using OpenSim.Framework.Console;
namespace OpenSim.Framework.Monitoring
{
@@ -62,7 +61,7 @@ namespace OpenSim.Framework.Monitoring
public static UserStatsCollector UserStats { get { return userStats; } }
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
- public static void RegisterConsoleCommands(CommandConsole console)
+ public static void RegisterConsoleCommands(ICommandConsole console)
{
console.Commands.AddCommand(
"General",
--
cgit v1.1
From 59a17ad676326d5affc2e221ef9c02166a85c6fd Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 00:26:15 +0100
Subject: Fix percentage stats to multiply by 100. Adjust container name for
packetpool stats.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index d7aff03..31989e5 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -351,7 +351,7 @@ namespace OpenSim.Framework.Monitoring
if (c == 0)
return 0;
- return (double)Antecedent / c;
+ return (double)Antecedent / c * 100;
}
set
@@ -367,7 +367,7 @@ namespace OpenSim.Framework.Monitoring
public override string ToConsoleString()
{
return string.Format(
- "{0}.{1}.{2} : {3:0.###}{4} ({5}/{6})",
+ "{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
}
}
--
cgit v1.1
From 4578ff74fec7500902f58fbdee6ce5a6b39601fb Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 23 Oct 2012 01:50:05 +0100
Subject: Add object count stats for new IncomingPacket and UDPPacketBuffer
pools if they are enabled. Add count stats for existing LLUDP pool.
This introduces a pull stat type in addition to the push stat type.
A pull stat takes a method on construction which knows how to update the stat on request.
In this way, special interfaces for pull stat collection are not necessary.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 75 +++++++++++++++++++++++++---
1 file changed, 69 insertions(+), 6 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 31989e5..116b2c0 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -249,6 +249,19 @@ namespace OpenSim.Framework.Monitoring
}
///
+ /// Stat type.
+ ///
+ ///
+ /// A push stat is one which is continually updated and so it's value can simply by read.
+ /// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated.
+ ///
+ public enum StatType
+ {
+ Push,
+ Pull
+ }
+
+ ///
/// Verbosity of stat.
///
///
@@ -285,29 +298,65 @@ namespace OpenSim.Framework.Monitoring
///
public string Container { get; private set; }
+ public StatType StatType { get; private set; }
+
+ ///
+ /// Action used to update this stat when the value is requested if it's a pull type.
+ ///
+ public Action PullAction { get; private set; }
+
public StatVerbosity Verbosity { get; private set; }
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public virtual string UnitName { get; private set; }
- public virtual double Value { get; set; }
+ public virtual double Value
+ {
+ get
+ {
+ // Asking for an update here means that the updater cannot access this value without infinite recursion.
+ // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
+ // called by the pull action and just return the value.
+ if (StatType == StatType.Pull)
+ PullAction(this);
+
+ return m_value;
+ }
+
+ set
+ {
+ m_value = value;
+ }
+ }
+
+ private double m_value;
///
/// Constructor
///
/// Short name for the stat. Must not contain spaces. e.g. "LongFrames"
/// Human readable name for the stat. e.g. "Long frames"
+ /// Description of stat
///
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
/// e.g. " frames"
///
/// Category under which this stat should appear, e.g. "scene". Do not capitalize.
/// Entity to which this stat relates. e.g. scene name if this is a per scene stat.
+ /// Push or pull
+ /// Pull stats need an action to update the stat on request. Push stats should set null here.
/// Verbosity of stat. Controls whether it will appear in short stat display or only full display.
- /// Description of stat
public Stat(
- string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
+ string shortName,
+ string name,
+ string description,
+ string unitName,
+ string category,
+ string container,
+ StatType type,
+ Action pullAction,
+ StatVerbosity verbosity)
{
if (StatsManager.SubCommands.Contains(category))
throw new Exception(
@@ -315,11 +364,18 @@ namespace OpenSim.Framework.Monitoring
ShortName = shortName;
Name = name;
+ Description = description;
UnitName = unitName;
Category = category;
Container = container;
+ StatType = type;
+
+ if (StatType == StatType.Push && pullAction != null)
+ throw new Exception("A push stat cannot have a pull action");
+ else
+ PullAction = pullAction;
+
Verbosity = verbosity;
- Description = description;
UniqueName = GenUniqueName(Container, Category, ShortName);
}
@@ -361,8 +417,15 @@ namespace OpenSim.Framework.Monitoring
}
public PercentageStat(
- string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
- : base(shortName, name, "%", category, container, verbosity, description) {}
+ string shortName,
+ string name,
+ string description,
+ string category,
+ string container,
+ StatType type,
+ Action pullAction,
+ StatVerbosity verbosity)
+ : base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
public override string ToConsoleString()
{
--
cgit v1.1
From 319ebaca06db3d4a38beff74725d321b7c836157 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 23 Oct 2012 02:44:15 +0100
Subject: Make it possible to turn the base UDP object packet pools on and off
whilst running via the "debug lludp pool " console command. For
debug purposes.
This does not currently apply to the higher LLUDP packetpool.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 116b2c0..4844336 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Framework.Monitoring
return false;
newContainer = new Dictionary(container);
- newContainer.Remove(stat.UniqueName);
+ newContainer.Remove(stat.ShortName);
newCategory = new Dictionary>(category);
newCategory.Remove(stat.Container);
@@ -279,11 +279,6 @@ namespace OpenSim.Framework.Monitoring
public class Stat
{
///
- /// Unique stat name used for indexing. Each ShortName in a Category must be unique.
- ///
- public string UniqueName { get; private set; }
-
- ///
/// Category of this stat (e.g. cache, scene, etc).
///
public string Category { get; private set; }
@@ -376,13 +371,6 @@ namespace OpenSim.Framework.Monitoring
PullAction = pullAction;
Verbosity = verbosity;
-
- UniqueName = GenUniqueName(Container, Category, ShortName);
- }
-
- public static string GenUniqueName(string container, string category, string shortName)
- {
- return string.Format("{0}+{1}+{2}", container, category, shortName);
}
public virtual string ToConsoleString()
--
cgit v1.1
From 038528dc80e0fe03956d61872ba30a887b2890a1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Nov 2012 02:02:59 +0000
Subject: Make PacketPool class stats pull stats instead of push stats so they
can be lifted up into LLUDPServer and be distiguished by scene name
---
OpenSim/Framework/Monitoring/StatsManager.cs | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 4844336..cebe905 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -382,14 +382,20 @@ namespace OpenSim.Framework.Monitoring
public class PercentageStat : Stat
{
- public int Antecedent { get; set; }
- public int Consequent { get; set; }
+ public long Antecedent { get; set; }
+ public long Consequent { get; set; }
public override double Value
{
get
{
- int c = Consequent;
+ // Asking for an update here means that the updater cannot access this value without infinite recursion.
+ // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
+ // called by the pull action and just return the value.
+ if (StatType == StatType.Pull)
+ PullAction(this);
+
+ long c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
@@ -400,7 +406,7 @@ namespace OpenSim.Framework.Monitoring
set
{
- throw new Exception("Cannot set value on a PercentageStat");
+ throw new InvalidOperationException("Cannot set value on a PercentageStat");
}
}
--
cgit v1.1
From cd088757e96217defc9a2b0bf323747615c3255e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 16 Nov 2012 04:36:22 +0000
Subject: Add a first draft mechanism for the IncomingPacketsProcessedStat to
show the delta over time.
The chief motivation for this is to be able to tell whether there's any impact on incoming packet processing from enabling extra packet pooling.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 139 ++++++++++++++++++++++++++-
1 file changed, 136 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index cebe905..eae7505 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Text;
namespace OpenSim.Framework.Monitoring
{
@@ -246,6 +247,24 @@ namespace OpenSim.Framework.Monitoring
return false;
}
+
+ public static void RecordStats()
+ {
+ lock (RegisteredStats)
+ {
+ foreach (Dictionary> category in RegisteredStats.Values)
+ {
+ foreach (Dictionary container in category.Values)
+ {
+ foreach (Stat stat in container.Values)
+ {
+ if (stat.MeasuresOfInterest != MeasuresOfInterest.None)
+ stat.RecordValue();
+ }
+ }
+ }
+ }
+ }
}
///
@@ -262,6 +281,16 @@ namespace OpenSim.Framework.Monitoring
}
///
+ /// Measures of interest for this stat.
+ ///
+ [Flags]
+ public enum MeasuresOfInterest
+ {
+ None,
+ AverageChangeOverTime
+ }
+
+ ///
/// Verbosity of stat.
///
///
@@ -295,6 +324,8 @@ namespace OpenSim.Framework.Monitoring
public StatType StatType { get; private set; }
+ public MeasuresOfInterest MeasuresOfInterest { get; private set; }
+
///
/// Action used to update this stat when the value is requested if it's a pull type.
///
@@ -328,6 +359,47 @@ namespace OpenSim.Framework.Monitoring
private double m_value;
///
+ /// Historical samples for calculating measures of interest average.
+ ///
+ ///
+ /// Will be null if no measures of interest require samples.
+ ///
+ private static Queue m_samples;
+
+ ///
+ /// Maximum number of statistical samples.
+ ///
+ ///
+ /// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
+ /// the main Watchdog.
+ ///
+ private static int m_maxSamples = 24;
+
+ public Stat(
+ string shortName,
+ string name,
+ string description,
+ string unitName,
+ string category,
+ string container,
+ StatType type,
+ Action pullAction,
+ StatVerbosity verbosity)
+ : this(
+ shortName,
+ name,
+ description,
+ unitName,
+ category,
+ container,
+ type,
+ MeasuresOfInterest.None,
+ pullAction,
+ verbosity)
+ {
+ }
+
+ ///
/// Constructor
///
/// Short name for the stat. Must not contain spaces. e.g. "LongFrames"
@@ -341,6 +413,7 @@ namespace OpenSim.Framework.Monitoring
/// Entity to which this stat relates. e.g. scene name if this is a per scene stat.
/// Push or pull
/// Pull stats need an action to update the stat on request. Push stats should set null here.
+ /// Measures of interest
/// Verbosity of stat. Controls whether it will appear in short stat display or only full display.
public Stat(
string shortName,
@@ -350,6 +423,7 @@ namespace OpenSim.Framework.Monitoring
string category,
string container,
StatType type,
+ MeasuresOfInterest moi,
Action pullAction,
StatVerbosity verbosity)
{
@@ -370,13 +444,66 @@ namespace OpenSim.Framework.Monitoring
else
PullAction = pullAction;
+ MeasuresOfInterest = moi;
+
+ if ((moi & MeasuresOfInterest.AverageChangeOverTime) == MeasuresOfInterest.AverageChangeOverTime)
+ m_samples = new Queue(m_maxSamples);
+
Verbosity = verbosity;
}
+ ///
+ /// Record a value in the sample set.
+ ///
+ ///
+ /// Do not call this if MeasuresOfInterest.None
+ ///
+ public void RecordValue()
+ {
+ double newValue = Value;
+
+ lock (m_samples)
+ {
+ if (m_samples.Count >= m_maxSamples)
+ m_samples.Dequeue();
+
+ m_samples.Enqueue(newValue);
+ }
+ }
+
public virtual string ToConsoleString()
{
- return string.Format(
- "{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
+
+ AppendMeasuresOfInterest(sb);
+
+ return sb.ToString();
+ }
+
+ protected void AppendMeasuresOfInterest(StringBuilder sb)
+ {
+ if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime)
+ == MeasuresOfInterest.AverageChangeOverTime)
+ {
+ double totalChange = 0;
+ double? lastSample = null;
+
+ lock (m_samples)
+ {
+ foreach (double s in m_samples)
+ {
+ if (lastSample != null)
+ totalChange += s - (double)lastSample;
+
+ lastSample = s;
+ }
+ }
+
+ int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1;
+
+ sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName);
+ }
}
}
@@ -423,9 +550,15 @@ namespace OpenSim.Framework.Monitoring
public override string ToConsoleString()
{
- return string.Format(
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendFormat(
"{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
+
+ AppendMeasuresOfInterest(sb);
+
+ return sb.ToString();
}
}
}
\ No newline at end of file
--
cgit v1.1
From 55f889cc66d78268c530c65a5fd111395cc26dc5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 16 Nov 2012 05:02:06 +0000
Subject: refactor: Move stat classes out of StatManager and into their own
files for clarity.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 260 ---------------------------
1 file changed, 260 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index eae7505..0762b01 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -301,264 +301,4 @@ namespace OpenSim.Framework.Monitoring
Debug,
Info
}
-
- ///
- /// Holds individual static details
- ///
- public class Stat
- {
- ///
- /// Category of this stat (e.g. cache, scene, etc).
- ///
- public string Category { get; private set; }
-
- ///
- /// Containing name for this stat.
- /// FIXME: In the case of a scene, this is currently the scene name (though this leaves
- /// us with a to-be-resolved problem of non-unique region names).
- ///
- ///
- /// The container.
- ///
- public string Container { get; private set; }
-
- public StatType StatType { get; private set; }
-
- public MeasuresOfInterest MeasuresOfInterest { get; private set; }
-
- ///
- /// Action used to update this stat when the value is requested if it's a pull type.
- ///
- public Action PullAction { get; private set; }
-
- public StatVerbosity Verbosity { get; private set; }
- public string ShortName { get; private set; }
- public string Name { get; private set; }
- public string Description { get; private set; }
- public virtual string UnitName { get; private set; }
-
- public virtual double Value
- {
- get
- {
- // Asking for an update here means that the updater cannot access this value without infinite recursion.
- // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
- // called by the pull action and just return the value.
- if (StatType == StatType.Pull)
- PullAction(this);
-
- return m_value;
- }
-
- set
- {
- m_value = value;
- }
- }
-
- private double m_value;
-
- ///
- /// Historical samples for calculating measures of interest average.
- ///
- ///
- /// Will be null if no measures of interest require samples.
- ///
- private static Queue m_samples;
-
- ///
- /// Maximum number of statistical samples.
- ///
- ///
- /// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
- /// the main Watchdog.
- ///
- private static int m_maxSamples = 24;
-
- public Stat(
- string shortName,
- string name,
- string description,
- string unitName,
- string category,
- string container,
- StatType type,
- Action pullAction,
- StatVerbosity verbosity)
- : this(
- shortName,
- name,
- description,
- unitName,
- category,
- container,
- type,
- MeasuresOfInterest.None,
- pullAction,
- verbosity)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Short name for the stat. Must not contain spaces. e.g. "LongFrames"
- /// Human readable name for the stat. e.g. "Long frames"
- /// Description of stat
- ///
- /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
- /// e.g. " frames"
- ///
- /// Category under which this stat should appear, e.g. "scene". Do not capitalize.
- /// Entity to which this stat relates. e.g. scene name if this is a per scene stat.
- /// Push or pull
- /// Pull stats need an action to update the stat on request. Push stats should set null here.
- /// Measures of interest
- /// Verbosity of stat. Controls whether it will appear in short stat display or only full display.
- public Stat(
- string shortName,
- string name,
- string description,
- string unitName,
- string category,
- string container,
- StatType type,
- MeasuresOfInterest moi,
- Action pullAction,
- StatVerbosity verbosity)
- {
- if (StatsManager.SubCommands.Contains(category))
- throw new Exception(
- string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
-
- ShortName = shortName;
- Name = name;
- Description = description;
- UnitName = unitName;
- Category = category;
- Container = container;
- StatType = type;
-
- if (StatType == StatType.Push && pullAction != null)
- throw new Exception("A push stat cannot have a pull action");
- else
- PullAction = pullAction;
-
- MeasuresOfInterest = moi;
-
- if ((moi & MeasuresOfInterest.AverageChangeOverTime) == MeasuresOfInterest.AverageChangeOverTime)
- m_samples = new Queue(m_maxSamples);
-
- Verbosity = verbosity;
- }
-
- ///
- /// Record a value in the sample set.
- ///
- ///
- /// Do not call this if MeasuresOfInterest.None
- ///
- public void RecordValue()
- {
- double newValue = Value;
-
- lock (m_samples)
- {
- if (m_samples.Count >= m_maxSamples)
- m_samples.Dequeue();
-
- m_samples.Enqueue(newValue);
- }
- }
-
- public virtual string ToConsoleString()
- {
- StringBuilder sb = new StringBuilder();
- sb.AppendFormat("{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
-
- AppendMeasuresOfInterest(sb);
-
- return sb.ToString();
- }
-
- protected void AppendMeasuresOfInterest(StringBuilder sb)
- {
- if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime)
- == MeasuresOfInterest.AverageChangeOverTime)
- {
- double totalChange = 0;
- double? lastSample = null;
-
- lock (m_samples)
- {
- foreach (double s in m_samples)
- {
- if (lastSample != null)
- totalChange += s - (double)lastSample;
-
- lastSample = s;
- }
- }
-
- int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1;
-
- sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName);
- }
- }
- }
-
- public class PercentageStat : Stat
- {
- public long Antecedent { get; set; }
- public long Consequent { get; set; }
-
- public override double Value
- {
- get
- {
- // Asking for an update here means that the updater cannot access this value without infinite recursion.
- // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
- // called by the pull action and just return the value.
- if (StatType == StatType.Pull)
- PullAction(this);
-
- long c = Consequent;
-
- // Avoid any chance of a multi-threaded divide-by-zero
- if (c == 0)
- return 0;
-
- return (double)Antecedent / c * 100;
- }
-
- set
- {
- throw new InvalidOperationException("Cannot set value on a PercentageStat");
- }
- }
-
- public PercentageStat(
- string shortName,
- string name,
- string description,
- string category,
- string container,
- StatType type,
- Action pullAction,
- StatVerbosity verbosity)
- : base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
-
- public override string ToConsoleString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.AppendFormat(
- "{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
- Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
-
- AppendMeasuresOfInterest(sb);
-
- return sb.ToString();
- }
- }
}
\ No newline at end of file
--
cgit v1.1
From afeb5d4917506ced2a1e4098aeb4bc94ae64fc06 Mon Sep 17 00:00:00 2001
From: Dan Lake
Date: Thu, 14 Feb 2013 20:05:42 -0800
Subject: Use SortedDictionary in StatsManager instead of regular Dictionary so
stats will interate and print in a defined order
---
OpenSim/Framework/Monitoring/StatsManager.cs | 40 ++++++++++++++--------------
1 file changed, 20 insertions(+), 20 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 0762b01..910907e 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -51,8 +51,8 @@ namespace OpenSim.Framework.Monitoring
///
/// Do not add or remove directly from this dictionary.
///
- public static Dictionary>> RegisteredStats
- = new Dictionary>>();
+ public static SortedDictionary>> RegisteredStats
+ = new SortedDictionary>>();
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
@@ -101,7 +101,7 @@ namespace OpenSim.Framework.Monitoring
}
else
{
- Dictionary> category;
+ SortedDictionary> category;
if (!RegisteredStats.TryGetValue(categoryName, out category))
{
con.OutputFormat("No such category as {0}", categoryName);
@@ -120,7 +120,7 @@ namespace OpenSim.Framework.Monitoring
}
private static void OutputCategoryStatsToConsole(
- ICommandConsole con, Dictionary> category)
+ ICommandConsole con, SortedDictionary> category)
{
foreach (var container in category.Values)
{
@@ -160,8 +160,8 @@ namespace OpenSim.Framework.Monitoring
///
public static bool RegisterStat(Stat stat)
{
- Dictionary> category = null, newCategory;
- Dictionary container = null, newContainer;
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
lock (RegisteredStats)
{
@@ -175,14 +175,14 @@ namespace OpenSim.Framework.Monitoring
// This means that we don't need to lock or copy them on iteration, which will be a much more
// common operation after startup.
if (container != null)
- newContainer = new Dictionary(container);
+ newContainer = new SortedDictionary(container);
else
- newContainer = new Dictionary();
+ newContainer = new SortedDictionary();
if (category != null)
- newCategory = new Dictionary>(category);
+ newCategory = new SortedDictionary>(category);
else
- newCategory = new Dictionary>();
+ newCategory = new SortedDictionary>();
newContainer[stat.ShortName] = stat;
newCategory[stat.Container] = newContainer;
@@ -196,21 +196,21 @@ namespace OpenSim.Framework.Monitoring
/// Deregister a statistic
/// >
///
- ///
public static bool DeregisterStat(Stat stat)
{
- Dictionary> category = null, newCategory;
- Dictionary container = null, newContainer;
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
lock (RegisteredStats)
{
if (!TryGetStat(stat, out category, out container))
return false;
- newContainer = new Dictionary(container);
+ newContainer = new SortedDictionary(container);
newContainer.Remove(stat.ShortName);
- newCategory = new Dictionary>(category);
+ newCategory = new SortedDictionary>(category);
newCategory.Remove(stat.Container);
newCategory[stat.Container] = newContainer;
@@ -220,15 +220,15 @@ namespace OpenSim.Framework.Monitoring
}
}
- public static bool TryGetStats(string category, out Dictionary> stats)
+ public static bool TryGetStats(string category, out SortedDictionary> stats)
{
return RegisteredStats.TryGetValue(category, out stats);
}
public static bool TryGetStat(
Stat stat,
- out Dictionary> category,
- out Dictionary container)
+ out SortedDictionary> category,
+ out SortedDictionary container)
{
category = null;
container = null;
@@ -252,9 +252,9 @@ namespace OpenSim.Framework.Monitoring
{
lock (RegisteredStats)
{
- foreach (Dictionary> category in RegisteredStats.Values)
+ foreach (SortedDictionary> category in RegisteredStats.Values)
{
- foreach (Dictionary container in category.Values)
+ foreach (SortedDictionary container in category.Values)
{
foreach (Stat stat in container.Values)
{
--
cgit v1.1
From ee8d726ec5cbcbaca8aebbcbfd25cfba963c43f8 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sat, 23 Feb 2013 17:04:19 -0800
Subject: Modify StatsManager so console command "show stats category
container" only outputs the statistics in the specified container in the
category.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 29 +++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 910907e..24db6d4 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -85,6 +85,7 @@ namespace OpenSim.Framework.Monitoring
if (cmd.Length > 2)
{
var categoryName = cmd[2];
+ var containerName = cmd.Length > 3 ? cmd[3] : String.Empty;
if (categoryName == AllSubCommand)
{
@@ -108,7 +109,20 @@ namespace OpenSim.Framework.Monitoring
}
else
{
- OutputCategoryStatsToConsole(con, category);
+ if (String.IsNullOrEmpty(containerName))
+ OutputCategoryStatsToConsole(con, category);
+ else
+ {
+ SortedDictionary container;
+ if (category.TryGetValue(containerName, out container))
+ {
+ OutputContainerStatsToConsole(con, container);
+ }
+ else
+ {
+ con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+ }
+ }
}
}
}
@@ -124,10 +138,15 @@ namespace OpenSim.Framework.Monitoring
{
foreach (var container in category.Values)
{
- foreach (Stat stat in container.Values)
- {
- con.Output(stat.ToConsoleString());
- }
+ OutputContainerStatsToConsole(con, container);
+ }
+ }
+
+ private static void OutputContainerStatsToConsole( ICommandConsole con, SortedDictionary container)
+ {
+ foreach (Stat stat in container.Values)
+ {
+ con.Output(stat.ToConsoleString());
}
}
--
cgit v1.1
From 0d2fd0d914581f755661455b8db2b9e399154632 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 17 Jun 2013 22:39:00 +0100
Subject: Make general server stats available on the robust console as well as
the simulator console
This means the "show stats" command is now active on the robust console.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 72 +++++++++++++++-------------
1 file changed, 40 insertions(+), 32 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 24db6d4..3aee984 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -54,13 +54,13 @@ namespace OpenSim.Framework.Monitoring
public static SortedDictionary>> RegisteredStats
= new SortedDictionary>>();
- private static AssetStatsCollector assetStats;
- private static UserStatsCollector userStats;
- private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
+// private static AssetStatsCollector assetStats;
+// private static UserStatsCollector userStats;
+// private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
- public static AssetStatsCollector AssetStats { get { return assetStats; } }
- public static UserStatsCollector UserStats { get { return userStats; } }
- public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
+// public static AssetStatsCollector AssetStats { get { return assetStats; } }
+// public static UserStatsCollector UserStats { get { return userStats; } }
+ public static SimExtraStatsCollector SimExtraStats { get; set; }
public static void RegisterConsoleCommands(ICommandConsole console)
{
@@ -89,10 +89,7 @@ namespace OpenSim.Framework.Monitoring
if (categoryName == AllSubCommand)
{
- foreach (var category in RegisteredStats.Values)
- {
- OutputCategoryStatsToConsole(con, category);
- }
+ OutputAllStatsToConsole(con);
}
else if (categoryName == ListSubCommand)
{
@@ -129,7 +126,18 @@ namespace OpenSim.Framework.Monitoring
else
{
// Legacy
- con.Output(SimExtraStats.Report());
+ if (SimExtraStats != null)
+ con.Output(SimExtraStats.Report());
+ else
+ OutputAllStatsToConsole(con);
+ }
+ }
+
+ private static void OutputAllStatsToConsole(ICommandConsole con)
+ {
+ foreach (var category in RegisteredStats.Values)
+ {
+ OutputCategoryStatsToConsole(con, category);
}
}
@@ -150,27 +158,27 @@ namespace OpenSim.Framework.Monitoring
}
}
- ///
- /// Start collecting statistics related to assets.
- /// Should only be called once.
- ///
- public static AssetStatsCollector StartCollectingAssetStats()
- {
- assetStats = new AssetStatsCollector();
-
- return assetStats;
- }
-
- ///
- /// Start collecting statistics related to users.
- /// Should only be called once.
- ///
- public static UserStatsCollector StartCollectingUserStats()
- {
- userStats = new UserStatsCollector();
-
- return userStats;
- }
+// ///
+// /// Start collecting statistics related to assets.
+// /// Should only be called once.
+// ///
+// public static AssetStatsCollector StartCollectingAssetStats()
+// {
+// assetStats = new AssetStatsCollector();
+//
+// return assetStats;
+// }
+//
+// ///
+// /// Start collecting statistics related to users.
+// /// Should only be called once.
+// ///
+// public static UserStatsCollector StartCollectingUserStats()
+// {
+// userStats = new UserStatsCollector();
+//
+// return userStats;
+// }
///
/// Registers a statistic.
--
cgit v1.1
From 086fd70a5fdfd9b3a0e56201596f6d6bb20f391e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 20 Jun 2013 00:00:39 +0100
Subject: Make it possible to specify display of stats in a particular
'container' by separating category and container with a period.
e.g. "show stats server.network"
I failed to realize this had already been implemented without the period in the show stats command (as the command help had not been updated).
However, I would prefer the . approach as it will allow specifying multiple stats, easier wildcarding, etc.
This commit also prevents any stat from having a period in its short name.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 3aee984..af9f5ba 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -68,12 +68,13 @@ namespace OpenSim.Framework.Monitoring
"General",
false,
"show stats",
- "show stats [list|all|]",
+ "show stats [list|all|[.]",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
+ "If list is specified then statistic categories are shown.\n"
+ "If all is specified then all registered statistics are shown.\n"
+ "If a category name is specified then only statistics from that category are shown.\n"
+ + "If a category container is also specified then only statistics from that category in that container are shown.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
}
@@ -84,8 +85,11 @@ namespace OpenSim.Framework.Monitoring
if (cmd.Length > 2)
{
- var categoryName = cmd[2];
- var containerName = cmd.Length > 3 ? cmd[3] : String.Empty;
+ string name = cmd[2];
+ string[] components = name.Split('.');
+
+ string categoryName = components[0];
+ string containerName = components.Length > 1 ? components[1] : null;
if (categoryName == AllSubCommand)
{
@@ -107,7 +111,9 @@ namespace OpenSim.Framework.Monitoring
else
{
if (String.IsNullOrEmpty(containerName))
+ {
OutputCategoryStatsToConsole(con, category);
+ }
else
{
SortedDictionary container;
--
cgit v1.1
From 05790ba1cf7dd07f9f11ce248262041eb300ea49 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 20 Jun 2013 00:45:56 +0100
Subject: Allow more than one stat category to be specified in "show stats"
e.g. "show stats httpserver.9000 server.network"
---
OpenSim/Framework/Monitoring/StatsManager.cs | 64 +++++++++++++++-------------
1 file changed, 34 insertions(+), 30 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index af9f5ba..12d3a75 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
namespace OpenSim.Framework.Monitoring
@@ -68,13 +69,14 @@ namespace OpenSim.Framework.Monitoring
"General",
false,
"show stats",
- "show stats [list|all|[.]",
+ "show stats [list|all|([.])+",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
- + "If list is specified then statistic categories are shown.\n"
- + "If all is specified then all registered statistics are shown.\n"
- + "If a category name is specified then only statistics from that category are shown.\n"
- + "If a category container is also specified then only statistics from that category in that container are shown.\n"
+ + "'list' argument will show statistic categories.\n"
+ + "'all' will show all statistics.\n"
+ + "A name will show statistics from that category.\n"
+ + "A . name will show statistics from that category in that container.\n"
+ + "More than one name can be given separated by spaces.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
}
@@ -85,45 +87,47 @@ namespace OpenSim.Framework.Monitoring
if (cmd.Length > 2)
{
- string name = cmd[2];
- string[] components = name.Split('.');
+ foreach (string name in cmd.Skip(2))
+ {
+ string[] components = name.Split('.');
- string categoryName = components[0];
- string containerName = components.Length > 1 ? components[1] : null;
+ string categoryName = components[0];
+ string containerName = components.Length > 1 ? components[1] : null;
- if (categoryName == AllSubCommand)
- {
- OutputAllStatsToConsole(con);
- }
- else if (categoryName == ListSubCommand)
- {
- con.Output("Statistic categories available are:");
- foreach (string category in RegisteredStats.Keys)
- con.OutputFormat(" {0}", category);
- }
- else
- {
- SortedDictionary> category;
- if (!RegisteredStats.TryGetValue(categoryName, out category))
+ if (categoryName == AllSubCommand)
+ {
+ OutputAllStatsToConsole(con);
+ }
+ else if (categoryName == ListSubCommand)
{
- con.OutputFormat("No such category as {0}", categoryName);
+ con.Output("Statistic categories available are:");
+ foreach (string category in RegisteredStats.Keys)
+ con.OutputFormat(" {0}", category);
}
else
{
- if (String.IsNullOrEmpty(containerName))
+ SortedDictionary> category;
+ if (!RegisteredStats.TryGetValue(categoryName, out category))
{
- OutputCategoryStatsToConsole(con, category);
+ con.OutputFormat("No such category as {0}", categoryName);
}
else
{
- SortedDictionary container;
- if (category.TryGetValue(containerName, out container))
+ if (String.IsNullOrEmpty(containerName))
{
- OutputContainerStatsToConsole(con, container);
+ OutputCategoryStatsToConsole(con, category);
}
else
{
- con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+ SortedDictionary container;
+ if (category.TryGetValue(containerName, out container))
+ {
+ OutputContainerStatsToConsole(con, container);
+ }
+ else
+ {
+ con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
+ }
}
}
}
--
cgit v1.1
From fa02f28dbfef9b9dc3621f5bbd6b026c827459a5 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Fri, 12 Jul 2013 14:04:14 -0700
Subject: Add ToOSDMap() overrides to the Stat subclass CounterStat. Add a
GetStatsAsOSDMap method to StatsManager which allows the filtered fetching of
stats for eventual returning over the internets.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 66 ++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 12d3a75..a5b54c9 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -30,6 +30,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
+using OpenMetaverse.StructuredData;
+
namespace OpenSim.Framework.Monitoring
{
///
@@ -168,6 +170,70 @@ namespace OpenSim.Framework.Monitoring
}
}
+ // Creates an OSDMap of the format:
+ // { categoryName: {
+ // containerName: {
+ // statName: {
+ // "Name": name,
+ // "ShortName": shortName,
+ // ...
+ // },
+ // statName: {
+ // "Name": name,
+ // "ShortName": shortName,
+ // ...
+ // },
+ // ...
+ // },
+ // containerName: {
+ // ...
+ // },
+ // ...
+ // },
+ // categoryName: {
+ // ...
+ // },
+ // ...
+ // }
+ // The passed in parameters will filter the categories, containers and stats returned. If any of the
+ // parameters are either EmptyOrNull or the AllSubCommand value, all of that type will be returned.
+ // Case matters.
+ public static OSDMap GetStatsAsOSDMap(string pCategoryName, string pContainerName, string pStatName)
+ {
+ OSDMap map = new OSDMap();
+
+ foreach (string catName in RegisteredStats.Keys)
+ {
+ // Do this category if null spec, "all" subcommand or category name matches passed parameter.
+ // Skip category if none of the above.
+ if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName))
+ continue;
+
+ OSDMap contMap = new OSDMap();
+ foreach (string contName in RegisteredStats[catName].Keys)
+ {
+ if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName))
+ continue;
+
+ OSDMap statMap = new OSDMap();
+
+ SortedDictionary theStats = RegisteredStats[catName][contName];
+ foreach (string statName in theStats.Keys)
+ {
+ if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName))
+ continue;
+
+ statMap.Add(statName, theStats[statName].ToOSDMap());
+ }
+
+ contMap.Add(contName, statMap);
+ }
+ map.Add(catName, contMap);
+ }
+
+ return map;
+ }
+
// ///
// /// Start collecting statistics related to assets.
// /// Should only be called once.
--
cgit v1.1
From 8efe4bfc2ed7086e9fdf4812297e6525f955f6ac Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 29 Jul 2013 23:18:29 +0100
Subject: Make "abnormal thread terminations" into
"ClientLogoutsDueToNoReceives" and add this to the StatsManager
This reflects the actual use of this stat - it hasn't recorded general exceptions for some time.
Make the sim extra stats collector draw the data from the stats manager rather than maintaing this data itself.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 65 +++++++++++++++++++++++++---
1 file changed, 60 insertions(+), 5 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index a5b54c9..e6a2304 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -271,7 +271,7 @@ namespace OpenSim.Framework.Monitoring
// Stat name is not unique across category/container/shortname key.
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
// in a class are run in the same instance of the VM.
- if (TryGetStat(stat, out category, out container))
+ if (TryGetStatParents(stat, out category, out container))
return false;
// We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
@@ -307,7 +307,7 @@ namespace OpenSim.Framework.Monitoring
lock (RegisteredStats)
{
- if (!TryGetStat(stat, out category, out container))
+ if (!TryGetStatParents(stat, out category, out container))
return false;
newContainer = new SortedDictionary(container);
@@ -323,12 +323,67 @@ namespace OpenSim.Framework.Monitoring
}
}
- public static bool TryGetStats(string category, out SortedDictionary> stats)
+ public static bool TryGetStat(string category, string container, string statShortName, out Stat stat)
{
- return RegisteredStats.TryGetValue(category, out stats);
+ stat = null;
+ SortedDictionary> categoryStats;
+
+ lock (RegisteredStats)
+ {
+ if (!TryGetStatsForCategory(category, out categoryStats))
+ return false;
+
+ SortedDictionary containerStats;
+
+ if (!categoryStats.TryGetValue(container, out containerStats))
+ return false;
+
+ return containerStats.TryGetValue(statShortName, out stat);
+ }
+ }
+
+ public static bool TryGetStatsForCategory(
+ string category, out SortedDictionary> stats)
+ {
+ lock (RegisteredStats)
+ return RegisteredStats.TryGetValue(category, out stats);
+ }
+
+ ///
+ /// Get the same stat for each container in a given category.
+ ///
+ ///
+ /// The stats if there were any to fetch. Otherwise null.
+ ///
+ ///
+ ///
+ public static List GetStatsFromEachContainer(string category, string statShortName)
+ {
+ SortedDictionary> categoryStats;
+
+ lock (RegisteredStats)
+ {
+ if (!RegisteredStats.TryGetValue(category, out categoryStats))
+ return null;
+
+ List stats = null;
+
+ foreach (SortedDictionary containerStats in categoryStats.Values)
+ {
+ if (containerStats.ContainsKey(statShortName))
+ {
+ if (stats == null)
+ stats = new List();
+
+ stats.Add(containerStats[statShortName]);
+ }
+ }
+
+ return stats;
+ }
}
- public static bool TryGetStat(
+ public static bool TryGetStatParents(
Stat stat,
out SortedDictionary> category,
out SortedDictionary container)
--
cgit v1.1
From 76bd3de2fd243d0c910404af8a9998de746b04c4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 5 Aug 2013 19:22:47 +0100
Subject: Add checks monitoring framework to provide alerts if certain
conditions do not hold.
Not yet in use.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index e6a2304..87197f4 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -35,9 +35,9 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Monitoring
{
///
- /// Singleton used to provide access to statistics reporters
+ /// Static class used to register/deregister/fetch statistics
///
- public class StatsManager
+ public static class StatsManager
{
// Subcommand used to list other stats.
public const string AllSubCommand = "all";
@@ -257,7 +257,7 @@ namespace OpenSim.Framework.Monitoring
// }
///
- /// Registers a statistic.
+ /// Register a statistic.
///
///
///
--
cgit v1.1
From 4c2f6de8e4957df3c7186437089ba0925edb1a08 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 6 Aug 2013 18:29:33 +0100
Subject: Add the experimental ability to dump stats (result of command "show
stats all") to file OpenSimStats.log every 5 seconds.
This can currently only be activated with the console command "debug stats record start".
Off by default.
Records to file OpenSimStats.log for simulator and RobustStats.log for ROBUST
---
OpenSim/Framework/Monitoring/StatsManager.cs | 52 +++++++++++++++++++++-------
1 file changed, 40 insertions(+), 12 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 87197f4..c8e838c 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -81,6 +81,8 @@ namespace OpenSim.Framework.Monitoring
+ "More than one name can be given separated by spaces.\n"
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
+
+ StatsLogger.RegisterConsoleCommands(console);
}
public static void HandleShowStatsCommand(string module, string[] cmd)
@@ -145,29 +147,55 @@ namespace OpenSim.Framework.Monitoring
}
}
- private static void OutputAllStatsToConsole(ICommandConsole con)
+ public static List GetAllStatsReports()
{
+ List reports = new List();
+
foreach (var category in RegisteredStats.Values)
- {
- OutputCategoryStatsToConsole(con, category);
- }
+ reports.AddRange(GetCategoryStatsReports(category));
+
+ return reports;
+ }
+
+ private static void OutputAllStatsToConsole(ICommandConsole con)
+ {
+ foreach (string report in GetAllStatsReports())
+ con.Output(report);
+ }
+
+ private static List GetCategoryStatsReports(
+ SortedDictionary> category)
+ {
+ List reports = new List();
+
+ foreach (var container in category.Values)
+ reports.AddRange(GetContainerStatsReports(container));
+
+ return reports;
}
private static void OutputCategoryStatsToConsole(
ICommandConsole con, SortedDictionary> category)
{
- foreach (var container in category.Values)
- {
- OutputContainerStatsToConsole(con, container);
- }
+ foreach (string report in GetCategoryStatsReports(category))
+ con.Output(report);
}
- private static void OutputContainerStatsToConsole( ICommandConsole con, SortedDictionary container)
+ private static List GetContainerStatsReports(SortedDictionary container)
{
+ List reports = new List();
+
foreach (Stat stat in container.Values)
- {
- con.Output(stat.ToConsoleString());
- }
+ reports.Add(stat.ToConsoleString());
+
+ return reports;
+ }
+
+ private static void OutputContainerStatsToConsole(
+ ICommandConsole con, SortedDictionary container)
+ {
+ foreach (string report in GetContainerStatsReports(container))
+ con.Output(report);
}
// Creates an OSDMap of the format:
--
cgit v1.1
From 50c163ae6ca734610694f4edcc109ff0bdc65ba1 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Tue, 6 Aug 2013 08:21:16 -0700
Subject: Add a JSON web fetch of the statististics managed by StatsManager.
Disabled by default. Enable by setting
[Startup]ManagedStatsRemoteFetchURI="Something" and thereafter
"http://ServerHTTPPort/Something/" will return all the managed stats
(equivilent to "show stats all" console command). Accepts queries "cat=",
"cont=" and "stat=" to specify statistic category, container and statistic
names. The special name "all" is the default and returns all values in that
group.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 31 ++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index c8e838c..23c6f18 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -26,10 +26,12 @@
*/
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using OpenSim.Framework;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Monitoring
@@ -262,6 +264,35 @@ namespace OpenSim.Framework.Monitoring
return map;
}
+ public static Hashtable HandleStatsRequest(Hashtable request)
+ {
+ Hashtable responsedata = new Hashtable();
+ string regpath = request["uri"].ToString();
+ int response_code = 200;
+ string contenttype = "text/json";
+
+ string pCategoryName = StatsManager.AllSubCommand;
+ string pContainerName = StatsManager.AllSubCommand;
+ string pStatName = StatsManager.AllSubCommand;
+
+ if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString();
+ if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
+ if (request.ContainsKey("stat")) pStatName = request["cat"].ToString();
+
+ string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString();
+
+ // m_log.DebugFormat("{0} StatFetch: uri={1}, cat={2}, cont={3}, stat={4}, resp={5}",
+ // LogHeader, regpath, pCategoryName, pContainerName, pStatName, strOut);
+
+ responsedata["int_response_code"] = response_code;
+ responsedata["content_type"] = contenttype;
+ responsedata["keepalive"] = false;
+ responsedata["str_response_string"] = strOut;
+ responsedata["access_control_allow_origin"] = "*";
+
+ return responsedata;
+ }
+
// ///
// /// Start collecting statistics related to assets.
// /// Should only be called once.
--
cgit v1.1
From d9bd6e6b5be3100141a3b1202f859c65a302d4ee Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 8 Aug 2013 09:41:11 -0700
Subject: Add parameter and explanation of ManagedStats return to
OpenSimDefaults.ini. Add 'callback' query parameter to managed stats return
to return function form of JSON data.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 23c6f18..7cf1fa7 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -281,6 +281,12 @@ namespace OpenSim.Framework.Monitoring
string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString();
+ // If requestor wants it as a callback function, build response as a function rather than just the JSON string.
+ if (request.ContainsKey("callback"))
+ {
+ strOut = request["callback"].ToString() + "(" + strOut + ");";
+ }
+
// m_log.DebugFormat("{0} StatFetch: uri={1}, cat={2}, cont={3}, stat={4}, resp={5}",
// LogHeader, regpath, pCategoryName, pContainerName, pStatName, strOut);
--
cgit v1.1
From 217c8deae5fab5aa025932b027dfc4a4b629cc58 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 17 Aug 2013 00:51:21 +0100
Subject: minor: remove mono compiler warning in StatsManager
---
OpenSim/Framework/Monitoring/StatsManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 7cf1fa7..05ee4c5 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -267,7 +267,7 @@ namespace OpenSim.Framework.Monitoring
public static Hashtable HandleStatsRequest(Hashtable request)
{
Hashtable responsedata = new Hashtable();
- string regpath = request["uri"].ToString();
+// string regpath = request["uri"].ToString();
int response_code = 200;
string contenttype = "text/json";
--
cgit v1.1
From 8ce3fa646b4da171d96784935ba5a39ea65dd70a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 18 Mar 2014 20:21:47 +0000
Subject: Allow "show stats" console command to take a full stat name and
display only that stat.
For example, scene.test.RootAgents will show only the RootAgents stat in the scene named "test"
---
OpenSim/Framework/Monitoring/StatsManager.cs | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 05ee4c5..8fcbdca 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Framework.Monitoring
string categoryName = components[0];
string containerName = components.Length > 1 ? components[1] : null;
+ string statName = components.Length > 2 ? components[2] : null;
if (categoryName == AllSubCommand)
{
@@ -128,7 +129,23 @@ namespace OpenSim.Framework.Monitoring
SortedDictionary container;
if (category.TryGetValue(containerName, out container))
{
- OutputContainerStatsToConsole(con, container);
+ if (String.IsNullOrEmpty(statName))
+ {
+ OutputContainerStatsToConsole(con, container);
+ }
+ else
+ {
+ Stat stat;
+ if (container.TryGetValue(statName, out stat))
+ {
+ OutputStatToConsole(con, stat);
+ }
+ else
+ {
+ con.OutputFormat(
+ "No such stat {0} in {1}.{2}", statName, categoryName, containerName);
+ }
+ }
}
else
{
@@ -200,6 +217,11 @@ namespace OpenSim.Framework.Monitoring
con.Output(report);
}
+ private static void OutputStatToConsole(ICommandConsole con, Stat stat)
+ {
+ con.Output(stat.ToConsoleString());
+ }
+
// Creates an OSDMap of the format:
// { categoryName: {
// containerName: {
--
cgit v1.1
From 98587665160ae82fcc26c7cd03bded8e0e81751c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 19 Mar 2014 00:35:49 +0000
Subject: minor: Make "stats show" an alias for "show stats" command.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 8fcbdca..0bac247 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -72,8 +72,8 @@ namespace OpenSim.Framework.Monitoring
console.Commands.AddCommand(
"General",
false,
- "show stats",
- "show stats [list|all|([.])+",
+ "stats show",
+ "stats show [list|all|([.])+",
"Show statistical information for this server",
"If no final argument is specified then legacy statistics information is currently shown.\n"
+ "'list' argument will show statistic categories.\n"
@@ -84,6 +84,14 @@ namespace OpenSim.Framework.Monitoring
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
HandleShowStatsCommand);
+ console.Commands.AddCommand(
+ "General",
+ false,
+ "show stats",
+ "show stats [list|all|([.])+",
+ "Alias for 'stats show' command",
+ HandleShowStatsCommand);
+
StatsLogger.RegisterConsoleCommands(console);
}
--
cgit v1.1
From 5d534127663899cd5592c865b1d00855fce25854 Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Sun, 29 Jun 2014 16:40:11 +0300
Subject: Write UDP statistics to the log, not just the console (e.g., "show
queues")
---
OpenSim/Framework/Monitoring/StatsManager.cs | 53 ++++++++++++----------------
1 file changed, 22 insertions(+), 31 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Reflection;
+using log4net;
using OpenSim.Framework;
using OpenMetaverse.StructuredData;
@@ -41,6 +43,8 @@ namespace OpenSim.Framework.Monitoring
///
public static class StatsManager
{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
// Subcommand used to list other stats.
public const string AllSubCommand = "all";
@@ -98,6 +102,7 @@ namespace OpenSim.Framework.Monitoring
public static void HandleShowStatsCommand(string module, string[] cmd)
{
ICommandConsole con = MainConsole.Instance;
+ StringBuilder report = new StringBuilder();
if (cmd.Length > 2)
{
@@ -111,7 +116,8 @@ namespace OpenSim.Framework.Monitoring
if (categoryName == AllSubCommand)
{
- OutputAllStatsToConsole(con);
+ foreach (string report2 in GetAllStatsReports())
+ report.AppendLine(report2);
}
else if (categoryName == ListSubCommand)
{
@@ -130,7 +136,8 @@ namespace OpenSim.Framework.Monitoring
{
if (String.IsNullOrEmpty(containerName))
{
- OutputCategoryStatsToConsole(con, category);
+ foreach (string report2 in GetCategoryStatsReports(category))
+ report.AppendLine(report2);
}
else
{
@@ -139,14 +146,15 @@ namespace OpenSim.Framework.Monitoring
{
if (String.IsNullOrEmpty(statName))
{
- OutputContainerStatsToConsole(con, container);
+ foreach (string report2 in GetContainerStatsReports(container))
+ report.AppendLine(report2);
}
else
{
Stat stat;
if (container.TryGetValue(statName, out stat))
{
- OutputStatToConsole(con, stat);
+ report.AppendLine(stat.ToConsoleString());
}
else
{
@@ -168,10 +176,18 @@ namespace OpenSim.Framework.Monitoring
{
// Legacy
if (SimExtraStats != null)
- con.Output(SimExtraStats.Report());
+ {
+ report.Append(SimExtraStats.Report());
+ }
else
- OutputAllStatsToConsole(con);
+ {
+ foreach (string report2 in GetAllStatsReports())
+ report.AppendLine(report2);
+ }
}
+
+ if (report.Length > 0)
+ m_log.Debug(string.Join(" ", cmd) + "\n" + report.ToString());
}
public static List GetAllStatsReports()
@@ -184,12 +200,6 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
- private static void OutputAllStatsToConsole(ICommandConsole con)
- {
- foreach (string report in GetAllStatsReports())
- con.Output(report);
- }
-
private static List GetCategoryStatsReports(
SortedDictionary> category)
{
@@ -201,13 +211,6 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
- private static void OutputCategoryStatsToConsole(
- ICommandConsole con, SortedDictionary> category)
- {
- foreach (string report in GetCategoryStatsReports(category))
- con.Output(report);
- }
-
private static List GetContainerStatsReports(SortedDictionary container)
{
List reports = new List();
@@ -218,18 +221,6 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
- private static void OutputContainerStatsToConsole(
- ICommandConsole con, SortedDictionary container)
- {
- foreach (string report in GetContainerStatsReports(container))
- con.Output(report);
- }
-
- private static void OutputStatToConsole(ICommandConsole con, Stat stat)
- {
- con.Output(stat.ToConsoleString());
- }
-
// Creates an OSDMap of the format:
// { categoryName: {
// containerName: {
--
cgit v1.1
From cc61681484185f3c450fc0ab7efeb093c672d194 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 25 Jul 2014 01:56:41 +0100
Subject: Revert "Write UDP statistics to the log, not just the console (e.g.,
"show queues")"
Fixes http://opensimulator.org/mantis/view.php?id=7280
It can't be done this way because the stats data needs to show up on the console at all log levels, not just debug.
But this means setting it to log at fatal, which is not appropriate for this stuff in the log.
I understand the desire but this has to be done some other way, perhaps by (yet another) config parameter.
Also, this was already being done with the ClientStatsReport but that also should be done in another way, I think.
This reverts commit 5d534127663899cd5592c865b1d00855fce25854.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 53 ++++++++++++++++------------
1 file changed, 31 insertions(+), 22 deletions(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 5c8d934..0bac247 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -30,8 +30,6 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
-using System.Reflection;
-using log4net;
using OpenSim.Framework;
using OpenMetaverse.StructuredData;
@@ -43,8 +41,6 @@ namespace OpenSim.Framework.Monitoring
///
public static class StatsManager
{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
// Subcommand used to list other stats.
public const string AllSubCommand = "all";
@@ -102,7 +98,6 @@ namespace OpenSim.Framework.Monitoring
public static void HandleShowStatsCommand(string module, string[] cmd)
{
ICommandConsole con = MainConsole.Instance;
- StringBuilder report = new StringBuilder();
if (cmd.Length > 2)
{
@@ -116,8 +111,7 @@ namespace OpenSim.Framework.Monitoring
if (categoryName == AllSubCommand)
{
- foreach (string report2 in GetAllStatsReports())
- report.AppendLine(report2);
+ OutputAllStatsToConsole(con);
}
else if (categoryName == ListSubCommand)
{
@@ -136,8 +130,7 @@ namespace OpenSim.Framework.Monitoring
{
if (String.IsNullOrEmpty(containerName))
{
- foreach (string report2 in GetCategoryStatsReports(category))
- report.AppendLine(report2);
+ OutputCategoryStatsToConsole(con, category);
}
else
{
@@ -146,15 +139,14 @@ namespace OpenSim.Framework.Monitoring
{
if (String.IsNullOrEmpty(statName))
{
- foreach (string report2 in GetContainerStatsReports(container))
- report.AppendLine(report2);
+ OutputContainerStatsToConsole(con, container);
}
else
{
Stat stat;
if (container.TryGetValue(statName, out stat))
{
- report.AppendLine(stat.ToConsoleString());
+ OutputStatToConsole(con, stat);
}
else
{
@@ -176,18 +168,10 @@ namespace OpenSim.Framework.Monitoring
{
// Legacy
if (SimExtraStats != null)
- {
- report.Append(SimExtraStats.Report());
- }
+ con.Output(SimExtraStats.Report());
else
- {
- foreach (string report2 in GetAllStatsReports())
- report.AppendLine(report2);
- }
+ OutputAllStatsToConsole(con);
}
-
- if (report.Length > 0)
- m_log.Debug(string.Join(" ", cmd) + "\n" + report.ToString());
}
public static List GetAllStatsReports()
@@ -200,6 +184,12 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
+ private static void OutputAllStatsToConsole(ICommandConsole con)
+ {
+ foreach (string report in GetAllStatsReports())
+ con.Output(report);
+ }
+
private static List GetCategoryStatsReports(
SortedDictionary> category)
{
@@ -211,6 +201,13 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
+ private static void OutputCategoryStatsToConsole(
+ ICommandConsole con, SortedDictionary> category)
+ {
+ foreach (string report in GetCategoryStatsReports(category))
+ con.Output(report);
+ }
+
private static List GetContainerStatsReports(SortedDictionary container)
{
List reports = new List();
@@ -221,6 +218,18 @@ namespace OpenSim.Framework.Monitoring
return reports;
}
+ private static void OutputContainerStatsToConsole(
+ ICommandConsole con, SortedDictionary container)
+ {
+ foreach (string report in GetContainerStatsReports(container))
+ con.Output(report);
+ }
+
+ private static void OutputStatToConsole(ICommandConsole con, Stat stat)
+ {
+ con.Output(stat.ToConsoleString());
+ }
+
// Creates an OSDMap of the format:
// { categoryName: {
// containerName: {
--
cgit v1.1
From 7c2aeb9e8e72fe0a1168558b7810ff496f5a96ec Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 1 Jan 2015 09:39:07 -0800
Subject: Fix cut-and-paste error that made StatsManager web fetch queries fail
for container specification.
---
OpenSim/Framework/Monitoring/StatsManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Framework/Monitoring/StatsManager.cs')
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 0bac247..3136ee8 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -307,7 +307,7 @@ namespace OpenSim.Framework.Monitoring
if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString();
if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
- if (request.ContainsKey("stat")) pStatName = request["cat"].ToString();
+ if (request.ContainsKey("stat")) pStatName = request["stat"].ToString();
string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString();
--
cgit v1.1