mirror of
https://github.com/opensim/opensim.git
synced 2026-08-01 06:06:06 +08:00
* Adds an active log to the WebStats console. for an example of it in use as it is right now see http://wmcv.com:9000/SStats/
* It still isn't quite ready to be used mainstream. * A couple of things to note, it doesn't keep track of the logs if nobody is looking at the stats. * It doesn't read the whole log file. Just the last 10 lines of the stream. Tested to 1GB+ logfiles with no noticeable performance issues.
This commit is contained in:
@@ -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<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>();
|
||||
private List<Scene> m_scene = new List<Scene>();
|
||||
private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>();
|
||||
private Dictionary<UUID, USimStatsData> m_simstatsCounters = new Dictionary<UUID, USimStatsData>();
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user