diff options
author | Teravus Ovares | 2009-01-05 04:09:04 +0000 |
---|---|---|
committer | Teravus Ovares | 2009-01-05 04:09:04 +0000 |
commit | e4a8cc192dd16930718ff18838aa82e6187741bf (patch) | |
tree | a41492dc43a435fcd8a9395fb1f6aff8ae03b702 /OpenSim/Region/UserStatistics/WebStatsModule.cs | |
parent | * Another minor GenericMessage fix - If we assume the method names are case-i... (diff) | |
download | opensim-SC-e4a8cc192dd16930718ff18838aa82e6187741bf.zip opensim-SC-e4a8cc192dd16930718ff18838aa82e6187741bf.tar.gz opensim-SC-e4a8cc192dd16930718ff18838aa82e6187741bf.tar.bz2 opensim-SC-e4a8cc192dd16930718ff18838aa82e6187741bf.tar.xz |
* 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.
Diffstat (limited to 'OpenSim/Region/UserStatistics/WebStatsModule.cs')
-rw-r--r-- | OpenSim/Region/UserStatistics/WebStatsModule.cs | 66 |
1 files changed, 63 insertions, 3 deletions
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 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections; | 2 | using System.Collections; |
3 | using System.Collections.Generic; | 3 | using System.Collections.Generic; |
4 | using System.IO; | ||
4 | using System.Net; // to be used for REST-->Grid shortly | 5 | using System.Net; // to be used for REST-->Grid shortly |
5 | using System.Reflection; | 6 | using System.Reflection; |
7 | using System.Text; | ||
8 | using System.Threading; | ||
6 | using log4net; | 9 | using log4net; |
7 | using Nini.Config; | 10 | using Nini.Config; |
8 | using OpenMetaverse; | 11 | using OpenMetaverse; |
@@ -25,14 +28,19 @@ namespace OpenSim.Region.UserStatistics | |||
25 | { | 28 | { |
26 | private static readonly ILog m_log = | 29 | private static readonly ILog m_log = |
27 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 30 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
31 | |||
28 | private static SqliteConnection dbConn; | 32 | private static SqliteConnection dbConn; |
29 | private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>(); | 33 | private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>(); |
30 | private List<Scene> m_scene = new List<Scene>(); | 34 | private List<Scene> m_scene = new List<Scene>(); |
31 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); | 35 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); |
32 | private Dictionary<UUID, USimStatsData> m_simstatsCounters = new Dictionary<UUID, USimStatsData>(); | 36 | private Dictionary<UUID, USimStatsData> m_simstatsCounters = new Dictionary<UUID, USimStatsData>(); |
33 | private const int updateStatsMod = 6; | 37 | private const int updateStatsMod = 6; |
38 | private int updateLogMod = 1; | ||
39 | private volatile int updateLogCounter = 0; | ||
34 | private volatile int concurrencyCounter = 0; | 40 | private volatile int concurrencyCounter = 0; |
35 | private bool enabled = false; | 41 | private bool enabled = false; |
42 | private string m_loglines = String.Empty; | ||
43 | private volatile int lastHit = 12000; | ||
36 | 44 | ||
37 | 45 | ||
38 | public virtual void Initialise(Scene scene, IConfigSource config) | 46 | public virtual void Initialise(Scene scene, IConfigSource config) |
@@ -42,7 +50,8 @@ namespace OpenSim.Region.UserStatistics | |||
42 | { | 50 | { |
43 | cnfg = config.Configs["WebStats"]; | 51 | cnfg = config.Configs["WebStats"]; |
44 | enabled = cnfg.GetBoolean("enabled", false); | 52 | enabled = cnfg.GetBoolean("enabled", false); |
45 | 53 | ||
54 | |||
46 | } | 55 | } |
47 | catch (Exception) | 56 | catch (Exception) |
48 | { | 57 | { |
@@ -68,12 +77,14 @@ namespace OpenSim.Region.UserStatistics | |||
68 | Updater_distributor updatedep = new Updater_distributor(); | 77 | Updater_distributor updatedep = new Updater_distributor(); |
69 | ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX(); | 78 | ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX(); |
70 | SimStatsAJAX ajSimStats = new SimStatsAJAX(); | 79 | SimStatsAJAX ajSimStats = new SimStatsAJAX(); |
80 | LogLinesAJAX ajLogLines = new LogLinesAJAX(); | ||
71 | reports.Add("", rep); | 81 | reports.Add("", rep); |
72 | reports.Add("index.aspx", rep); | 82 | reports.Add("index.aspx", rep); |
73 | reports.Add("prototype.js", protodep); | 83 | reports.Add("prototype.js", protodep); |
74 | reports.Add("updater.js", updatedep); | 84 | reports.Add("updater.js", updatedep); |
75 | reports.Add("activeconnectionsajax.ajax", ajConnections); | 85 | reports.Add("activeconnectionsajax.ajax", ajConnections); |
76 | reports.Add("simstatsajax.ajax", ajSimStats); | 86 | reports.Add("simstatsajax.ajax", ajSimStats); |
87 | reports.Add("activelogajax.ajax", ajLogLines); | ||
77 | 88 | ||
78 | scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest); | 89 | scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest); |
79 | 90 | ||
@@ -95,10 +106,17 @@ namespace OpenSim.Region.UserStatistics | |||
95 | 106 | ||
96 | try | 107 | try |
97 | { | 108 | { |
98 | 109 | // Ignore the update if there's a report running right now | |
99 | if (concurrencyCounter > 0) | 110 | // ignore the update if there hasn't been a hit in 30 seconds. |
111 | if (concurrencyCounter > 0 && System.Environment.TickCount - lastHit < 30000) | ||
100 | return; | 112 | return; |
101 | 113 | ||
114 | if ((updateLogCounter++ % updateLogMod) == 0) | ||
115 | { | ||
116 | m_loglines = readLogLines(10); | ||
117 | if (updateLogCounter > 10000) updateLogCounter = 1; | ||
118 | } | ||
119 | |||
102 | USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; | 120 | USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; |
103 | 121 | ||
104 | if ((++ss.StatsCounter % updateStatsMod) == 0) | 122 | if ((++ss.StatsCounter % updateStatsMod) == 0) |
@@ -114,6 +132,7 @@ namespace OpenSim.Region.UserStatistics | |||
114 | 132 | ||
115 | public Hashtable HandleStatsRequest(Hashtable request) | 133 | public Hashtable HandleStatsRequest(Hashtable request) |
116 | { | 134 | { |
135 | lastHit = System.Environment.TickCount; | ||
117 | Hashtable responsedata = new Hashtable(); | 136 | Hashtable responsedata = new Hashtable(); |
118 | string regpath = request["uri"].ToString(); | 137 | string regpath = request["uri"].ToString(); |
119 | int response_code = 404; | 138 | int response_code = 404; |
@@ -130,6 +149,7 @@ namespace OpenSim.Region.UserStatistics | |||
130 | repParams["DatabaseConnection"] = dbConn; | 149 | repParams["DatabaseConnection"] = dbConn; |
131 | repParams["Scenes"] = m_scene; | 150 | repParams["Scenes"] = m_scene; |
132 | repParams["SimStats"] = m_simstatsCounters; | 151 | repParams["SimStats"] = m_simstatsCounters; |
152 | repParams["LogLines"] = m_loglines; | ||
133 | 153 | ||
134 | concurrencyCounter++; | 154 | concurrencyCounter++; |
135 | 155 | ||
@@ -245,6 +265,7 @@ namespace OpenSim.Region.UserStatistics | |||
245 | { | 265 | { |
246 | lock (m_scene) | 266 | lock (m_scene) |
247 | { | 267 | { |
268 | updateLogMod = m_scene.Count * 2; | ||
248 | foreach (Scene scene in m_scene) | 269 | foreach (Scene scene in m_scene) |
249 | { | 270 | { |
250 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 271 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
@@ -315,6 +336,45 @@ namespace OpenSim.Region.UserStatistics | |||
315 | 336 | ||
316 | } | 337 | } |
317 | 338 | ||
339 | public string readLogLines( int amount) | ||
340 | { | ||
341 | Encoding encoding = Encoding.ASCII; | ||
342 | int sizeOfChar = encoding.GetByteCount("\n"); | ||
343 | byte[] buffer = encoding.GetBytes("\n"); | ||
344 | string logfile = Util.logDir() + "/" + "OpenSim.log"; | ||
345 | FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); | ||
346 | Int64 tokenCount = 0; | ||
347 | Int64 endPosition = fs.Length / sizeOfChar; | ||
348 | |||
349 | for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar) | ||
350 | { | ||
351 | fs.Seek(-position, SeekOrigin.End); | ||
352 | fs.Read(buffer, 0, buffer.Length); | ||
353 | |||
354 | if (encoding.GetString(buffer) == "\n") | ||
355 | { | ||
356 | tokenCount++; | ||
357 | if (tokenCount == amount) | ||
358 | { | ||
359 | byte[] returnBuffer = new byte[fs.Length - fs.Position]; | ||
360 | fs.Read(returnBuffer, 0, returnBuffer.Length); | ||
361 | fs.Close(); | ||
362 | fs.Dispose(); | ||
363 | return encoding.GetString(returnBuffer); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | // handle case where number of tokens in file is less than numberOfTokens | ||
369 | fs.Seek(0, SeekOrigin.Begin); | ||
370 | buffer = new byte[fs.Length]; | ||
371 | fs.Read(buffer, 0, buffer.Length); | ||
372 | fs.Close(); | ||
373 | fs.Dispose(); | ||
374 | return encoding.GetString(buffer); | ||
375 | |||
376 | } | ||
377 | |||
318 | public UUID GetRegionUUIDFromHandle(ulong regionhandle) | 378 | public UUID GetRegionUUIDFromHandle(ulong regionhandle) |
319 | { | 379 | { |
320 | lock (m_scene) | 380 | lock (m_scene) |