throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
HTMLUtil.UL_O(ref output, "");
+
foreach (string throttlename in throttles.Keys)
{
HTMLUtil.LI_O(ref output, "");
diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs
index 02b15ad..eac4a7e 100644
--- a/OpenSim/Region/UserStatistics/Default_Report.cs
+++ b/OpenSim/Region/UserStatistics/Default_Report.cs
@@ -76,9 +76,9 @@ TD.align_top { vertical-align: top; }
HTMLUtil.HtmlHeaders_O(ref output);
HTMLUtil.InsertProtoTypeAJAX(ref output);
- string[] ajaxUpdaterDivs = new string[2];
- int[] ajaxUpdaterSeconds = new int[2];
- string[] ajaxUpdaterReportFragments = new string[2];
+ string[] ajaxUpdaterDivs = new string[3];
+ int[] ajaxUpdaterSeconds = new int[3];
+ string[] ajaxUpdaterReportFragments = new string[3];
ajaxUpdaterDivs[0] = "activeconnections";
ajaxUpdaterSeconds[0] = 10;
@@ -88,6 +88,10 @@ TD.align_top { vertical-align: top; }
ajaxUpdaterSeconds[1] = 20;
ajaxUpdaterReportFragments[1] = "simstatsajax.ajax";
+ ajaxUpdaterDivs[2] = "activelog";
+ ajaxUpdaterSeconds[2] = 5;
+ ajaxUpdaterReportFragments[2] = "activelogajax.ajax";
+
HTMLUtil.InsertPeriodicUpdaters(ref output, ajaxUpdaterDivs, ajaxUpdaterSeconds, ajaxUpdaterReportFragments);
output.Append(STYLESHEET);
@@ -152,11 +156,11 @@ TD.align_top { vertical-align: top; }
HTMLUtil.TABLE_O(ref output, "");
HTMLUtil.TR_O(ref output, "");
HTMLUtil.TD_O(ref output, "align_top");
- output.Append("loading...
");
+ output.Append("Active Connections loading...
");
HTMLUtil.TD_C(ref output);
HTMLUtil.TD_O(ref output, "align_top");
- output.Append("loading...
");
-
+ output.Append("SimStats loading...
");
+ output.Append("ActiveLog loading...
");
HTMLUtil.TD_C(ref output);
HTMLUtil.TR_C(ref output);
HTMLUtil.TABLE_C(ref output);
diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs
new file mode 100644
index 0000000..9626c12
--- /dev/null
+++ b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Region.Environment.Scenes;
+using OpenSim.Framework.Statistics;
+
+namespace OpenSim.Region.UserStatistics
+{
+ public class LogLinesAJAX : IStatsController
+ {
+ private Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
+
+ private Regex webFormat = new Regex(@"[^\s]*\s([^,]*),[^\s]*\s([A-Z]*)[^\s-][^\[]*\[([^\]]*)\]([^\n]*)",
+ RegexOptions.Singleline | RegexOptions.Compiled);
+ private Regex TitleColor = new Regex(@"[^\s]*\s(?:[^,]*),[^\s]*\s(?:[A-Z]*)[^\s-][^\[]*\[([^\]]*)\](?:[^\n]*)",
+ RegexOptions.Singleline | RegexOptions.Compiled);
+
+
+ #region IStatsController Members
+
+ public Hashtable ProcessModel(Hashtable pParams)
+ {
+ Hashtable nh = new Hashtable();
+ nh.Add("loglines", pParams["LogLines"]);
+ return nh;
+ }
+
+ public string RenderView(Hashtable pModelResult)
+ {
+ StringBuilder output = new StringBuilder();
+
+ HTMLUtil.HR(ref output, "");
+ output.Append("ActiveLog
\n");
+
+ string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n");
+
+ string[] result = Regex.Split(tmp, "\n");
+
+ string formatopen = "";
+ string formatclose = "";
+
+ for (int i = 0; i < result.Length;i++ )
+ {
+ if (result[i].Length >= 30)
+ {
+ string logtype = result[i].Substring(24, 6);
+ switch (logtype)
+ {
+ case "WARN ":
+ formatopen = "";
+ formatclose = "";
+ break;
+
+ case "ERROR ":
+ formatopen = "";
+ formatclose = "";
+ break;
+
+ default:
+ formatopen = "";
+ formatclose = "";
+ break;
+
+ }
+ }
+ StringBuilder replaceStr = new StringBuilder();
+ //string titlecolorresults =
+
+ string formatresult = Regex.Replace(TitleColor.Replace(result[i], "$1"), "[^ABCDEFabcdef0-9]", "");
+ if (formatresult.Length > 6)
+ {
+ formatresult = formatresult.Substring(0, 6);
+
+ }
+ for (int j = formatresult.Length; j <= 5; j++)
+ formatresult += "0";
+ replaceStr.Append("$1 - [$3] $4
");
+ string repstr = replaceStr.ToString();
+
+ output.Append(formatopen);
+ output.Append(webFormat.Replace(result[i], repstr));
+ output.Append(formatclose);
+ }
+
+
+ return output.ToString();
+ }
+
+ #endregion
+ }
+}
diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
index f6dd1d6..26fe3d4 100644
--- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
+++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
@@ -21,7 +21,6 @@ namespace OpenSim.Region.UserStatistics
Hashtable nh = new Hashtable();
nh.Add("hdata", m_scene);
nh.Add("simstats", pParams["SimStats"]);
-
return nh;
}
@@ -181,7 +180,9 @@ namespace OpenSim.Region.UserStatistics
HTMLUtil.TD_C(ref output);
HTMLUtil.TR_C(ref output);
HTMLUtil.TABLE_C(ref output);
+
}
+
return output.ToString();
}
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs
index 4eb8cb7..832c763 100644
--- a/OpenSim/Region/UserStatistics/WebStatsModule.cs
+++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs
@@ -1,8 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.IO;
using System.Net; // to be used for REST-->Grid shortly
using System.Reflection;
+using System.Text;
+using System.Threading;
using log4net;
using Nini.Config;
using OpenMetaverse;
@@ -25,14 +28,19 @@ namespace OpenSim.Region.UserStatistics
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
private static SqliteConnection dbConn;
private Dictionary m_sessions = new Dictionary();
private List m_scene = new List();
private Dictionary reports = new Dictionary();
private Dictionary m_simstatsCounters = new Dictionary();
private const int updateStatsMod = 6;
+ private int updateLogMod = 1;
+ private volatile int updateLogCounter = 0;
private volatile int concurrencyCounter = 0;
private bool enabled = false;
+ private string m_loglines = String.Empty;
+ private volatile int lastHit = 12000;
public virtual void Initialise(Scene scene, IConfigSource config)
@@ -42,7 +50,8 @@ namespace OpenSim.Region.UserStatistics
{
cnfg = config.Configs["WebStats"];
enabled = cnfg.GetBoolean("enabled", false);
-
+
+
}
catch (Exception)
{
@@ -68,12 +77,14 @@ namespace OpenSim.Region.UserStatistics
Updater_distributor updatedep = new Updater_distributor();
ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX();
SimStatsAJAX ajSimStats = new SimStatsAJAX();
+ LogLinesAJAX ajLogLines = new LogLinesAJAX();
reports.Add("", rep);
reports.Add("index.aspx", rep);
reports.Add("prototype.js", protodep);
reports.Add("updater.js", updatedep);
reports.Add("activeconnectionsajax.ajax", ajConnections);
reports.Add("simstatsajax.ajax", ajSimStats);
+ reports.Add("activelogajax.ajax", ajLogLines);
scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest);
@@ -95,10 +106,17 @@ namespace OpenSim.Region.UserStatistics
try
{
-
- if (concurrencyCounter > 0)
+ // Ignore the update if there's a report running right now
+ // ignore the update if there hasn't been a hit in 30 seconds.
+ if (concurrencyCounter > 0 && System.Environment.TickCount - lastHit < 30000)
return;
+ if ((updateLogCounter++ % updateLogMod) == 0)
+ {
+ m_loglines = readLogLines(10);
+ if (updateLogCounter > 10000) updateLogCounter = 1;
+ }
+
USimStatsData ss = m_simstatsCounters[stats.RegionUUID];
if ((++ss.StatsCounter % updateStatsMod) == 0)
@@ -114,6 +132,7 @@ namespace OpenSim.Region.UserStatistics
public Hashtable HandleStatsRequest(Hashtable request)
{
+ lastHit = System.Environment.TickCount;
Hashtable responsedata = new Hashtable();
string regpath = request["uri"].ToString();
int response_code = 404;
@@ -130,6 +149,7 @@ namespace OpenSim.Region.UserStatistics
repParams["DatabaseConnection"] = dbConn;
repParams["Scenes"] = m_scene;
repParams["SimStats"] = m_simstatsCounters;
+ repParams["LogLines"] = m_loglines;
concurrencyCounter++;
@@ -245,6 +265,7 @@ namespace OpenSim.Region.UserStatistics
{
lock (m_scene)
{
+ updateLogMod = m_scene.Count * 2;
foreach (Scene scene in m_scene)
{
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
@@ -315,6 +336,45 @@ namespace OpenSim.Region.UserStatistics
}
+ public string readLogLines( int amount)
+ {
+ Encoding encoding = Encoding.ASCII;
+ int sizeOfChar = encoding.GetByteCount("\n");
+ byte[] buffer = encoding.GetBytes("\n");
+ string logfile = Util.logDir() + "/" + "OpenSim.log";
+ FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ Int64 tokenCount = 0;
+ Int64 endPosition = fs.Length / sizeOfChar;
+
+ for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar)
+ {
+ fs.Seek(-position, SeekOrigin.End);
+ fs.Read(buffer, 0, buffer.Length);
+
+ if (encoding.GetString(buffer) == "\n")
+ {
+ tokenCount++;
+ if (tokenCount == amount)
+ {
+ byte[] returnBuffer = new byte[fs.Length - fs.Position];
+ fs.Read(returnBuffer, 0, returnBuffer.Length);
+ fs.Close();
+ fs.Dispose();
+ return encoding.GetString(returnBuffer);
+ }
+ }
+ }
+
+ // handle case where number of tokens in file is less than numberOfTokens
+ fs.Seek(0, SeekOrigin.Begin);
+ buffer = new byte[fs.Length];
+ fs.Read(buffer, 0, buffer.Length);
+ fs.Close();
+ fs.Dispose();
+ return encoding.GetString(buffer);
+
+ }
+
public UUID GetRegionUUIDFromHandle(ulong regionhandle)
{
lock (m_scene)
--
cgit v1.1