public void RecordEventMetricReflection() { UserEventObject myDataObject = new UserEventObject(null); EventMetric.Register(myDataObject); EventMetricDefinition metricDefinition; Assert.IsTrue(EventMetricDefinition.TryGetValue(typeof(UserEventObject), out metricDefinition)); EventMetricDefinition.Write(myDataObject); // Now try it with inheritance and interfaces in the mix. UserMultipleEventObject bigDataObject = new UserMultipleEventObject(null); EventMetric.Register(bigDataObject); // There's no event at the top level, so this lookup should fail. Assert.IsFalse(EventMetricDefinition.TryGetValue(typeof(UserMultipleEventObject), out metricDefinition)); // Now check for interfaces... Assert.IsTrue(EventMetricDefinition.TryGetValue(typeof(IEventMetricOne), out metricDefinition)); Assert.IsTrue(EventMetricDefinition.TryGetValue(typeof(IEventMetricTwo), out metricDefinition)); Assert.IsTrue(EventMetricDefinition.TryGetValue(typeof(IEventMetricThree), out metricDefinition)); Assert.IsTrue(EventMetricDefinition.TryGetValue(typeof(IEventMetricFour), out metricDefinition)); // And sample all of them on the big object with a single call... EventMetric.Write(bigDataObject); }
/// <summary> /// Record an event metric using a programmatic declaration /// </summary> /// <param name="pagesLoaded"></param> public static void RecordCacheMetric(int pagesLoaded) { EventMetricDefinition cacheMetric; //so we can be called multiple times we want to see if the definition already exists. if (EventMetricDefinition.TryGetValue("GibraltarSample", "Database.Engine", "Cache", out cacheMetric) == false) { cacheMetric = new EventMetricDefinition("GibraltarSample", "Database.Engine", "Cache"); //add the values (that are part of the definition) cacheMetric.AddValue("pages", typeof(int), SummaryFunction.Average, "Pages", "Pages in Cache", "Total number of pages in cache"); cacheMetric.AddValue("size", typeof(int), SummaryFunction.Average, "Bytes", "Cache Size", "Total number of bytes used by pages in cache"); //and now that we're done, we need to register this definition. This locks the definition //and makes it go live. Note that it's based by ref because if another thread registered the same metric, we'll get the //registered object (whoever one the race), not necessarily the one we've just created to pass in. EventMetricDefinition.Register(ref cacheMetric); } //Now we can get the specific metric we want to record samples under (this is an instance of the definition) EventMetric cacheEventMetric = EventMetric.Register(cacheMetric, null); //now go ahead and write that sample. EventMetricSample newSample = cacheEventMetric.CreateSample(); newSample.SetValue("pages", pagesLoaded); newSample.SetValue("size", pagesLoaded * 8196); newSample.Write(); }
public void EventMetricsByMethodsPerformanceTest() { EventMetricDefinition eventDefinition; if (false == EventMetricDefinition.TryGetValue("PerformanceTestsMetrics", "Performance.EventMetrics.Methods", "UserEvent", out eventDefinition)) { eventDefinition = new EventMetricDefinition("PerformanceTestsMetrics", "Performance.EventMetrics.Methods", "UserEvent"); eventDefinition.Caption = "User Event"; eventDefinition.Description = "Unit test event metric with typical data."; eventDefinition.AddValue("fileName", typeof(string), SummaryFunction.Count, null, "File name", "The name of the file"); eventDefinition.AddValue("operation", typeof(UserFileOperation), SummaryFunction.Count, null, "Operation", "The type of file operation being performed."); eventDefinition.AddValue("duration", typeof(TimeSpan), SummaryFunction.Average, "ms", "Duration", "The duration for this file operation."); EventMetricDefinition.Register(ref eventDefinition, "duration"); } Assert.IsNotNull(eventDefinition); Assert.IsTrue(eventDefinition.IsReadOnly); Trace.TraceInformation("Event metric definition registered by methods."); EventMetric eventMetric = EventMetric.Register(eventDefinition, "MethodsPerformanceTest"); Assert.IsNotNull(eventMetric); string fileName = @"C:\Dummy\File\Name.txt"; DateTimeOffset operationStart = DateTimeOffset.UtcNow; DateTimeOffset operationEnd = operationStart.AddMilliseconds(1234); //first, lets get everything to flush so we have our best initial state. Log.Information(LogWriteMode.WaitForCommit, "Test.Agent.Metrics.Performance", "Preparing for Test", "Flushing queue"); //now that we know it's flushed everything, lets do our timed loop. DateTimeOffset startTime = DateTimeOffset.UtcNow; for (int curMessage = 0; curMessage < LoopsPerEventTest; curMessage++) { EventMetricSample eventSample = eventMetric.CreateSample(); eventSample.SetValue("fileName", fileName); eventSample.SetValue("operation", UserFileOperation.Write); eventSample.SetValue("duration", operationEnd - operationStart); eventSample.Write(); } DateTimeOffset messageEndTime = DateTimeOffset.UtcNow; //one wait for commit message to force the buffer to flush. Log.Information(LogWriteMode.WaitForCommit, "Test.Agent.Metrics.Performance", "Waiting for Samples to Commit", null); //and store off our time DateTimeOffset endTime = DateTimeOffset.UtcNow; TimeSpan testDuration = endTime - startTime; TimeSpan loopDuration = messageEndTime - startTime; const int messagesPerTest = LoopsPerEventTest * MessagesPerEventLoop; Trace.TraceInformation("Event Metrics by Methods Test committed {0:N0} events in {1:F3} ms (average {2:F4} ms per message). Average loop time {3:F4} ms ({4} values per message) and final flush time {5:F3} ms.", messagesPerTest, testDuration.TotalMilliseconds, (testDuration.TotalMilliseconds / messagesPerTest), (loopDuration.TotalMilliseconds / LoopsPerEventTest), ValuesPerEventMessage, (endTime - messageEndTime).TotalMilliseconds); }
public void Setup() { // This is an example of how to create an event metric definition programatically. EventMetricDefinition newMetricDefinition; // Define an event metric manually (the long way). First, see if it's already registered... if (EventMetricDefinition.TryGetValue("EventMetricTests", "Gibraltar.Monitor.Test", "Manual", out newMetricDefinition) == false) { // It's not registered yet, so we need to fill out the template to define it. EventMetricDefinition newEventMetric = new EventMetricDefinition("EventMetricTests", "Gibraltar.Monitor.Test", "Manual"); // Now we want to add a few value columns to make it useful. // NOTE: This is designed to exactly match UserEventObject for convenience in analzing results. // The dummy data values we're using are unitless, so we'll just use null for the required unitCaption parameter. newEventMetric.AddValue("short_average", typeof(short), SummaryFunction.Average, null, "Short Average", "Data of type Short"); newEventMetric.AddValue("short_sum", typeof(short), SummaryFunction.Sum, null, "Short Sum", "Data of type Short"); newEventMetric.AddValue("short_runningaverage", typeof(short), SummaryFunction.RunningAverage, null, "Short Running Average", "Data of type Short"); newEventMetric.AddValue("short_runningsum", typeof(short), SummaryFunction.RunningSum, null, "Short Running Sum", "Data of type Short"); newEventMetric.AddValue("ushort_average", typeof(ushort), SummaryFunction.Average, null, "UShort Average", "Data of type UShort"); newEventMetric.AddValue("ushort_sum", typeof(ushort), SummaryFunction.Sum, null, "UShort Sum", "Data of type UShort"); // Pick an interesting value column as the default to be graphed for this metric. We'll pass it below. EventMetricValueDefinition defaultValue = newEventMetric.AddValue("int_average", typeof(int), SummaryFunction.Average, null, "Int Average", "Data of type Int"); newEventMetric.AddValue("int_sum", typeof(int), SummaryFunction.Sum, null, "Int Sum", "Data of type Int"); newEventMetric.AddValue("uint_average", typeof(uint), SummaryFunction.Average, null, "UInt Average", "Data of type UInt"); newEventMetric.AddValue("uint_sum", typeof(uint), SummaryFunction.Sum, null, "UInt Sum", "Data of type UInt"); newEventMetric.AddValue("long_average", typeof(long), SummaryFunction.Average, null, "Long Average", "Data of type Long"); newEventMetric.AddValue("long_sum", typeof(long), SummaryFunction.Sum, null, "Long Sum", "Data of type Long"); newEventMetric.AddValue("ulong_average", typeof(ulong), SummaryFunction.Average, null, "ULong Average", "Data of type ULong"); newEventMetric.AddValue("ulong_sum", typeof(ulong), SummaryFunction.Sum, null, "ULong Sum", "Data of type ULong"); newEventMetric.AddValue("decimal_average", typeof(decimal), SummaryFunction.Average, null, "Decimal Average", "Data of type Decimal"); newEventMetric.AddValue("decimal_sum", typeof(decimal), SummaryFunction.Sum, null, "Decimal Sum", "Data of type Decimal"); newEventMetric.AddValue("double_average", typeof(double), SummaryFunction.Average, null, "Double Average", "Data of type Double"); newEventMetric.AddValue("double_sum", typeof(double), SummaryFunction.Sum, null, "Double Sum", "Data of type Double"); newEventMetric.AddValue("float_average", typeof(float), SummaryFunction.Average, null, "Float Average", "Data of type Float"); newEventMetric.AddValue("float_sum", typeof(float), SummaryFunction.Sum, null, "Float Sum", "Data of type Float"); newEventMetric.AddValue("timespan_average", typeof(TimeSpan), SummaryFunction.Average, null, "TimeSpan Average", "Data of type TimeSpan"); newEventMetric.AddValue("timespan_sum", typeof(TimeSpan), SummaryFunction.Sum, null, "TimeSpan Sum", "Data of type TimeSpan"); newEventMetric.AddValue("timespan_runningaverage", typeof(TimeSpan), SummaryFunction.RunningAverage, null, "TimeSpan Running Average", "Data of type TimeSpan represented as a running average."); newEventMetric.AddValue("timespan_runningsum", typeof(TimeSpan), SummaryFunction.RunningSum, null, "TimeSpan Running Sum", "Data of type TimeSpan represented as a running sum."); newEventMetric.AddValue("string", typeof(string), SummaryFunction.Count, null, "String", "Data of type String"); newEventMetric.AddValue("system.enum", typeof(UserDataEnumeration), SummaryFunction.Count, null, "System.Enum", "Data of type System.Enum"); // Finally, register it with Gibraltar, and specify the default value column we saved above. EventMetricDefinition.Register(ref newEventMetric, defaultValue); } EventMetricDefinition metricDefinition; Assert.IsTrue(EventMetricDefinition.TryGetValue("EventMetricTests", "Gibraltar.Monitor.Test", "Manual", out metricDefinition)); Assert.IsNotNull(metricDefinition); }
public void RecordEventMetricPerformanceTest() { // Internally we want to make this comparable to the reflection test, just varying the part that uses reflection. EventMetricDefinition metricDefinition; Assert.IsTrue(EventMetricDefinition.TryGetValue("EventMetricTests", "Gibraltar.Monitor.Test", "Manual", out metricDefinition)); Assert.IsNotNull(metricDefinition); EventMetric thisExperimentMetric = EventMetric.Register(metricDefinition, "RecordEventMetricPerformanceTest"); Assert.IsNotNull(thisExperimentMetric); // We're going to write out a BUNCH of samples... Trace.TraceInformation("Starting performance test"); DateTime curTime = DateTime.Now; //for timing how fast we are int curSample; for (curSample = 0; curSample < 32000; curSample++) { EventMetricSample newSample = thisExperimentMetric.CreateSample(); newSample.SetValue("short_average", curSample); newSample.SetValue("short_sum", curSample); newSample.SetValue("short_runningaverage", curSample); newSample.SetValue("short_runningsum", curSample); newSample.SetValue("ushort_average", (ushort)curSample); newSample.SetValue("ushort_sum", (ushort)curSample); newSample.SetValue("int_average", curSample); newSample.SetValue("int_sum", curSample); newSample.SetValue("uint_average", (uint)curSample); newSample.SetValue("uint_sum", (uint)curSample); newSample.SetValue("long_average", curSample); newSample.SetValue("long_sum", curSample); newSample.SetValue("ulong_average", (ulong)curSample); newSample.SetValue("ulong_sum", (ulong)curSample); newSample.SetValue("decimal_average", curSample); newSample.SetValue("decimal_sum", curSample); newSample.SetValue("double_average", curSample); newSample.SetValue("double_sum", curSample); newSample.SetValue("float_average", curSample); newSample.SetValue("float_sum", curSample); newSample.SetValue("timespan_average", new TimeSpan(curSample)); newSample.SetValue("timespan_sum", new TimeSpan(curSample)); newSample.SetValue("timespan_runningaverage", new TimeSpan(curSample)); newSample.SetValue("timespan_runningsum", new TimeSpan(curSample)); newSample.SetValue("string", string.Format(CultureInfo.CurrentCulture, "The current manual sample is {0}", curSample)); newSample.SetValue("system.enum", (UserDataEnumeration)curSample); newSample.Write(); //only now does it get written because we had to wait until you populated the metrics } TimeSpan duration = DateTime.Now - curTime; Trace.TraceInformation("Completed performance test in {0} milliseconds for {1} samples", duration.TotalMilliseconds, curSample); Log.Verbose(LogWriteMode.WaitForCommit, "Test.Agent.Metrics.EventMetric.Methods", "Event Metrics performance test flush", null); }
/// <summary> /// Perform the one-time work to create a metric /// </summary> /// <param name="name">Dot-delimited display name for this metric</param> private void InitializeMetric(string name) { // Handle edge cases if (string.IsNullOrEmpty(name)) { name = DefaultInstance; } name = name.Trim(); while (!string.IsNullOrEmpty(name) && name[0] == '.') { name = name.Substring(1).Trim(); } // Set up category and instance as Loupe wants string category; string instance; var pos = name.LastIndexOf('.'); // check for delimited name if (pos <= 0) { // If not deliminated, just use base category category = RootCategory; instance = name; } else { // If delimited, just use the last part as instance name // and combine the rest with category category = RootCategory + '.' + name.Substring(0, pos); instance = name.Substring(pos + 1); } _logCategory = category + "." + instance; // Initializ category for logging EventMetricDefinition metricDefinition; // Create the metric on first call then use cached copy thereafter if (!EventMetricDefinition.TryGetValue(MetricSystem, category, instance, out metricDefinition)) { metricDefinition = new EventMetricDefinition(MetricSystem, category, instance); metricDefinition.AddValue(DurationCaption, typeof(TimeSpan), SummaryFunction.Average, null, DurationCaption, null); EventMetricDefinition.Register(ref metricDefinition); } // Grab the metric from cache Metric = EventMetric.Register(metricDefinition, null); }
public void RecordEventMetric() { // Internally we want to make this comparable to the reflection test, just varying the part that uses reflection. EventMetricDefinition metricDefinition; Assert.IsTrue(EventMetricDefinition.TryGetValue("EventMetricTests", "Gibraltar.Monitor.Test", "Manual", out metricDefinition)); Assert.IsNotNull(metricDefinition); EventMetric thisExperimentMetric = EventMetric.Register(metricDefinition, "RecordEventMetric"); Assert.IsNotNull(thisExperimentMetric); // To write a sample manually, we must first create an empty sample for this event metric instance. EventMetricSample newSample = thisExperimentMetric.CreateSample(); // Then we set the values. newSample.SetValue("short_average", 1); newSample.SetValue("short_sum", 1); newSample.SetValue("short_runningaverage", 1); newSample.SetValue("short_runningsum", 1); newSample.SetValue("ushort_average", (ushort)1); newSample.SetValue("ushort_sum", (ushort)1); newSample.SetValue("int_average", 1); newSample.SetValue("int_sum", 1); newSample.SetValue("uint_average", (uint)1); newSample.SetValue("uint_sum", (uint)1); newSample.SetValue("long_average", 1); newSample.SetValue("long_sum", 1); newSample.SetValue("ulong_average", (ulong)1); newSample.SetValue("ulong_sum", (ulong)1); newSample.SetValue("decimal_average", 1); newSample.SetValue("decimal_sum", 1); newSample.SetValue("double_average", 1); newSample.SetValue("double_sum", 1); newSample.SetValue("float_average", 1); newSample.SetValue("float_sum", 1); newSample.SetValue("timespan_average", new TimeSpan(1)); newSample.SetValue("timespan_sum", new TimeSpan(1)); newSample.SetValue("timespan_runningaverage", new TimeSpan(1)); newSample.SetValue("timespan_runningsum", new TimeSpan(1)); newSample.SetValue("string", string.Format(CultureInfo.CurrentCulture, "The current manual sample is {0}", 1)); newSample.SetValue("system.enum", (UserDataEnumeration)1); // And finally, tell the sample to write itself to the Gibraltar log. newSample.Write(); }
private static EventMetricDefinition GetMetricDefinition() { if (!EventMetricDefinition.TryGetValue(MetricSystem, MetricCategory, MetricCaption, out var eventMetricDefinition)) { eventMetricDefinition = new EventMetricDefinition(MetricSystem, MetricCategory, MetricName) { Caption = MetricCaption, Description = MetricDescription }; eventMetricDefinition.AddHitCount(MetricValue.PageName, "Page", "The page name without path"); eventMetricDefinition.AddHitCount(MetricValue.AbsolutePath, "Absolute Path", "The full path from the root of the web site to the page that was requested including the page"); eventMetricDefinition.AddDuration(MetricValue.TotalDuration, "Total Request Duration", "The entire time it took for the request to be satisfied"); eventMetricDefinition.AddDuration(MetricValue.AuthenticateDuration, "Authenticate Request Duration", "The time it took for the request to be authenticated"); eventMetricDefinition.AddDuration(MetricValue.AuthorizeRequestDuration, "Authorize Request Duration", "The time it took for the request to be authorized"); eventMetricDefinition.AddDuration(MetricValue.ResolveRequestCacheDuration, "Resolve Request Cache Duration", "The time it took for the request to be looked up in cache"); eventMetricDefinition.AddDuration(MetricValue.AcquireRequestStateDuration, "Acquire Request State Duration", "The time it took for the request state to be acquired"); eventMetricDefinition.AddDuration(MetricValue.RequestHandlerExecuteDuration, "Request Handler Execute Duration", "The time it took for the request handler to execute. This includes the time for most ASP.NET page code"); eventMetricDefinition.AddDuration(MetricValue.ReleaseRequestStateDuration, "Release Request State Duration", "The time it took for the request state to be released"); eventMetricDefinition.AddDuration(MetricValue.UpdateRequestCacheDuration, "Update Request Cache Duration", "The time it took for the request cache to be updated"); eventMetricDefinition.AddDuration(MetricValue.LogRequestDuration, "Log Request Duration", "The time it took for the request to be logged"); eventMetricDefinition.AddFlag(MetricValue.ServedFromCache, "Cached Response", "Indicates if the response was served from the output cache instead of generated"); eventMetricDefinition.AddHitCount(MetricValue.QueryString, "Query String", "The query string used for the request"); eventMetricDefinition.AddCount(MetricValue.UserName, "User", "The user associated with the action being performed"); eventMetricDefinition.AddCount(MetricValue.SessionId, "SessionId", "Session Id associated with action being performed"); eventMetricDefinition.AddCount(MetricValue.AgentSessionId, "AgentSessionId", "Id from JavaScript agent for session"); EventMetricDefinition.Register(ref eventMetricDefinition); } return(eventMetricDefinition); }