diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Monitoring/Stats/Stat.cs | 102 |
1 files changed, 95 insertions, 7 deletions
diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs index f91251b..a7cb2a6 100644 --- a/OpenSim/Framework/Monitoring/Stats/Stat.cs +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs | |||
@@ -27,15 +27,23 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
30 | using System.Text; | 32 | using System.Text; |
33 | using log4net; | ||
34 | using OpenMetaverse.StructuredData; | ||
31 | 35 | ||
32 | namespace OpenSim.Framework.Monitoring | 36 | namespace OpenSim.Framework.Monitoring |
33 | { | 37 | { |
34 | /// <summary> | 38 | /// <summary> |
35 | /// Holds individual statistic details | 39 | /// Holds individual statistic details |
36 | /// </summary> | 40 | /// </summary> |
37 | public class Stat | 41 | public class Stat : IDisposable |
38 | { | 42 | { |
43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | public static readonly char[] DisallowedShortNameCharacters = { '.' }; | ||
46 | |||
39 | /// <summary> | 47 | /// <summary> |
40 | /// Category of this stat (e.g. cache, scene, etc). | 48 | /// Category of this stat (e.g. cache, scene, etc). |
41 | /// </summary> | 49 | /// </summary> |
@@ -93,7 +101,7 @@ namespace OpenSim.Framework.Monitoring | |||
93 | /// <remarks> | 101 | /// <remarks> |
94 | /// Will be null if no measures of interest require samples. | 102 | /// Will be null if no measures of interest require samples. |
95 | /// </remarks> | 103 | /// </remarks> |
96 | private static Queue<double> m_samples; | 104 | private Queue<double> m_samples; |
97 | 105 | ||
98 | /// <summary> | 106 | /// <summary> |
99 | /// Maximum number of statistical samples. | 107 | /// Maximum number of statistical samples. |
@@ -160,6 +168,13 @@ namespace OpenSim.Framework.Monitoring | |||
160 | throw new Exception( | 168 | throw new Exception( |
161 | string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category)); | 169 | string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category)); |
162 | 170 | ||
171 | foreach (char c in DisallowedShortNameCharacters) | ||
172 | { | ||
173 | if (shortName.IndexOf(c) != -1) | ||
174 | shortName = shortName.Replace(c, '#'); | ||
175 | // throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c)); | ||
176 | } | ||
177 | |||
163 | ShortName = shortName; | 178 | ShortName = shortName; |
164 | Name = name; | 179 | Name = name; |
165 | Description = description; | 180 | Description = description; |
@@ -181,6 +196,12 @@ namespace OpenSim.Framework.Monitoring | |||
181 | Verbosity = verbosity; | 196 | Verbosity = verbosity; |
182 | } | 197 | } |
183 | 198 | ||
199 | // IDisposable.Dispose() | ||
200 | public virtual void Dispose() | ||
201 | { | ||
202 | return; | ||
203 | } | ||
204 | |||
184 | /// <summary> | 205 | /// <summary> |
185 | /// Record a value in the sample set. | 206 | /// Record a value in the sample set. |
186 | /// </summary> | 207 | /// </summary> |
@@ -196,6 +217,8 @@ namespace OpenSim.Framework.Monitoring | |||
196 | if (m_samples.Count >= m_maxSamples) | 217 | if (m_samples.Count >= m_maxSamples) |
197 | m_samples.Dequeue(); | 218 | m_samples.Dequeue(); |
198 | 219 | ||
220 | // m_log.DebugFormat("[STAT]: Recording value {0} for {1}", newValue, Name); | ||
221 | |||
199 | m_samples.Enqueue(newValue); | 222 | m_samples.Enqueue(newValue); |
200 | } | 223 | } |
201 | } | 224 | } |
@@ -203,35 +226,100 @@ namespace OpenSim.Framework.Monitoring | |||
203 | public virtual string ToConsoleString() | 226 | public virtual string ToConsoleString() |
204 | { | 227 | { |
205 | StringBuilder sb = new StringBuilder(); | 228 | StringBuilder sb = new StringBuilder(); |
206 | sb.AppendFormat("{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName); | 229 | sb.AppendFormat( |
230 | "{0}.{1}.{2} : {3}{4}", | ||
231 | Category, | ||
232 | Container, | ||
233 | ShortName, | ||
234 | Value, | ||
235 | string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName)); | ||
207 | 236 | ||
208 | AppendMeasuresOfInterest(sb); | 237 | AppendMeasuresOfInterest(sb); |
209 | 238 | ||
210 | return sb.ToString(); | 239 | return sb.ToString(); |
211 | } | 240 | } |
212 | 241 | ||
213 | protected void AppendMeasuresOfInterest(StringBuilder sb) | 242 | public virtual OSDMap ToOSDMap() |
214 | { | 243 | { |
215 | if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime) | 244 | OSDMap ret = new OSDMap(); |
216 | == MeasuresOfInterest.AverageChangeOverTime) | 245 | ret.Add("StatType", "Stat"); // used by overloading classes to denote type of stat |
246 | |||
247 | ret.Add("Category", OSD.FromString(Category)); | ||
248 | ret.Add("Container", OSD.FromString(Container)); | ||
249 | ret.Add("ShortName", OSD.FromString(ShortName)); | ||
250 | ret.Add("Name", OSD.FromString(Name)); | ||
251 | ret.Add("Description", OSD.FromString(Description)); | ||
252 | ret.Add("UnitName", OSD.FromString(UnitName)); | ||
253 | ret.Add("Value", OSD.FromReal(Value)); | ||
254 | |||
255 | double lastChangeOverTime, averageChangeOverTime; | ||
256 | if (ComputeMeasuresOfInterest(out lastChangeOverTime, out averageChangeOverTime)) | ||
257 | { | ||
258 | ret.Add("LastChangeOverTime", OSD.FromReal(lastChangeOverTime)); | ||
259 | ret.Add("AverageChangeOverTime", OSD.FromReal(averageChangeOverTime)); | ||
260 | } | ||
261 | |||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | // Compute the averages over time and return same. | ||
266 | // Return 'true' if averages were actually computed. 'false' if no average info. | ||
267 | public bool ComputeMeasuresOfInterest(out double lastChangeOverTime, out double averageChangeOverTime) | ||
268 | { | ||
269 | bool ret = false; | ||
270 | lastChangeOverTime = 0; | ||
271 | averageChangeOverTime = 0; | ||
272 | |||
273 | if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime) == MeasuresOfInterest.AverageChangeOverTime) | ||
217 | { | 274 | { |
218 | double totalChange = 0; | 275 | double totalChange = 0; |
276 | double? penultimateSample = null; | ||
219 | double? lastSample = null; | 277 | double? lastSample = null; |
220 | 278 | ||
221 | lock (m_samples) | 279 | lock (m_samples) |
222 | { | 280 | { |
281 | // m_log.DebugFormat( | ||
282 | // "[STAT]: Samples for {0} are {1}", | ||
283 | // Name, string.Join(",", m_samples.Select(s => s.ToString()).ToArray())); | ||
284 | |||
223 | foreach (double s in m_samples) | 285 | foreach (double s in m_samples) |
224 | { | 286 | { |
225 | if (lastSample != null) | 287 | if (lastSample != null) |
226 | totalChange += s - (double)lastSample; | 288 | totalChange += s - (double)lastSample; |
227 | 289 | ||
290 | penultimateSample = lastSample; | ||
228 | lastSample = s; | 291 | lastSample = s; |
229 | } | 292 | } |
230 | } | 293 | } |
231 | 294 | ||
295 | if (lastSample != null && penultimateSample != null) | ||
296 | { | ||
297 | lastChangeOverTime | ||
298 | = ((double)lastSample - (double)penultimateSample) / (Watchdog.WATCHDOG_INTERVAL_MS / 1000); | ||
299 | } | ||
300 | |||
232 | int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1; | 301 | int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1; |
233 | 302 | ||
234 | sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName); | 303 | averageChangeOverTime = totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000); |
304 | ret = true; | ||
305 | } | ||
306 | |||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | protected void AppendMeasuresOfInterest(StringBuilder sb) | ||
311 | { | ||
312 | double lastChangeOverTime = 0; | ||
313 | double averageChangeOverTime = 0; | ||
314 | |||
315 | if (ComputeMeasuresOfInterest(out lastChangeOverTime, out averageChangeOverTime)) | ||
316 | { | ||
317 | sb.AppendFormat( | ||
318 | ", {0:0.##}{1}/s, {2:0.##}{3}/s", | ||
319 | lastChangeOverTime, | ||
320 | string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName), | ||
321 | averageChangeOverTime, | ||
322 | string.IsNullOrEmpty(UnitName) ? "" : string.Format(" {0}", UnitName)); | ||
235 | } | 323 | } |
236 | } | 324 | } |
237 | } | 325 | } |