From 31304c222df1e5a832afd0ebcf7d3ed403543e54 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 21:00:59 +0100
Subject: Make SceneManager.OnRegionsReadyStatusChange event available.
This is fired when all regions are ready or when at least one region becomes not ready.
Recently added EventManager.OnRegionReady becomes OnRegionReadyStatusChange to match OnLoginsEnabledStatusChange
---
OpenSim/Framework/IScene.cs | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 2c38e0f..87ec99e 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -71,6 +71,14 @@ namespace OpenSim.Framework
///
bool LoginsEnabled { get; set; }
+ ///
+ /// Is this region ready for use?
+ ///
+ ///
+ /// This does not mean that logins are enabled, merely that they can be.
+ ///
+ bool Ready { get; set; }
+
float TimeDilation { get; }
bool AllowScriptCrossings { get; }
--
cgit v1.1
From a1e99642c19810f98084e77723df1e242d2c26d0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 22:29:40 +0100
Subject: Add experimental "OpenSim object memory churn" statistics to output
of region console "show stats" command
This aims to capture the amount of memory that OpenSim turns over whilst operating a region.
This memory is not lost - apart from leaks it is reclaimed by the garbage collector.
However, the more memory that gets turned over the more work the GC has to do to reclaim it.
---
OpenSim/Framework/Statistics/BaseStatsCollector.cs | 20 ++++++++++++--------
OpenSim/Framework/Watchdog.cs | 3 +++
2 files changed, 15 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
index c9e57ce..28ce650 100644
--- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
@@ -44,14 +44,18 @@ namespace OpenSim.Framework.Statistics
StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine);
- sb.Append(
- string.Format(
- "Allocated to OpenSim objects: {0} MB\n",
- Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
- sb.Append(
- string.Format(
- "Process memory : {0} MB\n",
- Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
+
+ sb.AppendFormat(
+ "Allocated to OpenSim objects: {0} MB\n",
+ Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
+
+ sb.AppendFormat(
+ "OpenSim object memory churn : {0} KB/s\n",
+ Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
+
+ sb.AppendFormat(
+ "Process memory : {0} MB\n",
+ Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
return sb.ToString();
}
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 8a74f53..54e3d1a 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -325,6 +325,9 @@ namespace OpenSim.Framework
callback(callbackInfo);
}
+ if (MemoryWatchdog.Enabled)
+ MemoryWatchdog.Update();
+
m_watchdogTimer.Start();
}
}
--
cgit v1.1
From 22aa436648e7cdddefa5fb7263c0fdec294733b5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 22:33:24 +0100
Subject: Correct churn stat from MB/s from KB/s
---
OpenSim/Framework/Statistics/BaseStatsCollector.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
index 28ce650..1fe086c 100644
--- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Framework.Statistics
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
sb.AppendFormat(
- "OpenSim object memory churn : {0} KB/s\n",
+ "OpenSim object memory churn : {0} MB/s\n",
Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
--
cgit v1.1
From 227126adb784ed70739f42aec0072bdd8f06de9a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 22:38:28 +0100
Subject: Add MemoryWatchdog class missing from git master a1e9964
---
OpenSim/Framework/MemoryWatchdog.cs | 129 ++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
create mode 100644 OpenSim/Framework/MemoryWatchdog.cs
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/MemoryWatchdog.cs b/OpenSim/Framework/MemoryWatchdog.cs
new file mode 100644
index 0000000..1e93077
--- /dev/null
+++ b/OpenSim/Framework/MemoryWatchdog.cs
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework
+{
+ ///
+ /// Experimental watchdog for memory usage.
+ ///
+ public static class MemoryWatchdog
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Is this watchdog active?
+ ///
+ public static bool Enabled
+ {
+ get { return m_enabled; }
+ set
+ {
+// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
+
+ if (value && !m_enabled)
+ UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
+
+ m_enabled = value;
+ }
+ }
+ private static bool m_enabled;
+
+ ///
+ /// Average memory churn in bytes per millisecond.
+ ///
+ public static double AverageMemoryChurn
+ {
+ get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
+ }
+
+ ///
+ /// 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;
+
+ ///
+ /// Time when the watchdog was last updated.
+ ///
+ private static int m_lastUpdateTick;
+
+ ///
+ /// Memory used at time of last watchdog update.
+ ///
+ private static long m_lastUpdateMemory;
+
+ ///
+ /// Memory churn rate per millisecond.
+ ///
+ private static double m_churnRatePerMillisecond;
+
+ ///
+ /// Historical samples for calculating moving average.
+ ///
+ private static Queue m_samples = new Queue(m_maxSamples);
+
+ public static void Update()
+ {
+ int now = Util.EnvironmentTickCount();
+ long memoryNow = GC.GetTotalMemory(false);
+ long memoryDiff = memoryNow - m_lastUpdateMemory;
+
+ if (memoryDiff >= 0)
+ {
+ if (m_samples.Count >= m_maxSamples)
+ m_samples.Dequeue();
+
+ double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
+
+ // This should never happen since it's not useful for updates to occur with no time elapsed, but
+ // protect ourselves from a divide-by-zero just in case.
+ if (elapsed == 0)
+ return;
+
+ m_samples.Enqueue(memoryDiff / (double)elapsed);
+ }
+
+ UpdateLastRecord(memoryNow, now);
+ }
+
+ private static void UpdateLastRecord(long memoryNow, int timeNow)
+ {
+ m_lastUpdateMemory = memoryNow;
+ m_lastUpdateTick = timeNow;
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.1
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.
---
.../Framework/Monitoring/AssetStatsCollector.cs | 104 +++++
OpenSim/Framework/Monitoring/BaseStatsCollector.cs | 67 +++
.../Monitoring/Interfaces/IPullStatsProvider.cs | 41 ++
.../Monitoring/Interfaces/IStatsCollector.cs | 49 +++
.../Framework/Monitoring/SimExtraStatsCollector.cs | 463 ++++++++++++++++++++
OpenSim/Framework/Monitoring/StatsManager.cs | 65 +++
OpenSim/Framework/Monitoring/UserStatsCollector.cs | 92 ++++
OpenSim/Framework/Servers/BaseOpenSimServer.cs | 2 +-
.../Framework/Statistics/AssetStatsCollector.cs | 104 -----
OpenSim/Framework/Statistics/BaseStatsCollector.cs | 68 ---
.../Statistics/Interfaces/IPullStatsProvider.cs | 41 --
.../Statistics/Interfaces/IStatsCollector.cs | 49 ---
.../Framework/Statistics/SimExtraStatsCollector.cs | 464 ---------------------
OpenSim/Framework/Statistics/StatsManager.cs | 65 ---
OpenSim/Framework/Statistics/UserStatsCollector.cs | 92 ----
15 files changed, 882 insertions(+), 884 deletions(-)
create mode 100644 OpenSim/Framework/Monitoring/AssetStatsCollector.cs
create mode 100644 OpenSim/Framework/Monitoring/BaseStatsCollector.cs
create mode 100644 OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
create mode 100644 OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
create mode 100644 OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
create mode 100644 OpenSim/Framework/Monitoring/StatsManager.cs
create mode 100644 OpenSim/Framework/Monitoring/UserStatsCollector.cs
delete mode 100644 OpenSim/Framework/Statistics/AssetStatsCollector.cs
delete mode 100644 OpenSim/Framework/Statistics/BaseStatsCollector.cs
delete mode 100644 OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs
delete mode 100644 OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs
delete mode 100644 OpenSim/Framework/Statistics/SimExtraStatsCollector.cs
delete mode 100644 OpenSim/Framework/Statistics/StatsManager.cs
delete mode 100644 OpenSim/Framework/Statistics/UserStatsCollector.cs
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Monitoring/AssetStatsCollector.cs b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
new file mode 100644
index 0000000..2a4d45b
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Timers;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Asset service statistics collection
+ ///
+ public class AssetStatsCollector : BaseStatsCollector
+ {
+ private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
+ private DateTime startTime = DateTime.Now;
+
+ private long assetRequestsToday;
+ private long assetRequestsNotFoundToday;
+ private long assetRequestsYesterday;
+ private long assetRequestsNotFoundYesterday;
+
+ public long AssetRequestsToday { get { return assetRequestsToday; } }
+ public long AssetRequestsNotFoundToday { get { return assetRequestsNotFoundToday; } }
+ public long AssetRequestsYesterday { get { return assetRequestsYesterday; } }
+ public long AssetRequestsNotFoundYesterday { get { return assetRequestsNotFoundYesterday; } }
+
+ public AssetStatsCollector()
+ {
+ ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
+ ageStatsTimer.Enabled = true;
+ }
+
+ private void OnAgeing(object source, ElapsedEventArgs e)
+ {
+ assetRequestsYesterday = assetRequestsToday;
+
+ // There is a possibility that an asset request could occur between the execution of these
+ // two statements. But we're better off without the synchronization overhead.
+ assetRequestsToday = 0;
+
+ assetRequestsNotFoundYesterday = assetRequestsNotFoundToday;
+ assetRequestsNotFoundToday = 0;
+ }
+
+ ///
+ /// Record that an asset request failed to find an asset
+ ///
+ public void AddNotFoundRequest()
+ {
+ assetRequestsNotFoundToday++;
+ }
+
+ ///
+ /// Record that a request was made to the asset server
+ ///
+ public void AddRequest()
+ {
+ assetRequestsToday++;
+ }
+
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ override public string Report()
+ {
+ double elapsedHours = (DateTime.Now - startTime).TotalHours;
+ if (elapsedHours <= 0) { elapsedHours = 1; } // prevent divide by zero
+
+ long assetRequestsTodayPerHour = (long)Math.Round(AssetRequestsToday / elapsedHours);
+ long assetRequestsYesterdayPerHour = (long)Math.Round(AssetRequestsYesterday / 24.0);
+
+ return string.Format(
+@"Asset requests today : {0} ({1} per hour) of which {2} were not found
+Asset requests yesterday : {3} ({4} per hour) of which {5} were not found",
+ AssetRequestsToday, assetRequestsTodayPerHour, AssetRequestsNotFoundToday,
+ AssetRequestsYesterday, assetRequestsYesterdayPerHour, AssetRequestsNotFoundYesterday);
+ }
+ }
+}
diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
new file mode 100644
index 0000000..57a63ef
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Text;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Statistics which all collectors are interested in reporting
+ ///
+ public class BaseStatsCollector : IStatsCollector
+ {
+ public virtual string Report()
+ {
+ StringBuilder sb = new StringBuilder(Environment.NewLine);
+ sb.Append("MEMORY STATISTICS");
+ sb.Append(Environment.NewLine);
+
+ sb.AppendFormat(
+ "Allocated to OpenSim objects: {0} MB\n",
+ Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
+
+ sb.AppendFormat(
+ "OpenSim object memory churn : {0} MB/s\n",
+ Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
+
+ sb.AppendFormat(
+ "Process memory : {0} MB\n",
+ Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
+
+ return sb.ToString();
+ }
+
+ public virtual string XReport(string uptime, string version)
+ {
+ return (string) Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0).ToString() ;
+ }
+ }
+}
diff --git a/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
new file mode 100644
index 0000000..86a6620
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.Interfaces
+{
+ ///
+ /// Implemented by objects which allow statistical information to be pulled from them.
+ ///
+ public interface IPullStatsProvider
+ {
+ ///
+ /// Provide statistical information. Only temporary one long string.
+ ///
+ ///
+ string GetStats();
+ }
+}
diff --git a/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
new file mode 100644
index 0000000..99f75e3
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
@@ -0,0 +1,49 @@
+/*
+ * 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
+{
+ ///
+ /// Implemented by classes which collect up non-viewer statistical information
+ ///
+ public interface IStatsCollector
+ {
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ string Report();
+
+ ///
+ /// Report back collected statistical information in json
+ ///
+ ///
+ /// A
+ ///
+ string XReport(string uptime, string version);
+ }
+}
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
new file mode 100644
index 0000000..cdd7cc7
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -0,0 +1,463 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework.Monitoring.Interfaces;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane
+ ///
+ public class SimExtraStatsCollector : BaseStatsCollector
+ {
+ private long abnormalClientThreadTerminations;
+
+// private long assetsInCache;
+// private long texturesInCache;
+// private long assetCacheMemoryUsage;
+// private long textureCacheMemoryUsage;
+// private TimeSpan assetRequestTimeAfterCacheMiss;
+// private long blockedMissingTextureRequests;
+
+// private long assetServiceRequestFailures;
+// private long inventoryServiceRetrievalFailures;
+
+ private volatile float timeDilation;
+ private volatile float simFps;
+ private volatile float physicsFps;
+ private volatile float agentUpdates;
+ private volatile float rootAgents;
+ private volatile float childAgents;
+ private volatile float totalPrims;
+ private volatile float activePrims;
+ private volatile float totalFrameTime;
+ private volatile float netFrameTime;
+ private volatile float physicsFrameTime;
+ private volatile float otherFrameTime;
+ private volatile float imageFrameTime;
+ private volatile float inPacketsPerSecond;
+ private volatile float outPacketsPerSecond;
+ private volatile float unackedBytes;
+ private volatile float agentFrameTime;
+ private volatile float pendingDownloads;
+ private volatile float pendingUploads;
+ private volatile float activeScripts;
+ private volatile float scriptLinesPerSecond;
+
+ ///
+ /// Number of times that a client thread terminated because of an exception
+ ///
+ public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } }
+
+// ///
+// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
+// /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these
+// /// haven't yet been implemented...
+// ///
+// public long AssetsInCache { get { return assetsInCache; } }
+//
+// ///
+// /// Currently unused
+// ///
+// public long TexturesInCache { get { return texturesInCache; } }
+//
+// ///
+// /// Currently misleading since we can't currently subtract removed asset memory usage without a performance hit
+// ///
+// public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } }
+//
+// ///
+// /// Currently unused
+// ///
+// public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } }
+
+ public float TimeDilation { get { return timeDilation; } }
+ public float SimFps { get { return simFps; } }
+ public float PhysicsFps { get { return physicsFps; } }
+ public float AgentUpdates { get { return agentUpdates; } }
+ public float RootAgents { get { return rootAgents; } }
+ public float ChildAgents { get { return childAgents; } }
+ public float TotalPrims { get { return totalPrims; } }
+ public float ActivePrims { get { return activePrims; } }
+ public float TotalFrameTime { get { return totalFrameTime; } }
+ public float NetFrameTime { get { return netFrameTime; } }
+ public float PhysicsFrameTime { get { return physicsFrameTime; } }
+ public float OtherFrameTime { get { return otherFrameTime; } }
+ public float ImageFrameTime { get { return imageFrameTime; } }
+ public float InPacketsPerSecond { get { return inPacketsPerSecond; } }
+ public float OutPacketsPerSecond { get { return outPacketsPerSecond; } }
+ public float UnackedBytes { get { return unackedBytes; } }
+ public float AgentFrameTime { get { return agentFrameTime; } }
+ public float PendingDownloads { get { return pendingDownloads; } }
+ public float PendingUploads { get { return pendingUploads; } }
+ public float ActiveScripts { get { return activeScripts; } }
+ public float ScriptLinesPerSecond { get { return scriptLinesPerSecond; } }
+
+// ///
+// /// This is the time it took for the last asset request made in response to a cache miss.
+// ///
+// public TimeSpan AssetRequestTimeAfterCacheMiss { get { return assetRequestTimeAfterCacheMiss; } }
+//
+// ///
+// /// Number of persistent requests for missing textures we have started blocking from clients. To some extent
+// /// this is just a temporary statistic to keep this problem in view - the root cause of this lies either
+// /// in a mishandling of the reply protocol, related to avatar appearance or may even originate in graphics
+// /// driver bugs on clients (though this seems less likely).
+// ///
+// public long BlockedMissingTextureRequests { get { return blockedMissingTextureRequests; } }
+//
+// ///
+// /// Record the number of times that an asset request has failed. Failures are effectively exceptions, such as
+// /// request timeouts. If an asset service replies that a particular asset cannot be found, this is not counted
+// /// as a failure
+// ///
+// public long AssetServiceRequestFailures { get { return assetServiceRequestFailures; } }
+
+ ///
+ /// Number of known failures to retrieve avatar inventory from the inventory service. This does not
+ /// cover situations where the inventory service accepts the request but never returns any data, since
+ /// we do not yet timeout this situation.
+ ///
+ /// Commented out because we do not cache inventory at this point
+// public long InventoryServiceRetrievalFailures { get { return inventoryServiceRetrievalFailures; } }
+
+ ///
+ /// Retrieve the total frame time (in ms) of the last frame
+ ///
+ //public float TotalFrameTime { get { return totalFrameTime; } }
+
+ ///
+ /// Retrieve the physics update component (in ms) of the last frame
+ ///
+ //public float PhysicsFrameTime { get { return physicsFrameTime; } }
+
+ ///
+ /// Retain a dictionary of all packet queues stats reporters
+ ///
+ private IDictionary packetQueueStatsCollectors
+ = new Dictionary();
+
+ public void AddAbnormalClientThreadTermination()
+ {
+ abnormalClientThreadTerminations++;
+ }
+
+// public void AddAsset(AssetBase asset)
+// {
+// assetsInCache++;
+// //assetCacheMemoryUsage += asset.Data.Length;
+// }
+//
+// public void RemoveAsset(UUID uuid)
+// {
+// assetsInCache--;
+// }
+//
+// public void AddTexture(AssetBase image)
+// {
+// if (image.Data != null)
+// {
+// texturesInCache++;
+//
+// // This could have been a pull stat, though there was originally a nebulous idea to measure flow rates
+// textureCacheMemoryUsage += image.Data.Length;
+// }
+// }
+//
+// ///
+// /// Signal that the asset cache has been cleared.
+// ///
+// public void ClearAssetCacheStatistics()
+// {
+// assetsInCache = 0;
+// assetCacheMemoryUsage = 0;
+// texturesInCache = 0;
+// textureCacheMemoryUsage = 0;
+// }
+//
+// public void AddAssetRequestTimeAfterCacheMiss(TimeSpan ts)
+// {
+// assetRequestTimeAfterCacheMiss = ts;
+// }
+//
+// public void AddBlockedMissingTextureRequest()
+// {
+// blockedMissingTextureRequests++;
+// }
+//
+// public void AddAssetServiceRequestFailure()
+// {
+// assetServiceRequestFailures++;
+// }
+
+// public void AddInventoryServiceRetrievalFailure()
+// {
+// inventoryServiceRetrievalFailures++;
+// }
+
+ ///
+ /// Register as a packet queue stats provider
+ ///
+ /// An agent UUID
+ ///
+ public void RegisterPacketQueueStatsProvider(UUID uuid, IPullStatsProvider provider)
+ {
+ lock (packetQueueStatsCollectors)
+ {
+ // FIXME: If the region service is providing more than one region, then the child and root agent
+ // queues are wrongly replacing each other here.
+ packetQueueStatsCollectors[uuid] = new PacketQueueStatsCollector(provider);
+ }
+ }
+
+ ///
+ /// Deregister a packet queue stats provider
+ ///
+ /// An agent UUID
+ public void DeregisterPacketQueueStatsProvider(UUID uuid)
+ {
+ lock (packetQueueStatsCollectors)
+ {
+ packetQueueStatsCollectors.Remove(uuid);
+ }
+ }
+
+ ///
+ /// This is the method on which the classic sim stats reporter (which collects stats for
+ /// client purposes) sends information to listeners.
+ ///
+ ///
+ public void ReceiveClassicSimStatsPacket(SimStats stats)
+ {
+ // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
+ // SimStatsPacket that was being used).
+ timeDilation = stats.StatsBlock[0].StatValue;
+ simFps = stats.StatsBlock[1].StatValue;
+ physicsFps = stats.StatsBlock[2].StatValue;
+ agentUpdates = stats.StatsBlock[3].StatValue;
+ rootAgents = stats.StatsBlock[4].StatValue;
+ childAgents = stats.StatsBlock[5].StatValue;
+ totalPrims = stats.StatsBlock[6].StatValue;
+ activePrims = stats.StatsBlock[7].StatValue;
+ totalFrameTime = stats.StatsBlock[8].StatValue;
+ netFrameTime = stats.StatsBlock[9].StatValue;
+ physicsFrameTime = stats.StatsBlock[10].StatValue;
+ otherFrameTime = stats.StatsBlock[11].StatValue;
+ imageFrameTime = stats.StatsBlock[12].StatValue;
+ inPacketsPerSecond = stats.StatsBlock[13].StatValue;
+ outPacketsPerSecond = stats.StatsBlock[14].StatValue;
+ unackedBytes = stats.StatsBlock[15].StatValue;
+ agentFrameTime = stats.StatsBlock[16].StatValue;
+ pendingDownloads = stats.StatsBlock[17].StatValue;
+ pendingUploads = stats.StatsBlock[18].StatValue;
+ activeScripts = stats.StatsBlock[19].StatValue;
+ scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
+ }
+
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ public override string Report()
+ {
+ StringBuilder sb = new StringBuilder(Environment.NewLine);
+// sb.Append("ASSET STATISTICS");
+// sb.Append(Environment.NewLine);
+
+ /*
+ sb.Append(
+ string.Format(
+@"Asset cache contains {0,6} non-texture assets using {1,10} K
+Texture cache contains {2,6} texture assets using {3,10} K
+Latest asset request time after cache miss: {4}s
+Blocked client requests for missing textures: {5}
+Asset service request failures: {6}"+ Environment.NewLine,
+ AssetsInCache, Math.Round(AssetCacheMemoryUsage / 1024.0),
+ TexturesInCache, Math.Round(TextureCacheMemoryUsage / 1024.0),
+ assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
+ BlockedMissingTextureRequests,
+ AssetServiceRequestFailures));
+ */
+
+ /*
+ sb.Append(
+ string.Format(
+@"Asset cache contains {0,6} assets
+Latest asset request time after cache miss: {1}s
+Blocked client requests for missing textures: {2}
+Asset service request failures: {3}" + Environment.NewLine,
+ AssetsInCache,
+ assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
+ BlockedMissingTextureRequests,
+ AssetServiceRequestFailures));
+ */
+
+ sb.Append(Environment.NewLine);
+ sb.Append("CONNECTION STATISTICS");
+ sb.Append(Environment.NewLine);
+ sb.Append(
+ string.Format(
+ "Abnormal client thread terminations: {0}" + Environment.NewLine,
+ abnormalClientThreadTerminations));
+
+// sb.Append(Environment.NewLine);
+// sb.Append("INVENTORY STATISTICS");
+// sb.Append(Environment.NewLine);
+// sb.Append(
+// string.Format(
+// "Initial inventory caching failures: {0}" + Environment.NewLine,
+// InventoryServiceRetrievalFailures));
+
+ sb.Append(Environment.NewLine);
+ sb.Append("FRAME STATISTICS");
+ sb.Append(Environment.NewLine);
+ sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS");
+ sb.Append(Environment.NewLine);
+ sb.Append(
+ string.Format(
+ "{0,6:0.00} {1,6:0} {2,6:0.0} {3,6:0.0} {4,6:0} {5,6:0} {6,6:0} {7,6:0} {8,6:0} {9,6:0}",
+ timeDilation, simFps, physicsFps, agentUpdates, rootAgents,
+ childAgents, totalPrims, activePrims, activeScripts, scriptLinesPerSecond));
+
+ sb.Append(Environment.NewLine);
+ sb.Append(Environment.NewLine);
+ // There is no script frame time currently because we don't yet collect it
+ sb.Append("PktsIn PktOut PendDl PendUl UnackB TotlFt NetFt PhysFt OthrFt AgntFt ImgsFt");
+ sb.Append(Environment.NewLine);
+ sb.Append(
+ string.Format(
+ "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}",
+ inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
+ netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
+ sb.Append(Environment.NewLine);
+
+ /*
+ sb.Append(Environment.NewLine);
+ sb.Append("PACKET QUEUE STATISTICS");
+ sb.Append(Environment.NewLine);
+ sb.Append("Agent UUID ");
+ sb.Append(
+ string.Format(
+ " {0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
+ "Send", "In", "Out", "Resend", "Land", "Wind", "Cloud", "Task", "Texture", "Asset"));
+ sb.Append(Environment.NewLine);
+
+ foreach (UUID key in packetQueueStatsCollectors.Keys)
+ {
+ sb.Append(string.Format("{0}: ", key));
+ sb.Append(packetQueueStatsCollectors[key].Report());
+ sb.Append(Environment.NewLine);
+ }
+ */
+
+ sb.Append(base.Report());
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Report back collected statistical information as json serialization.
+ ///
+ ///
+ public override string XReport(string uptime, string version)
+ {
+ OSDMap args = new OSDMap(30);
+// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
+// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
+// assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0));
+// args["BlockedMissingTextureRequests"] = OSD.FromString (String.Format ("{0:0.##}",
+// BlockedMissingTextureRequests));
+// args["AssetServiceRequestFailures"] = OSD.FromString (String.Format ("{0:0.##}",
+// AssetServiceRequestFailures));
+// args["abnormalClientThreadTerminations"] = OSD.FromString (String.Format ("{0:0.##}",
+// abnormalClientThreadTerminations));
+// args["InventoryServiceRetrievalFailures"] = OSD.FromString (String.Format ("{0:0.##}",
+// InventoryServiceRetrievalFailures));
+ args["Dilatn"] = OSD.FromString (String.Format ("{0:0.##}", timeDilation));
+ args["SimFPS"] = OSD.FromString (String.Format ("{0:0.##}", simFps));
+ args["PhyFPS"] = OSD.FromString (String.Format ("{0:0.##}", physicsFps));
+ args["AgntUp"] = OSD.FromString (String.Format ("{0:0.##}", agentUpdates));
+ args["RootAg"] = OSD.FromString (String.Format ("{0:0.##}", rootAgents));
+ args["ChldAg"] = OSD.FromString (String.Format ("{0:0.##}", childAgents));
+ args["Prims"] = OSD.FromString (String.Format ("{0:0.##}", totalPrims));
+ args["AtvPrm"] = OSD.FromString (String.Format ("{0:0.##}", activePrims));
+ args["AtvScr"] = OSD.FromString (String.Format ("{0:0.##}", activeScripts));
+ args["ScrLPS"] = OSD.FromString (String.Format ("{0:0.##}", scriptLinesPerSecond));
+ args["PktsIn"] = OSD.FromString (String.Format ("{0:0.##}", inPacketsPerSecond));
+ args["PktOut"] = OSD.FromString (String.Format ("{0:0.##}", outPacketsPerSecond));
+ args["PendDl"] = OSD.FromString (String.Format ("{0:0.##}", pendingDownloads));
+ args["PendUl"] = OSD.FromString (String.Format ("{0:0.##}", pendingUploads));
+ args["UnackB"] = OSD.FromString (String.Format ("{0:0.##}", unackedBytes));
+ args["TotlFt"] = OSD.FromString (String.Format ("{0:0.##}", totalFrameTime));
+ args["NetFt"] = OSD.FromString (String.Format ("{0:0.##}", netFrameTime));
+ args["PhysFt"] = OSD.FromString (String.Format ("{0:0.##}", physicsFrameTime));
+ args["OthrFt"] = OSD.FromString (String.Format ("{0:0.##}", otherFrameTime));
+ args["AgntFt"] = OSD.FromString (String.Format ("{0:0.##}", agentFrameTime));
+ args["ImgsFt"] = OSD.FromString (String.Format ("{0:0.##}", imageFrameTime));
+ args["Memory"] = OSD.FromString (base.XReport (uptime, version));
+ args["Uptime"] = OSD.FromString (uptime);
+ args["Version"] = OSD.FromString (version);
+
+ string strBuffer = "";
+ strBuffer = OSDParser.SerializeJsonString(args);
+
+ return strBuffer;
+ }
+ }
+
+ ///
+ /// Pull packet queue stats from packet queues and report
+ ///
+ public class PacketQueueStatsCollector : IStatsCollector
+ {
+ private IPullStatsProvider m_statsProvider;
+
+ public PacketQueueStatsCollector(IPullStatsProvider provider)
+ {
+ m_statsProvider = provider;
+ }
+
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ public string Report()
+ {
+ return m_statsProvider.GetStats();
+ }
+
+ public string XReport(string uptime, string version)
+ {
+ return "";
+ }
+ }
+}
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
diff --git a/OpenSim/Framework/Monitoring/UserStatsCollector.cs b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
new file mode 100644
index 0000000..e89c8e6
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+using System.Timers;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Collects user service statistics
+ ///
+ public class UserStatsCollector : BaseStatsCollector
+ {
+ private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
+
+ private int successfulLoginsToday;
+ public int SuccessfulLoginsToday { get { return successfulLoginsToday; } }
+
+ private int successfulLoginsYesterday;
+ public int SuccessfulLoginsYesterday { get { return successfulLoginsYesterday; } }
+
+ private int successfulLogins;
+ public int SuccessfulLogins { get { return successfulLogins; } }
+
+ private int logouts;
+ public int Logouts { get { return logouts; } }
+
+ public UserStatsCollector()
+ {
+ ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
+ ageStatsTimer.Enabled = true;
+ }
+
+ private void OnAgeing(object source, ElapsedEventArgs e)
+ {
+ successfulLoginsYesterday = successfulLoginsToday;
+
+ // There is a possibility that an asset request could occur between the execution of these
+ // two statements. But we're better off without the synchronization overhead.
+ successfulLoginsToday = 0;
+ }
+
+ ///
+ /// Record a successful login
+ ///
+ public void AddSuccessfulLogin()
+ {
+ successfulLogins++;
+ successfulLoginsToday++;
+ }
+
+ public void AddLogout()
+ {
+ logouts++;
+ }
+
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ override public string Report()
+ {
+ return string.Format(
+@"Successful logins total : {0}, today : {1}, yesterday : {2}
+ Logouts total : {3}",
+ SuccessfulLogins, SuccessfulLoginsToday, SuccessfulLoginsYesterday, Logouts);
+ }
+ }
+}
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 14d8b0c..ab8d95a 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -42,7 +42,7 @@ using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using Timer=System.Timers.Timer;
using OpenMetaverse;
diff --git a/OpenSim/Framework/Statistics/AssetStatsCollector.cs b/OpenSim/Framework/Statistics/AssetStatsCollector.cs
deleted file mode 100644
index 7082ef3..0000000
--- a/OpenSim/Framework/Statistics/AssetStatsCollector.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Timers;
-
-namespace OpenSim.Framework.Statistics
-{
- ///
- /// Asset service statistics collection
- ///
- public class AssetStatsCollector : BaseStatsCollector
- {
- private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
- private DateTime startTime = DateTime.Now;
-
- private long assetRequestsToday;
- private long assetRequestsNotFoundToday;
- private long assetRequestsYesterday;
- private long assetRequestsNotFoundYesterday;
-
- public long AssetRequestsToday { get { return assetRequestsToday; } }
- public long AssetRequestsNotFoundToday { get { return assetRequestsNotFoundToday; } }
- public long AssetRequestsYesterday { get { return assetRequestsYesterday; } }
- public long AssetRequestsNotFoundYesterday { get { return assetRequestsNotFoundYesterday; } }
-
- public AssetStatsCollector()
- {
- ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
- ageStatsTimer.Enabled = true;
- }
-
- private void OnAgeing(object source, ElapsedEventArgs e)
- {
- assetRequestsYesterday = assetRequestsToday;
-
- // There is a possibility that an asset request could occur between the execution of these
- // two statements. But we're better off without the synchronization overhead.
- assetRequestsToday = 0;
-
- assetRequestsNotFoundYesterday = assetRequestsNotFoundToday;
- assetRequestsNotFoundToday = 0;
- }
-
- ///
- /// Record that an asset request failed to find an asset
- ///
- public void AddNotFoundRequest()
- {
- assetRequestsNotFoundToday++;
- }
-
- ///
- /// Record that a request was made to the asset server
- ///
- public void AddRequest()
- {
- assetRequestsToday++;
- }
-
- ///
- /// Report back collected statistical information.
- ///
- ///
- override public string Report()
- {
- double elapsedHours = (DateTime.Now - startTime).TotalHours;
- if (elapsedHours <= 0) { elapsedHours = 1; } // prevent divide by zero
-
- long assetRequestsTodayPerHour = (long)Math.Round(AssetRequestsToday / elapsedHours);
- long assetRequestsYesterdayPerHour = (long)Math.Round(AssetRequestsYesterday / 24.0);
-
- return string.Format(
-@"Asset requests today : {0} ({1} per hour) of which {2} were not found
-Asset requests yesterday : {3} ({4} per hour) of which {5} were not found",
- AssetRequestsToday, assetRequestsTodayPerHour, AssetRequestsNotFoundToday,
- AssetRequestsYesterday, assetRequestsYesterdayPerHour, AssetRequestsNotFoundYesterday);
- }
- }
-}
diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
deleted file mode 100644
index 1fe086c..0000000
--- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Diagnostics;
-using System.Text;
-using OpenMetaverse;
-using OpenMetaverse.StructuredData;
-
-
-namespace OpenSim.Framework.Statistics
-{
- ///
- /// Statistics which all collectors are interested in reporting
- ///
- public class BaseStatsCollector : IStatsCollector
- {
- public virtual string Report()
- {
- StringBuilder sb = new StringBuilder(Environment.NewLine);
- sb.Append("MEMORY STATISTICS");
- sb.Append(Environment.NewLine);
-
- sb.AppendFormat(
- "Allocated to OpenSim objects: {0} MB\n",
- Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
-
- sb.AppendFormat(
- "OpenSim object memory churn : {0} MB/s\n",
- Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
-
- sb.AppendFormat(
- "Process memory : {0} MB\n",
- Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
-
- return sb.ToString();
- }
-
- public virtual string XReport(string uptime, string version)
- {
- return (string) Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0).ToString() ;
- }
- }
-}
diff --git a/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs b/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs
deleted file mode 100644
index 430e580..0000000
--- a/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.Statistics.Interfaces
-{
- ///
- /// Implemented by objects which allow statistical information to be pulled from them.
- ///
- public interface IPullStatsProvider
- {
- ///
- /// Provide statistical information. Only temporary one long string.
- ///
- ///
- string GetStats();
- }
-}
diff --git a/OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs b/OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs
deleted file mode 100644
index 477bbb3..0000000
--- a/OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.Statistics
-{
- ///
- /// Implemented by classes which collect up non-viewer statistical information
- ///
- public interface IStatsCollector
- {
- ///
- /// Report back collected statistical information.
- ///
- ///
- string Report();
-
- ///
- /// Report back collected statistical information in json
- ///
- ///
- /// A
- ///
- string XReport(string uptime, string version);
- }
-}
diff --git a/OpenSim/Framework/Statistics/SimExtraStatsCollector.cs b/OpenSim/Framework/Statistics/SimExtraStatsCollector.cs
deleted file mode 100644
index a506e3b..0000000
--- a/OpenSim/Framework/Statistics/SimExtraStatsCollector.cs
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenMetaverse;
-using OpenSim.Framework.Statistics.Interfaces;
-using OpenMetaverse.StructuredData;
-
-namespace OpenSim.Framework.Statistics
-{
- ///
- /// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane
- ///
- public class SimExtraStatsCollector : BaseStatsCollector
- {
- private long abnormalClientThreadTerminations;
-
-// private long assetsInCache;
-// private long texturesInCache;
-// private long assetCacheMemoryUsage;
-// private long textureCacheMemoryUsage;
-// private TimeSpan assetRequestTimeAfterCacheMiss;
-// private long blockedMissingTextureRequests;
-
-// private long assetServiceRequestFailures;
-// private long inventoryServiceRetrievalFailures;
-
- private volatile float timeDilation;
- private volatile float simFps;
- private volatile float physicsFps;
- private volatile float agentUpdates;
- private volatile float rootAgents;
- private volatile float childAgents;
- private volatile float totalPrims;
- private volatile float activePrims;
- private volatile float totalFrameTime;
- private volatile float netFrameTime;
- private volatile float physicsFrameTime;
- private volatile float otherFrameTime;
- private volatile float imageFrameTime;
- private volatile float inPacketsPerSecond;
- private volatile float outPacketsPerSecond;
- private volatile float unackedBytes;
- private volatile float agentFrameTime;
- private volatile float pendingDownloads;
- private volatile float pendingUploads;
- private volatile float activeScripts;
- private volatile float scriptLinesPerSecond;
-
- ///
- /// Number of times that a client thread terminated because of an exception
- ///
- public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } }
-
-// ///
-// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
-// /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these
-// /// haven't yet been implemented...
-// ///
-// public long AssetsInCache { get { return assetsInCache; } }
-//
-// ///
-// /// Currently unused
-// ///
-// public long TexturesInCache { get { return texturesInCache; } }
-//
-// ///
-// /// Currently misleading since we can't currently subtract removed asset memory usage without a performance hit
-// ///
-// public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } }
-//
-// ///
-// /// Currently unused
-// ///
-// public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } }
-
- public float TimeDilation { get { return timeDilation; } }
- public float SimFps { get { return simFps; } }
- public float PhysicsFps { get { return physicsFps; } }
- public float AgentUpdates { get { return agentUpdates; } }
- public float RootAgents { get { return rootAgents; } }
- public float ChildAgents { get { return childAgents; } }
- public float TotalPrims { get { return totalPrims; } }
- public float ActivePrims { get { return activePrims; } }
- public float TotalFrameTime { get { return totalFrameTime; } }
- public float NetFrameTime { get { return netFrameTime; } }
- public float PhysicsFrameTime { get { return physicsFrameTime; } }
- public float OtherFrameTime { get { return otherFrameTime; } }
- public float ImageFrameTime { get { return imageFrameTime; } }
- public float InPacketsPerSecond { get { return inPacketsPerSecond; } }
- public float OutPacketsPerSecond { get { return outPacketsPerSecond; } }
- public float UnackedBytes { get { return unackedBytes; } }
- public float AgentFrameTime { get { return agentFrameTime; } }
- public float PendingDownloads { get { return pendingDownloads; } }
- public float PendingUploads { get { return pendingUploads; } }
- public float ActiveScripts { get { return activeScripts; } }
- public float ScriptLinesPerSecond { get { return scriptLinesPerSecond; } }
-
-// ///
-// /// This is the time it took for the last asset request made in response to a cache miss.
-// ///
-// public TimeSpan AssetRequestTimeAfterCacheMiss { get { return assetRequestTimeAfterCacheMiss; } }
-//
-// ///
-// /// Number of persistent requests for missing textures we have started blocking from clients. To some extent
-// /// this is just a temporary statistic to keep this problem in view - the root cause of this lies either
-// /// in a mishandling of the reply protocol, related to avatar appearance or may even originate in graphics
-// /// driver bugs on clients (though this seems less likely).
-// ///
-// public long BlockedMissingTextureRequests { get { return blockedMissingTextureRequests; } }
-//
-// ///
-// /// Record the number of times that an asset request has failed. Failures are effectively exceptions, such as
-// /// request timeouts. If an asset service replies that a particular asset cannot be found, this is not counted
-// /// as a failure
-// ///
-// public long AssetServiceRequestFailures { get { return assetServiceRequestFailures; } }
-
- ///
- /// Number of known failures to retrieve avatar inventory from the inventory service. This does not
- /// cover situations where the inventory service accepts the request but never returns any data, since
- /// we do not yet timeout this situation.
- ///
- /// Commented out because we do not cache inventory at this point
-// public long InventoryServiceRetrievalFailures { get { return inventoryServiceRetrievalFailures; } }
-
- ///
- /// Retrieve the total frame time (in ms) of the last frame
- ///
- //public float TotalFrameTime { get { return totalFrameTime; } }
-
- ///
- /// Retrieve the physics update component (in ms) of the last frame
- ///
- //public float PhysicsFrameTime { get { return physicsFrameTime; } }
-
- ///
- /// Retain a dictionary of all packet queues stats reporters
- ///
- private IDictionary packetQueueStatsCollectors
- = new Dictionary();
-
- public void AddAbnormalClientThreadTermination()
- {
- abnormalClientThreadTerminations++;
- }
-
-// public void AddAsset(AssetBase asset)
-// {
-// assetsInCache++;
-// //assetCacheMemoryUsage += asset.Data.Length;
-// }
-//
-// public void RemoveAsset(UUID uuid)
-// {
-// assetsInCache--;
-// }
-//
-// public void AddTexture(AssetBase image)
-// {
-// if (image.Data != null)
-// {
-// texturesInCache++;
-//
-// // This could have been a pull stat, though there was originally a nebulous idea to measure flow rates
-// textureCacheMemoryUsage += image.Data.Length;
-// }
-// }
-//
-// ///
-// /// Signal that the asset cache has been cleared.
-// ///
-// public void ClearAssetCacheStatistics()
-// {
-// assetsInCache = 0;
-// assetCacheMemoryUsage = 0;
-// texturesInCache = 0;
-// textureCacheMemoryUsage = 0;
-// }
-//
-// public void AddAssetRequestTimeAfterCacheMiss(TimeSpan ts)
-// {
-// assetRequestTimeAfterCacheMiss = ts;
-// }
-//
-// public void AddBlockedMissingTextureRequest()
-// {
-// blockedMissingTextureRequests++;
-// }
-//
-// public void AddAssetServiceRequestFailure()
-// {
-// assetServiceRequestFailures++;
-// }
-
-// public void AddInventoryServiceRetrievalFailure()
-// {
-// inventoryServiceRetrievalFailures++;
-// }
-
- ///
- /// Register as a packet queue stats provider
- ///
- /// An agent UUID
- ///
- public void RegisterPacketQueueStatsProvider(UUID uuid, IPullStatsProvider provider)
- {
- lock (packetQueueStatsCollectors)
- {
- // FIXME: If the region service is providing more than one region, then the child and root agent
- // queues are wrongly replacing each other here.
- packetQueueStatsCollectors[uuid] = new PacketQueueStatsCollector(provider);
- }
- }
-
- ///
- /// Deregister a packet queue stats provider
- ///
- /// An agent UUID
- public void DeregisterPacketQueueStatsProvider(UUID uuid)
- {
- lock (packetQueueStatsCollectors)
- {
- packetQueueStatsCollectors.Remove(uuid);
- }
- }
-
- ///
- /// This is the method on which the classic sim stats reporter (which collects stats for
- /// client purposes) sends information to listeners.
- ///
- ///
- public void ReceiveClassicSimStatsPacket(SimStats stats)
- {
- // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
- // SimStatsPacket that was being used).
- timeDilation = stats.StatsBlock[0].StatValue;
- simFps = stats.StatsBlock[1].StatValue;
- physicsFps = stats.StatsBlock[2].StatValue;
- agentUpdates = stats.StatsBlock[3].StatValue;
- rootAgents = stats.StatsBlock[4].StatValue;
- childAgents = stats.StatsBlock[5].StatValue;
- totalPrims = stats.StatsBlock[6].StatValue;
- activePrims = stats.StatsBlock[7].StatValue;
- totalFrameTime = stats.StatsBlock[8].StatValue;
- netFrameTime = stats.StatsBlock[9].StatValue;
- physicsFrameTime = stats.StatsBlock[10].StatValue;
- otherFrameTime = stats.StatsBlock[11].StatValue;
- imageFrameTime = stats.StatsBlock[12].StatValue;
- inPacketsPerSecond = stats.StatsBlock[13].StatValue;
- outPacketsPerSecond = stats.StatsBlock[14].StatValue;
- unackedBytes = stats.StatsBlock[15].StatValue;
- agentFrameTime = stats.StatsBlock[16].StatValue;
- pendingDownloads = stats.StatsBlock[17].StatValue;
- pendingUploads = stats.StatsBlock[18].StatValue;
- activeScripts = stats.StatsBlock[19].StatValue;
- scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
- }
-
- ///
- /// Report back collected statistical information.
- ///
- ///
- public override string Report()
- {
- StringBuilder sb = new StringBuilder(Environment.NewLine);
-// sb.Append("ASSET STATISTICS");
-// sb.Append(Environment.NewLine);
-
- /*
- sb.Append(
- string.Format(
-@"Asset cache contains {0,6} non-texture assets using {1,10} K
-Texture cache contains {2,6} texture assets using {3,10} K
-Latest asset request time after cache miss: {4}s
-Blocked client requests for missing textures: {5}
-Asset service request failures: {6}"+ Environment.NewLine,
- AssetsInCache, Math.Round(AssetCacheMemoryUsage / 1024.0),
- TexturesInCache, Math.Round(TextureCacheMemoryUsage / 1024.0),
- assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
- BlockedMissingTextureRequests,
- AssetServiceRequestFailures));
- */
-
- /*
- sb.Append(
- string.Format(
-@"Asset cache contains {0,6} assets
-Latest asset request time after cache miss: {1}s
-Blocked client requests for missing textures: {2}
-Asset service request failures: {3}" + Environment.NewLine,
- AssetsInCache,
- assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0,
- BlockedMissingTextureRequests,
- AssetServiceRequestFailures));
- */
-
- sb.Append(Environment.NewLine);
- sb.Append("CONNECTION STATISTICS");
- sb.Append(Environment.NewLine);
- sb.Append(
- string.Format(
- "Abnormal client thread terminations: {0}" + Environment.NewLine,
- abnormalClientThreadTerminations));
-
-// sb.Append(Environment.NewLine);
-// sb.Append("INVENTORY STATISTICS");
-// sb.Append(Environment.NewLine);
-// sb.Append(
-// string.Format(
-// "Initial inventory caching failures: {0}" + Environment.NewLine,
-// InventoryServiceRetrievalFailures));
-
- sb.Append(Environment.NewLine);
- sb.Append("FRAME STATISTICS");
- sb.Append(Environment.NewLine);
- sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS");
- sb.Append(Environment.NewLine);
- sb.Append(
- string.Format(
- "{0,6:0.00} {1,6:0} {2,6:0.0} {3,6:0.0} {4,6:0} {5,6:0} {6,6:0} {7,6:0} {8,6:0} {9,6:0}",
- timeDilation, simFps, physicsFps, agentUpdates, rootAgents,
- childAgents, totalPrims, activePrims, activeScripts, scriptLinesPerSecond));
-
- sb.Append(Environment.NewLine);
- sb.Append(Environment.NewLine);
- // There is no script frame time currently because we don't yet collect it
- sb.Append("PktsIn PktOut PendDl PendUl UnackB TotlFt NetFt PhysFt OthrFt AgntFt ImgsFt");
- sb.Append(Environment.NewLine);
- sb.Append(
- string.Format(
- "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}",
- inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
- netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
- sb.Append(Environment.NewLine);
-
- /*
- sb.Append(Environment.NewLine);
- sb.Append("PACKET QUEUE STATISTICS");
- sb.Append(Environment.NewLine);
- sb.Append("Agent UUID ");
- sb.Append(
- string.Format(
- " {0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
- "Send", "In", "Out", "Resend", "Land", "Wind", "Cloud", "Task", "Texture", "Asset"));
- sb.Append(Environment.NewLine);
-
- foreach (UUID key in packetQueueStatsCollectors.Keys)
- {
- sb.Append(string.Format("{0}: ", key));
- sb.Append(packetQueueStatsCollectors[key].Report());
- sb.Append(Environment.NewLine);
- }
- */
-
- sb.Append(base.Report());
-
- return sb.ToString();
- }
-
- ///
- /// Report back collected statistical information as json serialization.
- ///
- ///
- public override string XReport(string uptime, string version)
- {
- OSDMap args = new OSDMap(30);
-// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
-// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
-// assetRequestTimeAfterCacheMiss.Milliseconds / 1000.0));
-// args["BlockedMissingTextureRequests"] = OSD.FromString (String.Format ("{0:0.##}",
-// BlockedMissingTextureRequests));
-// args["AssetServiceRequestFailures"] = OSD.FromString (String.Format ("{0:0.##}",
-// AssetServiceRequestFailures));
-// args["abnormalClientThreadTerminations"] = OSD.FromString (String.Format ("{0:0.##}",
-// abnormalClientThreadTerminations));
-// args["InventoryServiceRetrievalFailures"] = OSD.FromString (String.Format ("{0:0.##}",
-// InventoryServiceRetrievalFailures));
- args["Dilatn"] = OSD.FromString (String.Format ("{0:0.##}", timeDilation));
- args["SimFPS"] = OSD.FromString (String.Format ("{0:0.##}", simFps));
- args["PhyFPS"] = OSD.FromString (String.Format ("{0:0.##}", physicsFps));
- args["AgntUp"] = OSD.FromString (String.Format ("{0:0.##}", agentUpdates));
- args["RootAg"] = OSD.FromString (String.Format ("{0:0.##}", rootAgents));
- args["ChldAg"] = OSD.FromString (String.Format ("{0:0.##}", childAgents));
- args["Prims"] = OSD.FromString (String.Format ("{0:0.##}", totalPrims));
- args["AtvPrm"] = OSD.FromString (String.Format ("{0:0.##}", activePrims));
- args["AtvScr"] = OSD.FromString (String.Format ("{0:0.##}", activeScripts));
- args["ScrLPS"] = OSD.FromString (String.Format ("{0:0.##}", scriptLinesPerSecond));
- args["PktsIn"] = OSD.FromString (String.Format ("{0:0.##}", inPacketsPerSecond));
- args["PktOut"] = OSD.FromString (String.Format ("{0:0.##}", outPacketsPerSecond));
- args["PendDl"] = OSD.FromString (String.Format ("{0:0.##}", pendingDownloads));
- args["PendUl"] = OSD.FromString (String.Format ("{0:0.##}", pendingUploads));
- args["UnackB"] = OSD.FromString (String.Format ("{0:0.##}", unackedBytes));
- args["TotlFt"] = OSD.FromString (String.Format ("{0:0.##}", totalFrameTime));
- args["NetFt"] = OSD.FromString (String.Format ("{0:0.##}", netFrameTime));
- args["PhysFt"] = OSD.FromString (String.Format ("{0:0.##}", physicsFrameTime));
- args["OthrFt"] = OSD.FromString (String.Format ("{0:0.##}", otherFrameTime));
- args["AgntFt"] = OSD.FromString (String.Format ("{0:0.##}", agentFrameTime));
- args["ImgsFt"] = OSD.FromString (String.Format ("{0:0.##}", imageFrameTime));
- args["Memory"] = OSD.FromString (base.XReport (uptime, version));
- args["Uptime"] = OSD.FromString (uptime);
- args["Version"] = OSD.FromString (version);
-
- string strBuffer = "";
- strBuffer = OSDParser.SerializeJsonString(args);
-
- return strBuffer;
- }
- }
-
- ///
- /// Pull packet queue stats from packet queues and report
- ///
- public class PacketQueueStatsCollector : IStatsCollector
- {
- private IPullStatsProvider m_statsProvider;
-
- public PacketQueueStatsCollector(IPullStatsProvider provider)
- {
- m_statsProvider = provider;
- }
-
- ///
- /// Report back collected statistical information.
- ///
- ///
- public string Report()
- {
- return m_statsProvider.GetStats();
- }
-
- public string XReport(string uptime, string version)
- {
- return "";
- }
- }
-}
diff --git a/OpenSim/Framework/Statistics/StatsManager.cs b/OpenSim/Framework/Statistics/StatsManager.cs
deleted file mode 100644
index 436ce2f..0000000
--- a/OpenSim/Framework/Statistics/StatsManager.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.Statistics
-{
- ///
- /// 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
diff --git a/OpenSim/Framework/Statistics/UserStatsCollector.cs b/OpenSim/Framework/Statistics/UserStatsCollector.cs
deleted file mode 100644
index fd2a9bf..0000000
--- a/OpenSim/Framework/Statistics/UserStatsCollector.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.
- */
-
-using System.Timers;
-
-namespace OpenSim.Framework.Statistics
-{
- ///
- /// Collects user service statistics
- ///
- public class UserStatsCollector : BaseStatsCollector
- {
- private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000);
-
- private int successfulLoginsToday;
- public int SuccessfulLoginsToday { get { return successfulLoginsToday; } }
-
- private int successfulLoginsYesterday;
- public int SuccessfulLoginsYesterday { get { return successfulLoginsYesterday; } }
-
- private int successfulLogins;
- public int SuccessfulLogins { get { return successfulLogins; } }
-
- private int logouts;
- public int Logouts { get { return logouts; } }
-
- public UserStatsCollector()
- {
- ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing);
- ageStatsTimer.Enabled = true;
- }
-
- private void OnAgeing(object source, ElapsedEventArgs e)
- {
- successfulLoginsYesterday = successfulLoginsToday;
-
- // There is a possibility that an asset request could occur between the execution of these
- // two statements. But we're better off without the synchronization overhead.
- successfulLoginsToday = 0;
- }
-
- ///
- /// Record a successful login
- ///
- public void AddSuccessfulLogin()
- {
- successfulLogins++;
- successfulLoginsToday++;
- }
-
- public void AddLogout()
- {
- logouts++;
- }
-
- ///
- /// Report back collected statistical information.
- ///
- ///
- override public string Report()
- {
- return string.Format(
-@"Successful logins total : {0}, today : {1}, yesterday : {2}
- Logouts total : {3}",
- SuccessfulLogins, SuccessfulLoginsToday, SuccessfulLoginsYesterday, Logouts);
- }
- }
-}
--
cgit v1.1
From 5aec0ff207e9427b8756471eb003fd68859f67b1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 25 Jul 2012 23:27:00 +0100
Subject: Move Watchdog and MemoryWatchdog classes into
OpenSim.Framework.Monitoring with other monitoring code from
OpenSim.Framework
---
OpenSim/Framework/MemoryWatchdog.cs | 129 --------
OpenSim/Framework/Monitoring/MemoryWatchdog.cs | 129 ++++++++
OpenSim/Framework/Monitoring/Watchdog.cs | 334 +++++++++++++++++++++
OpenSim/Framework/Servers/BaseOpenSimServer.cs | 1 +
.../Framework/Servers/HttpServer/BaseHttpServer.cs | 1 +
.../HttpServer/PollServiceRequestManager.cs | 1 +
.../Servers/HttpServer/PollServiceWorkerThread.cs | 1 +
OpenSim/Framework/Watchdog.cs | 334 ---------------------
8 files changed, 467 insertions(+), 463 deletions(-)
delete mode 100644 OpenSim/Framework/MemoryWatchdog.cs
create mode 100644 OpenSim/Framework/Monitoring/MemoryWatchdog.cs
create mode 100644 OpenSim/Framework/Monitoring/Watchdog.cs
delete mode 100644 OpenSim/Framework/Watchdog.cs
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/MemoryWatchdog.cs b/OpenSim/Framework/MemoryWatchdog.cs
deleted file mode 100644
index 1e93077..0000000
--- a/OpenSim/Framework/MemoryWatchdog.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using log4net;
-
-namespace OpenSim.Framework
-{
- ///
- /// Experimental watchdog for memory usage.
- ///
- public static class MemoryWatchdog
- {
-// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- ///
- /// Is this watchdog active?
- ///
- public static bool Enabled
- {
- get { return m_enabled; }
- set
- {
-// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
-
- if (value && !m_enabled)
- UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
-
- m_enabled = value;
- }
- }
- private static bool m_enabled;
-
- ///
- /// Average memory churn in bytes per millisecond.
- ///
- public static double AverageMemoryChurn
- {
- get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
- }
-
- ///
- /// 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;
-
- ///
- /// Time when the watchdog was last updated.
- ///
- private static int m_lastUpdateTick;
-
- ///
- /// Memory used at time of last watchdog update.
- ///
- private static long m_lastUpdateMemory;
-
- ///
- /// Memory churn rate per millisecond.
- ///
- private static double m_churnRatePerMillisecond;
-
- ///
- /// Historical samples for calculating moving average.
- ///
- private static Queue m_samples = new Queue(m_maxSamples);
-
- public static void Update()
- {
- int now = Util.EnvironmentTickCount();
- long memoryNow = GC.GetTotalMemory(false);
- long memoryDiff = memoryNow - m_lastUpdateMemory;
-
- if (memoryDiff >= 0)
- {
- if (m_samples.Count >= m_maxSamples)
- m_samples.Dequeue();
-
- double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
-
- // This should never happen since it's not useful for updates to occur with no time elapsed, but
- // protect ourselves from a divide-by-zero just in case.
- if (elapsed == 0)
- return;
-
- m_samples.Enqueue(memoryDiff / (double)elapsed);
- }
-
- UpdateLastRecord(memoryNow, now);
- }
-
- private static void UpdateLastRecord(long memoryNow, int timeNow)
- {
- m_lastUpdateMemory = memoryNow;
- m_lastUpdateTick = timeNow;
- }
- }
-}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
new file mode 100644
index 0000000..6599613
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Experimental watchdog for memory usage.
+ ///
+ public static class MemoryWatchdog
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Is this watchdog active?
+ ///
+ public static bool Enabled
+ {
+ get { return m_enabled; }
+ set
+ {
+// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
+
+ if (value && !m_enabled)
+ UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
+
+ m_enabled = value;
+ }
+ }
+ private static bool m_enabled;
+
+ ///
+ /// Average memory churn in bytes per millisecond.
+ ///
+ public static double AverageMemoryChurn
+ {
+ get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
+ }
+
+ ///
+ /// 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;
+
+ ///
+ /// Time when the watchdog was last updated.
+ ///
+ private static int m_lastUpdateTick;
+
+ ///
+ /// Memory used at time of last watchdog update.
+ ///
+ private static long m_lastUpdateMemory;
+
+ ///
+ /// Memory churn rate per millisecond.
+ ///
+ private static double m_churnRatePerMillisecond;
+
+ ///
+ /// Historical samples for calculating moving average.
+ ///
+ private static Queue m_samples = new Queue(m_maxSamples);
+
+ public static void Update()
+ {
+ int now = Util.EnvironmentTickCount();
+ long memoryNow = GC.GetTotalMemory(false);
+ long memoryDiff = memoryNow - m_lastUpdateMemory;
+
+ if (memoryDiff >= 0)
+ {
+ if (m_samples.Count >= m_maxSamples)
+ m_samples.Dequeue();
+
+ double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
+
+ // This should never happen since it's not useful for updates to occur with no time elapsed, but
+ // protect ourselves from a divide-by-zero just in case.
+ if (elapsed == 0)
+ return;
+
+ m_samples.Enqueue(memoryDiff / (double)elapsed);
+ }
+
+ UpdateLastRecord(memoryNow, now);
+ }
+
+ private static void UpdateLastRecord(long memoryNow, int timeNow)
+ {
+ m_lastUpdateMemory = memoryNow;
+ m_lastUpdateTick = timeNow;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
new file mode 100644
index 0000000..d4cf02f
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -0,0 +1,334 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Manages launching threads and keeping watch over them for timeouts
+ ///
+ public static class Watchdog
+ {
+ /// Timer interval in milliseconds for the watchdog timer
+ const double WATCHDOG_INTERVAL_MS = 2500.0d;
+
+ /// Default timeout in milliseconds before a thread is considered dead
+ public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
+
+ [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
+ public class ThreadWatchdogInfo
+ {
+ public Thread Thread { get; private set; }
+
+ ///
+ /// Approximate tick when this thread was started.
+ ///
+ ///
+ /// Not terribly good since this quickly wraps around.
+ ///
+ public int FirstTick { get; private set; }
+
+ ///
+ /// Last time this heartbeat update was invoked
+ ///
+ public int LastTick { get; set; }
+
+ ///
+ /// Number of milliseconds before we notify that the thread is having a problem.
+ ///
+ public int Timeout { get; set; }
+
+ ///
+ /// Is this thread considered timed out?
+ ///
+ public bool IsTimedOut { get; set; }
+
+ ///
+ /// Will this thread trigger the alarm function if it has timed out?
+ ///
+ public bool AlarmIfTimeout { get; set; }
+
+ ///
+ /// Method execute if alarm goes off. If null then no alarm method is fired.
+ ///
+ public Func AlarmMethod { get; set; }
+
+ public ThreadWatchdogInfo(Thread thread, int timeout)
+ {
+ Thread = thread;
+ Timeout = timeout;
+ FirstTick = Environment.TickCount & Int32.MaxValue;
+ LastTick = FirstTick;
+ }
+ }
+
+ ///
+ /// This event is called whenever a tracked thread is
+ /// stopped or has not called UpdateThread() in time<
+ /// /summary>
+ public static event Action OnWatchdogTimeout;
+
+ private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ private static Dictionary m_threads;
+ private static System.Timers.Timer m_watchdogTimer;
+
+ ///
+ /// Last time the watchdog thread ran.
+ ///
+ ///
+ /// Should run every WATCHDOG_INTERVAL_MS
+ ///
+ public static int LastWatchdogThreadTick { get; private set; }
+
+ static Watchdog()
+ {
+ m_threads = new Dictionary();
+ m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
+ m_watchdogTimer.AutoReset = false;
+ m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
+
+ // Set now so we don't get alerted on the first run
+ LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
+
+ m_watchdogTimer.Start();
+ }
+
+ ///
+ /// Start a new thread that is tracked by the watchdog timer.
+ ///
+ /// The method that will be executed in a new thread
+ /// A name to give to the new thread
+ /// Priority to run the thread at
+ /// True to run this thread as a background thread, otherwise false
+ /// Trigger an alarm function is we have timed out
+ /// The newly created Thread object
+ public static Thread StartThread(
+ ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
+ {
+ return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
+ }
+
+ ///
+ /// Start a new thread that is tracked by the watchdog timer
+ ///
+ /// The method that will be executed in a new thread
+ /// A name to give to the new thread
+ /// Priority to run the thread at
+ /// True to run this thread as a background
+ /// thread, otherwise false
+ /// Trigger an alarm function is we have timed out
+ ///
+ /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
+ /// Normally, this will just return some useful debugging information.
+ ///
+ /// Number of milliseconds to wait until we issue a warning about timeout.
+ /// The newly created Thread object
+ public static Thread StartThread(
+ ThreadStart start, string name, ThreadPriority priority, bool isBackground,
+ bool alarmIfTimeout, Func alarmMethod, int timeout)
+ {
+ Thread thread = new Thread(start);
+ thread.Name = name;
+ thread.Priority = priority;
+ thread.IsBackground = isBackground;
+
+ ThreadWatchdogInfo twi
+ = new ThreadWatchdogInfo(thread, timeout)
+ { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
+
+ m_log.DebugFormat(
+ "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
+
+ lock (m_threads)
+ m_threads.Add(twi.Thread.ManagedThreadId, twi);
+
+ thread.Start();
+
+ return thread;
+ }
+
+ ///
+ /// Marks the current thread as alive
+ ///
+ public static void UpdateThread()
+ {
+ UpdateThread(Thread.CurrentThread.ManagedThreadId);
+ }
+
+ ///
+ /// Stops watchdog tracking on the current thread
+ ///
+ ///
+ /// True if the thread was removed from the list of tracked
+ /// threads, otherwise false
+ ///
+ public static bool RemoveThread()
+ {
+ return RemoveThread(Thread.CurrentThread.ManagedThreadId);
+ }
+
+ private static bool RemoveThread(int threadID)
+ {
+ lock (m_threads)
+ return m_threads.Remove(threadID);
+ }
+
+ public static bool AbortThread(int threadID)
+ {
+ lock (m_threads)
+ {
+ if (m_threads.ContainsKey(threadID))
+ {
+ ThreadWatchdogInfo twi = m_threads[threadID];
+ twi.Thread.Abort();
+ RemoveThread(threadID);
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private static void UpdateThread(int threadID)
+ {
+ ThreadWatchdogInfo threadInfo;
+
+ // Although TryGetValue is not a thread safe operation, we use a try/catch here instead
+ // of a lock for speed. Adding/removing threads is a very rare operation compared to
+ // UpdateThread(), and a single UpdateThread() failure here and there won't break
+ // anything
+ try
+ {
+ if (m_threads.TryGetValue(threadID, out threadInfo))
+ {
+ threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
+ threadInfo.IsTimedOut = false;
+ }
+ else
+ {
+ m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
+ }
+ }
+ catch { }
+ }
+
+ ///
+ /// Get currently watched threads for diagnostic purposes
+ ///
+ ///
+ public static ThreadWatchdogInfo[] GetThreadsInfo()
+ {
+ lock (m_threads)
+ return m_threads.Values.ToArray();
+ }
+
+ ///
+ /// Return the current thread's watchdog info.
+ ///
+ /// The watchdog info. null if the thread isn't being monitored.
+ public static ThreadWatchdogInfo GetCurrentThreadInfo()
+ {
+ lock (m_threads)
+ {
+ if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId))
+ return m_threads[Thread.CurrentThread.ManagedThreadId];
+ }
+
+ return null;
+ }
+
+ ///
+ /// Check watched threads. Fire alarm if appropriate.
+ ///
+ ///
+ ///
+ private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ int now = Environment.TickCount & Int32.MaxValue;
+ int msElapsed = now - LastWatchdogThreadTick;
+
+ if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
+ m_log.WarnFormat(
+ "[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
+ msElapsed, WATCHDOG_INTERVAL_MS);
+
+ LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
+
+ Action callback = OnWatchdogTimeout;
+
+ if (callback != null)
+ {
+ List callbackInfos = null;
+
+ lock (m_threads)
+ {
+ foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
+ {
+ if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
+ {
+ RemoveThread(threadInfo.Thread.ManagedThreadId);
+
+ if (callbackInfos == null)
+ callbackInfos = new List();
+
+ callbackInfos.Add(threadInfo);
+ }
+ else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
+ {
+ threadInfo.IsTimedOut = true;
+
+ if (threadInfo.AlarmIfTimeout)
+ {
+ if (callbackInfos == null)
+ callbackInfos = new List();
+
+ callbackInfos.Add(threadInfo);
+ }
+ }
+ }
+ }
+
+ if (callbackInfos != null)
+ foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
+ callback(callbackInfo);
+ }
+
+ if (MemoryWatchdog.Enabled)
+ MemoryWatchdog.Update();
+
+ m_watchdogTimer.Start();
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index ab8d95a..2a8ae38 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -40,6 +40,7 @@ using log4net.Core;
using log4net.Repository;
using OpenSim.Framework;
using OpenSim.Framework.Console;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Monitoring;
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 3de7f9c..f57ea76 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -45,6 +45,7 @@ using OpenMetaverse.StructuredData;
using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 3252251..8d50151 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -32,6 +32,7 @@ using System.Reflection;
using log4net;
using HttpServer;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 35a8dee..5adbcd1 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -34,6 +34,7 @@ using HttpServer;
using OpenMetaverse;
using System.Reflection;
using log4net;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
deleted file mode 100644
index 54e3d1a..0000000
--- a/OpenSim/Framework/Watchdog.cs
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using log4net;
-
-namespace OpenSim.Framework
-{
- ///
- /// Manages launching threads and keeping watch over them for timeouts
- ///
- public static class Watchdog
- {
- /// Timer interval in milliseconds for the watchdog timer
- const double WATCHDOG_INTERVAL_MS = 2500.0d;
-
- /// Default timeout in milliseconds before a thread is considered dead
- public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
-
- [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
- public class ThreadWatchdogInfo
- {
- public Thread Thread { get; private set; }
-
- ///
- /// Approximate tick when this thread was started.
- ///
- ///
- /// Not terribly good since this quickly wraps around.
- ///
- public int FirstTick { get; private set; }
-
- ///
- /// Last time this heartbeat update was invoked
- ///
- public int LastTick { get; set; }
-
- ///
- /// Number of milliseconds before we notify that the thread is having a problem.
- ///
- public int Timeout { get; set; }
-
- ///
- /// Is this thread considered timed out?
- ///
- public bool IsTimedOut { get; set; }
-
- ///
- /// Will this thread trigger the alarm function if it has timed out?
- ///
- public bool AlarmIfTimeout { get; set; }
-
- ///
- /// Method execute if alarm goes off. If null then no alarm method is fired.
- ///
- public Func AlarmMethod { get; set; }
-
- public ThreadWatchdogInfo(Thread thread, int timeout)
- {
- Thread = thread;
- Timeout = timeout;
- FirstTick = Environment.TickCount & Int32.MaxValue;
- LastTick = FirstTick;
- }
- }
-
- ///
- /// This event is called whenever a tracked thread is
- /// stopped or has not called UpdateThread() in time<
- /// /summary>
- public static event Action OnWatchdogTimeout;
-
- private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- private static Dictionary m_threads;
- private static System.Timers.Timer m_watchdogTimer;
-
- ///
- /// Last time the watchdog thread ran.
- ///
- ///
- /// Should run every WATCHDOG_INTERVAL_MS
- ///
- public static int LastWatchdogThreadTick { get; private set; }
-
- static Watchdog()
- {
- m_threads = new Dictionary();
- m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
- m_watchdogTimer.AutoReset = false;
- m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
-
- // Set now so we don't get alerted on the first run
- LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
-
- m_watchdogTimer.Start();
- }
-
- ///
- /// Start a new thread that is tracked by the watchdog timer.
- ///
- /// The method that will be executed in a new thread
- /// A name to give to the new thread
- /// Priority to run the thread at
- /// True to run this thread as a background thread, otherwise false
- /// Trigger an alarm function is we have timed out
- /// The newly created Thread object
- public static Thread StartThread(
- ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
- {
- return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
- }
-
- ///
- /// Start a new thread that is tracked by the watchdog timer
- ///
- /// The method that will be executed in a new thread
- /// A name to give to the new thread
- /// Priority to run the thread at
- /// True to run this thread as a background
- /// thread, otherwise false
- /// Trigger an alarm function is we have timed out
- ///
- /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
- /// Normally, this will just return some useful debugging information.
- ///
- /// Number of milliseconds to wait until we issue a warning about timeout.
- /// The newly created Thread object
- public static Thread StartThread(
- ThreadStart start, string name, ThreadPriority priority, bool isBackground,
- bool alarmIfTimeout, Func alarmMethod, int timeout)
- {
- Thread thread = new Thread(start);
- thread.Name = name;
- thread.Priority = priority;
- thread.IsBackground = isBackground;
-
- ThreadWatchdogInfo twi
- = new ThreadWatchdogInfo(thread, timeout)
- { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
-
- m_log.DebugFormat(
- "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
-
- lock (m_threads)
- m_threads.Add(twi.Thread.ManagedThreadId, twi);
-
- thread.Start();
-
- return thread;
- }
-
- ///
- /// Marks the current thread as alive
- ///
- public static void UpdateThread()
- {
- UpdateThread(Thread.CurrentThread.ManagedThreadId);
- }
-
- ///
- /// Stops watchdog tracking on the current thread
- ///
- ///
- /// True if the thread was removed from the list of tracked
- /// threads, otherwise false
- ///
- public static bool RemoveThread()
- {
- return RemoveThread(Thread.CurrentThread.ManagedThreadId);
- }
-
- private static bool RemoveThread(int threadID)
- {
- lock (m_threads)
- return m_threads.Remove(threadID);
- }
-
- public static bool AbortThread(int threadID)
- {
- lock (m_threads)
- {
- if (m_threads.ContainsKey(threadID))
- {
- ThreadWatchdogInfo twi = m_threads[threadID];
- twi.Thread.Abort();
- RemoveThread(threadID);
-
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
- private static void UpdateThread(int threadID)
- {
- ThreadWatchdogInfo threadInfo;
-
- // Although TryGetValue is not a thread safe operation, we use a try/catch here instead
- // of a lock for speed. Adding/removing threads is a very rare operation compared to
- // UpdateThread(), and a single UpdateThread() failure here and there won't break
- // anything
- try
- {
- if (m_threads.TryGetValue(threadID, out threadInfo))
- {
- threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
- threadInfo.IsTimedOut = false;
- }
- else
- {
- m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
- }
- }
- catch { }
- }
-
- ///
- /// Get currently watched threads for diagnostic purposes
- ///
- ///
- public static ThreadWatchdogInfo[] GetThreadsInfo()
- {
- lock (m_threads)
- return m_threads.Values.ToArray();
- }
-
- ///
- /// Return the current thread's watchdog info.
- ///
- /// The watchdog info. null if the thread isn't being monitored.
- public static ThreadWatchdogInfo GetCurrentThreadInfo()
- {
- lock (m_threads)
- {
- if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId))
- return m_threads[Thread.CurrentThread.ManagedThreadId];
- }
-
- return null;
- }
-
- ///
- /// Check watched threads. Fire alarm if appropriate.
- ///
- ///
- ///
- private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
- {
- int now = Environment.TickCount & Int32.MaxValue;
- int msElapsed = now - LastWatchdogThreadTick;
-
- if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
- m_log.WarnFormat(
- "[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
- msElapsed, WATCHDOG_INTERVAL_MS);
-
- LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
-
- Action callback = OnWatchdogTimeout;
-
- if (callback != null)
- {
- List callbackInfos = null;
-
- lock (m_threads)
- {
- foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
- {
- if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
- {
- RemoveThread(threadInfo.Thread.ManagedThreadId);
-
- if (callbackInfos == null)
- callbackInfos = new List();
-
- callbackInfos.Add(threadInfo);
- }
- else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
- {
- threadInfo.IsTimedOut = true;
-
- if (threadInfo.AlarmIfTimeout)
- {
- if (callbackInfos == null)
- callbackInfos = new List();
-
- callbackInfos.Add(threadInfo);
- }
- }
- }
- }
-
- if (callbackInfos != null)
- foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
- callback(callbackInfo);
- }
-
- if (MemoryWatchdog.Enabled)
- MemoryWatchdog.Update();
-
- m_watchdogTimer.Start();
- }
- }
-}
\ No newline at end of file
--
cgit v1.1
From 1133f81dce840e394763a4eea03067fa8d18f0e1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 27 Jul 2012 20:40:25 +0100
Subject: Remove a couple of compiler warnings pointed out by SignpostMarv
---
OpenSim/Framework/Servers/BaseOpenSimServer.cs | 1 -
1 file changed, 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 2a8ae38..7a5c16d 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -43,7 +43,6 @@ using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
-using OpenSim.Framework.Monitoring;
using Timer=System.Timers.Timer;
using OpenMetaverse;
--
cgit v1.1
From f3c5ce1bbd86fafa0e436efe5de804b65d64b8af Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 27 Jul 2012 22:20:08 +0100
Subject: minor: Comment out unused MemoryWatchdog.m_churnRatePerMillisecond -
this is currently calculated dynamically
---
OpenSim/Framework/Monitoring/MemoryWatchdog.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
index 6599613..a23cf1f 100644
--- a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
+++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
@@ -89,7 +89,7 @@ namespace OpenSim.Framework.Monitoring
///
/// Memory churn rate per millisecond.
///
- private static double m_churnRatePerMillisecond;
+// private static double m_churnRatePerMillisecond;
///
/// Historical samples for calculating moving average.
--
cgit v1.1
From adbdb220df4aacc93e81eeb2eb1854825e4db7fb Mon Sep 17 00:00:00 2001
From: SignpostMarv
Date: Fri, 27 Jul 2012 22:15:25 +0100
Subject: making first run more resilient to bad input (loop until good input,
rather than crash)
---
OpenSim/Framework/RegionInfo.cs | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index a505524..2080a16 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -480,9 +480,16 @@ namespace OpenSim.Framework
MainConsole.Instance.Output("=====================================\n");
if (name == String.Empty)
- name = MainConsole.Instance.CmdPrompt("New region name", name);
- if (name == String.Empty)
- throw new Exception("Cannot interactively create region with no name");
+ {
+ while (name.Trim() == string.Empty)
+ {
+ name = MainConsole.Instance.CmdPrompt("New region name", name);
+ if (name.Trim() == string.Empty)
+ {
+ MainConsole.Instance.Output("Cannot interactively create region with no name");
+ }
+ }
+ }
source.AddConfig(name);
@@ -513,15 +520,20 @@ namespace OpenSim.Framework
//
allKeys.Remove("RegionUUID");
string regionUUID = config.GetString("RegionUUID", string.Empty);
- if (regionUUID == String.Empty)
+ if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{
UUID newID = UUID.Random();
-
- regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
+ while (RegionID == UUID.Zero)
+ {
+ regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
+ if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
+ {
+ MainConsole.Instance.Output("RegionUUID must be a valid UUID");
+ }
+ }
config.Set("RegionUUID", regionUUID);
}
- RegionID = new UUID(regionUUID);
originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
// Location
--
cgit v1.1