Example #1
0
        public void PerformanceTest()
        {
            //first, lets get everything to flush so we have our best initial state.
            Log.EndFile("Preparing for Performance Test");
            Log.Information(LogWriteMode.WaitForCommit, "Test.Agent.Metrics.Performance", "Preparing for Test", "Flushing queue");

            SampledMetric.Register(typeof(UserSampledObject));

            UserSampledObject sampledObject = new UserSampledObject(25, 100);

            //now that we know it's flushed everything, lets do our timed loop.
            DateTimeOffset startTime = DateTimeOffset.UtcNow;

            for (int curMessage = 0; curMessage < MessagesPerTest; curMessage++)
            {
                SampledMetricDefinition.Write(sampledObject);
            }
            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 duration = endTime - startTime;

            Trace.TraceInformation("Sampled Metrics by Attribute Test Completed in {0}ms .  {1} messages were written at an average duration of {2}ms per message.  The flush took {3}ms.",
                                   duration.TotalMilliseconds, MessagesPerTest, (duration.TotalMilliseconds) / MessagesPerTest, (endTime - messageEndTime).TotalMilliseconds);
        }
        internal IMetricDefinition Externalize(Loupe.Extensibility.Data.IMetricDefinition metricDefinition)
        {
            if (metricDefinition == null)
            {
                return(null);
            }

            lock (Lock)
            {
                IMetricDefinition externalDefinition;
                if (m_Externalized.TryGetValue(metricDefinition, out externalDefinition) == false)
                {
                    Monitor.EventMetricDefinition         eventDefinition  = metricDefinition as Monitor.EventMetricDefinition;
                    Monitor.CustomSampledMetricDefinition customDefinition = metricDefinition as Monitor.CustomSampledMetricDefinition;

                    if (eventDefinition != null)
                    {
                        externalDefinition = new EventMetricDefinition(eventDefinition);
                    }
                    else if (customDefinition != null)
                    {
                        externalDefinition = new SampledMetricDefinition(customDefinition);
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format("Unable to wrap metric definition type: {0}", metricDefinition.GetType().Name));
                    }

                    m_Externalized[metricDefinition] = externalDefinition;
                }

                return(externalDefinition);
            }
        }
Example #3
0
        /// <summary>
        /// Snapshot cache metrics
        /// </summary>
        /// <param name="pagesLoaded"></param>
        public static void RecordCacheMetric(int pagesLoaded)
        {
            SampledMetricDefinition pageMetricDefinition;

            //since sampled metrics have only one value per metric, we have to create multiple metrics (one for every value)
            if (SampledMetricDefinition.TryGetValue("GibraltarSample", "Database.Engine", "Cache Pages", out pageMetricDefinition) == false)
            {
                //doesn't exist yet - add it in all of its glory.  This call is MT safe - we get back the object in cache even if registered on another thread.
                pageMetricDefinition = SampledMetricDefinition.Register("GibraltarSample", "Database.Engine", "cachePages", SamplingType.RawCount, "Pages", "Cache Pages", "The number of pages in the cache");
            }

            //now that we know we have the definitions, make sure we've defined the metric instances.
            SampledMetric pageMetric = SampledMetric.Register(pageMetricDefinition, null);

            //now go ahead and write those samples....
            pageMetric.WriteSample(pagesLoaded);

            //Continue for our second metric.
            SampledMetricDefinition sizeMetricDefinition;

            if (SampledMetricDefinition.TryGetValue("GibraltarSample", "Database.Engine", "Cache Size", out sizeMetricDefinition) == false)
            {
                //doesn't exist yet - add it in all of its glory  This call is MT safe - we get back the object in cache even if registered on another thread.
                sizeMetricDefinition = SampledMetricDefinition.Register("GibraltarSample", "Database.Engine", "cacheSize", SamplingType.RawCount, "Bytes", "Cache Size", "The number of bytes used by pages in the cache");
            }

            SampledMetric sizeMetric = SampledMetric.Register(sizeMetricDefinition, null);

            sizeMetric.WriteSample(pagesLoaded * 8196);
        }
Example #4
0
        public void SampledMetricsByAttributesPerformanceTest()
        {
            SampledMetric.Register(typeof(UserPerformanceObject));
            Trace.TraceInformation("Sampled metrics registered by attributes.");

            UserPerformanceObject sampledObject = new UserPerformanceObject("AttributesPerformanceTest", 25, 100);

            //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 < LoopsPerSampledTest; curMessage++)
            {
                SampledMetricDefinition.Write(sampledObject);
            }
            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 = LoopsPerSampledTest * MessagesPerSampledLoop;

            Trace.TraceInformation("Sampled Metrics by Attributes Test committed {0:N0} samples in {1:F3} ms (average {2:F4} ms per message).  Average loop time {3:F4} ms ({4} samples per loop) and final flush time {5:F3} ms.",
                                   messagesPerTest, testDuration.TotalMilliseconds, (testDuration.TotalMilliseconds / messagesPerTest),
                                   (loopDuration.TotalMilliseconds / LoopsPerSampledTest), MessagesPerSampledLoop,
                                   (endTime - messageEndTime).TotalMilliseconds);
        }
Example #5
0
        /// <summary>
        /// Write a sampled metric sample for this sampled metric instance using the provided data object.
        /// </summary>
        /// <remarks>The provided user data object must be assignable to the bound type which defined this sampled metric
        /// via attributes.</remarks>
        /// <example>
        ///     For examples, see the <see cref="SampledMetric">Sampled Metric</see> class
        ///     overview.
        /// </example>
        /// <param name="metricData">The object to retrieve metric values from.</param>
        /// <exception cref="ArgumentNullException">The provided metricData object was null.</exception>
        /// <exception cref="ArgumentException">This sampled metric's definition is not bound to sample automatically from a user data object.  WriteSample(...) must be given the data values directly.<br />-or-<br />
        /// The provided user data object type ({0}) is not assignable to this sampled metric's bound type ({1}) and can not be sampled automatically for this metric instance."></exception>
        public void WriteSample(object metricData)
        {
            if (metricData == null)
            {
                throw new ArgumentNullException(nameof(metricData));
            }

            if (Definition.IsBound == false)
            {
                throw new ArgumentException("This sampled metric's definition is not bound to sample automatically from a user data object.  WriteSample(...) must be given the data values directly.");
            }

            Type userDataType = metricData.GetType();

            if (Definition.BoundType.IsAssignableFrom(userDataType) == false)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The provided user data object type ({0}) is not assignable to this sampled metric's bound type ({1}) and can not be sampled automatically for this metric instance.",
                                                          userDataType, Definition.BoundType));
            }

            try
            {
                // Get the numerator value...
                NameValuePair <MemberTypes> dataBinding = Definition.DataBinding;
                BindingFlags dataBindingFlags           = m_MetricDefinition.GetBindingFlags(dataBinding);

                // This should throw an exception if dataBinding isn't valid, so we'll bail the whole thing.
                object rawNumerator = userDataType.InvokeMember(dataBinding.Name, dataBindingFlags, null, metricData, null, CultureInfo.InvariantCulture);
                double numerator    = Convert.ToDouble(rawNumerator, CultureInfo.CurrentCulture);

                if (SampledMetricDefinition.RequiresDivisor(SamplingType))
                {
                    NameValuePair <MemberTypes> divisorBinding = Definition.DivisorBinding;
                    BindingFlags divisorBindingFlags           = m_MetricDefinition.GetBindingFlags(divisorBinding);

                    // This should throw an exception if divisorBinding isn't valid, so we'll bail the whole thing.
                    object rawDivisor = userDataType.InvokeMember(divisorBinding.Name, divisorBindingFlags, null, metricData, null, CultureInfo.InvariantCulture);
                    double divisor    = Convert.ToDouble(rawDivisor, CultureInfo.CurrentCulture);

                    WriteSample(numerator, divisor); // Write the pair of values.
                }
                else
                {
                    WriteSample(numerator); // Write the single data value.
                }
            }
            catch
            {
#if DEBUG
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
#endif

                // We can't write this sample if we got an error reading the data.
            }
        }
Example #6
0
        /// <summary>Creates a new metric instance from the provided definition information, or returns any existing instance if found.</summary>
        /// <remarks>
        ///     <para>This call is designed to be safe in multithreaded environments. If two
        ///     threads attempt to register the same metric at the same time, the first will
        ///     register the metric and the second (and all subsequent calls to Register with the
        ///     same three part key) will return the same object.</para>
        ///     <para>If the Metric Definition doesn't exist, it will be created. If the Sampled
        ///     Metric doesn't exist, it will be created.</para>
        ///     <para>If a metric definition does exist with the same 3-part Key but is not a
        ///     sampled metric an exception will be thrown. This is one of the only times that an
        ///     exception can be thrown by the Loupe Agent.</para>
        /// </remarks>
        /// <example>
        ///     For examples, see the <see cref="SampledMetric">Sampled Metric</see> class
        ///     overview.
        /// </example>
        /// <param name="metricsSystem">The metrics capture system label.</param>
        /// <param name="categoryName">The name of the category with which this metric is associated.</param>
        /// <param name="counterName">The name of the metric definition within the category.</param>
        /// <param name="samplingType">The sampling type of this sampled metric counter.</param>
        /// <param name="unitCaption">A displayable caption for the units this metric samples, or null for unit-less values.</param>
        /// <param name="metricCaption">A displayable caption for this sampled metric counter.</param>
        /// <param name="description">An extended end-user description of this sampled metric counter.</param>
        /// <param name="instanceName">The unique name of this instance within the metric's collection (may be null).</param>
        public static SampledMetric Register(string metricsSystem, string categoryName, string counterName,
                                             SamplingType samplingType, string unitCaption, string metricCaption,
                                             string description, string instanceName)
        {
            SampledMetricDefinition metricDefinition = SampledMetricDefinition.Register(metricsSystem, categoryName, counterName, samplingType, unitCaption, metricCaption, description);

            // Then just forward into our call that requires the definition to be specified
            return(Register(metricDefinition, instanceName));
        }
Example #7
0
        /// <summary>Registers all sampled metric definitions defined by attributes on the provided object or Type, and registers
        /// metric instances where SampledMetricInstanceName attribute is also found or a non-null fall-back is specified.</summary>
        /// <remarks><para>This call ensures that the time-consuming reflection scan of all members looking for attributes
        /// across the entire inheritance of an object instance or Type has been done (e.g. outside of a critical path)
        /// so that the first call to Write(userDataObject) will not have to do that work within a critical path.  Results
        /// are cached internally, so redundant calls to this method will not repeat the scan for types already scanned
        /// (including as part of a different top-level type).</para>
        /// <para>If a live object is given (not just a Type) then the member(s) bound as [SampledMetricInstanceName] will be
        /// queried and used to also register a sampled metric instance with the returned name, to save that step as well,
        /// although this step is much quicker.  If a Type is given instead of a live object, it can not be queried for
        /// instance name(s) and will only register the sampled metric definitions.  Metric instances will still be created
        /// as needed when sampling a userDataObject, automatically.</para>
        /// <para>If fallbackInstanceName is null, only instances which specify an instance name in the live object will
        /// be registered (and returned).  With a valid string for fall-back instance name (including string.Empty for the
        /// "default instance"), a sampled metric will be registered and returned (barring errors) for each definition
        /// found.  The instance indicated by the binding in the object will always be used by preference over the
        /// fall-back instance name parameter, even if the instance name member returns a null.</para></remarks>
        /// <param name="userDataObject">An object or Type defining sampled metrics via attributes on itself or on its base types or interfaces.</param>
        /// <param name="fallbackInstanceName">The instance name to fall back on if a definition does not specify an instance name binding (may be null).</param>
        /// <returns>And array of all sampled metric instances found or created (one per definition) based on the instance
        /// name binding and optional fallbackInstanceName.</returns>
        /// <exception cref="ArgumentNullException">The provided userDataObject was null.</exception>
        internal static SampledMetric[] RegisterAll(object userDataObject, string fallbackInstanceName)
        {
            //we need a live object, not a null object or we'll fail
            if (userDataObject == null)
            {
                throw new ArgumentNullException(nameof(userDataObject));
            }

            // Register all of the event metric definitions it contains, object or Type:
            SampledMetricDefinition[] definitions = SampledMetricDefinition.RegisterAll(userDataObject);

            List <SampledMetric> metricsList = new List <SampledMetric>();

            if ((userDataObject is Type) == false)
            {
                // They gave us a live object, not just a Type, so see if there are metric instances we can register.

                // We'll cache the instance name for efficiency when multiple definitions in a row have the same BoundType.
                Type   boundType    = null;
                string instanceName = null;

                foreach (SampledMetricDefinition definition in definitions)
                {
                    if (definition.IsBound && definition.NameBound)
                    {
                        // We are bound, so BoundType won't be null.  Initial null value won't match, so we'll look it up.
                        if (definition.BoundType != boundType)
                        {
                            // New bound type, we need to look up the instance name bound for sampled metrics on that Type.
                            instanceName = definition.InvokeInstanceNameBinding(userDataObject) ?? fallbackInstanceName;
                            // A null return means it didn't have an instance name binding or couldn't read it, so we'll
                            // use the specified fallbackInstanceName instead.  If the instance name member returned null,
                            // this call will actually give us string.Empty, so we won't override it.  If this call and
                            // fallbackInstanceName are both null, we won't register the instance.
                            boundType = definition.BoundType;
                        }

                        if (instanceName != null) // null means it didn't find one, so we won't register an instance.
                        {
                            // In case there's an error in registration of one metric, we don't want to stop the rest.
                            try
                            {
                                // An empty string (meaning the found value was null or empty) will be registered (same as null).
                                metricsList.Add(Register(definition, instanceName));
                            }
                            // ReSharper disable EmptyGeneralCatchClause
                            catch
                            // ReSharper restore EmptyGeneralCatchClause
                            {
                            }
                        }
                    }
                }
            }

            return(metricsList.ToArray());
        }
Example #8
0
        public void TestEventAttributeReflection()
        {
            SampledMetric.Register(typeof(UserSampledObject));

            UserSampledObject sampledObject = new UserSampledObject(25, 100);

            SampledMetricDefinition.Write(sampledObject);

            SampledMetricDefinition sampledMetricDefinition;

            Assert.IsTrue(SampledMetricDefinition.TryGetValue(typeof(UserSampledObject), "IncrementalCount", out sampledMetricDefinition));

            sampledObject.SetValue(35, 90);
            sampledMetricDefinition.WriteSample(sampledObject);
        }
Example #9
0
        /// <summary>
        /// Creates a new metric instance from the provided definition information, or
        /// returns any existing instance if found.
        /// </summary>
        /// <remarks>
        ///     <para>If the Sampled Metric doesn't exist, it will be created.</para>
        ///     <para>This call is designed to be safe in multithreaded environments. If two
        ///     threads attempt to register the same metric at the same time, the first will
        ///     register the metric and the second (and all subsequent calls to Register with the
        ///     same three part key) will return the same object.</para>
        /// </remarks>
        /// <returns>The event metric object for the specified event metric instance.</returns>
        /// <example>
        ///     For examples, see the <see cref="SampledMetric">Sampled Metric</see> class
        ///     overview.
        /// </example>
        /// <param name="definition">The metric definition for the metric instance.</param>
        /// <param name="instanceName">The unique name of this instance within the metric's collection (may be null).</param>
        public static SampledMetric Register(SampledMetricDefinition definition, string instanceName)
        {
            if (definition == null)
            {
                // Uh-oh. AddOrGet() gave us a non-CustomSampledMetricDefinition?
                return(null);
            }

            SampledMetric metric;

            lock (definition.Metrics.Lock)
            {
                if (definition.Metrics.TryGetValue(instanceName, out metric) == false)
                {
                    metric = definition.Metrics.Add(instanceName);
                }
            }
            return(metric);
        }
Example #10
0
 /// <summary>
 /// Create a new custom sampled metric dictionary for the provided definition.
 /// </summary>
 /// <remarks>This dictionary is created automatically by the Custom Sampled Metric Definition during its initialization.</remarks>
 /// <param name="metricDefinition">The definition of the custom sampled metric to create a metric dictionary for</param>
 internal SampledMetricCollection(SampledMetricDefinition metricDefinition)
 {
     m_MetricDefinition  = metricDefinition;
     m_WrappedCollection = metricDefinition.WrappedDefinition.Metrics;
 }
 /// <summary>
 /// Create a new sampled metric dictionary for the provided definition.
 /// </summary>
 /// <remarks>This dictionary is created automatically by the Metric Definition during its initialization.</remarks>
 /// <param name="metricDefinition">The definition of the sampled metric to create a metric dictionary for</param>
 internal SampledMetricCollection(SampledMetricDefinition metricDefinition)
     : base(metricDefinition)
 {
 }
Example #12
0
 /// <summary>
 /// Create a new API custom sampled metric object from the provided API custom sampled metric definition and internal custom sampled metric.
 /// </summary>
 /// <remarks>The new metric will automatically be added to the metric definition's metrics collection.</remarks>
 /// <param name="definition">The API custom sampled metric definition for the metric instance.</param>
 /// <param name="metric">The internal custom sampled metric to wrap.</param>
 internal SampledMetric(SampledMetricDefinition definition, Monitor.CustomSampledMetric metric)
 {
     m_MetricDefinition = definition;
     m_WrappedMetric    = metric;
 }
Example #13
0
        public void BasicMetricUsage()
        {
            Log.TraceVerbose("Registering new sampled metric definitions");
            //go ahead and register a few metrics
            //int curMetricDefinitionCount = Log.MetricDefinitions.Count;

            SampledMetricDefinition incrementalCountDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                                  "Methods.Unit Test Data.Long", "IncrementalCount", SamplingType.IncrementalCount, null, "Incremental Count",
                                                                                                  "Unit test sampled metric using the incremental count calculation routine.");

            SampledMetricDefinition incrementalFractionDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                                     "Methods.Unit Test Data.Long", "IncrementalFraction", SamplingType.IncrementalFraction, null, "Incremental Fraction",
                                                                                                     "Unit test sampled metric using the incremental fraction calculation routine.  Rare, but fun.");

            SampledMetricDefinition totalCountDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                            "Methods.Unit Test Data.Long", "TotalCount", SamplingType.TotalCount, null, "Total Count",
                                                                                            "Unit test sampled metric using the Total Count calculation routine.  Very common.");

            SampledMetricDefinition totalFractionDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                               "Methods.Unit Test Data.Long", "TotalFraction", SamplingType.TotalFraction, null, "Total Fraction",
                                                                                               "Unit test sampled metric using the Total Fraction calculation routine.  Rare, but rounds us out.");

            SampledMetricDefinition rawCountDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                          "Methods.Unit Test Data.Long", "RawCount", SamplingType.RawCount, null, "Raw Count",
                                                                                          "Unit test sampled metric using the Raw Count calculation routine, which we will then average to create sample intervals.");

            SampledMetricDefinition rawFractionDefinition = SampledMetricDefinition.Register("BasicMetricUsage",
                                                                                             "Methods.Unit Test Data.Long", "RawFraction", SamplingType.RawFraction, null, "Raw Fraction",
                                                                                             "Unit test sampled metric using the Raw Fraction calculation routine.  Fraction types aren't common.");

            //we should have added six new metric definitions
            //Assert.AreEqual(curMetricDefinitionCount + 6, Log.MetricDefinitions.Count, "The number of registered metric definitions hasn't increased by the right amount, tending to mean that one or more metrics didn't register.");

            // These should never be null, but let's check to confirm.
            Assert.IsNotNull(incrementalCountDefinition);
            Assert.IsNotNull(incrementalFractionDefinition);
            Assert.IsNotNull(totalCountDefinition);
            Assert.IsNotNull(totalFractionDefinition);
            Assert.IsNotNull(rawCountDefinition);
            Assert.IsNotNull(rawFractionDefinition);

            //and lets go ahead and create new metrics for each definition
            Log.TraceVerbose("Obtaining default metric instances from each definition");

            SampledMetric incrementalCountMetric    = SampledMetric.Register(incrementalCountDefinition, null);
            SampledMetric incrementalFractionMetric = SampledMetric.Register(incrementalFractionDefinition, null);
            SampledMetric totalCountMetric          = SampledMetric.Register(totalCountDefinition, null);
            SampledMetric totalFractionMetric       = SampledMetric.Register(totalFractionDefinition, null);
            SampledMetric rawCountMetric            = SampledMetric.Register(rawCountDefinition, null);
            SampledMetric rawFractionMetric         = SampledMetric.Register(rawFractionDefinition, null);

            // These should never be null, either, but let's check to confirm.
            Assert.IsNotNull(incrementalCountMetric);
            Assert.IsNotNull(incrementalFractionMetric);
            Assert.IsNotNull(totalCountMetric);
            Assert.IsNotNull(totalFractionMetric);
            Assert.IsNotNull(rawCountMetric);
            Assert.IsNotNull(rawFractionMetric);

            //and finally, lets go log some data!
            Log.TraceVerbose("And now lets log data");

            //lets add 10 values, a few milliseconds apart
            int curSamplePass = 0;

            while (curSamplePass < 10)
            {
                //We're putting in fairly bogus data, but it will produce a consistent output.
                incrementalCountMetric.WriteSample(curSamplePass * 20);
                incrementalFractionMetric.WriteSample(curSamplePass * 20, curSamplePass * 30);
                totalCountMetric.WriteSample(curSamplePass * 20);
                totalFractionMetric.WriteSample(curSamplePass * 20, curSamplePass * 30);
                rawCountMetric.WriteSample(curSamplePass);
                rawFractionMetric.WriteSample(curSamplePass, 10.0);

                curSamplePass++;
                Thread.Sleep(100);
            }

            Log.TraceVerbose("Completed logging metric samples.");
        }
Example #14
0
        public void RegistrationConsistency()
        {
            Assert.IsTrue(true);
            bool question = SampledMetricDefinition.IsValidDataType(typeof(int));

            Assert.IsTrue(question);
            question = SampledMetricDefinition.IsValidDataType(GetType());
            Assert.IsFalse(question);

            // Create a sampled metric definition to work with.
            SampledMetricDefinition createdDefinitionOne = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                                            "Methods.Unit Test Data.Consistency", "Metric One", SamplingType.RawCount, null, "First metric",
                                                                                            "The first sampled metric definition for this test.");

            Assert.IsNotNull(createdDefinitionOne);

            // Get the same definition with different caption and description.
            SampledMetricDefinition obtainedDefinitionOne = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                                             "Methods.Unit Test Data.Consistency", "Metric One", SamplingType.RawCount, null, "The first metric",
                                                                                             "This is the first sampled metric definition for this test.");

            Assert.IsNotNull(obtainedDefinitionOne);

            Assert.AreSame(createdDefinitionOne, obtainedDefinitionOne,
                           "Second call to SampledMetricDefinition.Register() did not get the same definition object as the first. \"{0}\" vs \"{1}\".",
                           createdDefinitionOne.Caption, obtainedDefinitionOne.Caption);
            Assert.AreEqual("First metric", createdDefinitionOne.Caption);
            Assert.AreEqual("The first sampled metric definition for this test.", createdDefinitionOne.Description);

            // Get an instance from the definition.
            SampledMetric createdInstanceOneA = SampledMetric.Register(createdDefinitionOne, "Instance One A");

            Assert.IsNotNull(createdInstanceOneA);

            Assert.AreSame(createdDefinitionOne, createdInstanceOneA.Definition,
                           "Created instance does not point to the same definition object used to create it. \"{0}\" vs \"{1}\".",
                           createdDefinitionOne.Caption, createdInstanceOneA.Definition.Caption);
            Assert.AreEqual("Instance One A", createdInstanceOneA.InstanceName);

            // Get the same instance the same way again.
            SampledMetric obtainedInstanceOneA = SampledMetric.Register(createdDefinitionOne, "Instance One A");

            Assert.IsNotNull(obtainedInstanceOneA);

            Assert.AreSame(createdInstanceOneA, obtainedInstanceOneA,
                           "Second call to SampledMetric.Register() did not get the same metric instance object as the first. \"{0}\" vs \"{1}\".",
                           createdInstanceOneA.InstanceName, obtainedInstanceOneA.InstanceName);

            // Get the same instance directly.
            obtainedInstanceOneA = SampledMetric.Register("RegistrationConsistency",
                                                          "Methods.Unit Test Data.Consistency", "Metric One", SamplingType.RawCount, null, "Metric #1",
                                                          "This is metric definition #1 for this test.", "Instance One A");
            Assert.IsNotNull(obtainedInstanceOneA);
            Assert.IsNotNull(obtainedInstanceOneA.Definition);

            Assert.AreSame(createdInstanceOneA, obtainedInstanceOneA,
                           "Third call to SampledMetric.Register() did not get the same metric instance object as the first. \"{0}\" vs \"{1}\".",
                           createdInstanceOneA.InstanceName, obtainedInstanceOneA.InstanceName);

            // Get a second instance from the definition.
            SampledMetric createdInstanceOneB = SampledMetric.Register(createdDefinitionOne, "Instance One B");

            Assert.IsNotNull(createdInstanceOneB);
            Assert.IsNotNull(createdInstanceOneB.Definition);

            Assert.AreSame(createdDefinitionOne, createdInstanceOneB.Definition,
                           "Created instance does not point to the same definition object used to create it. \"{0}\" vs \"{1}\".",
                           createdDefinitionOne.Caption, createdInstanceOneB.Definition.Caption);
            Assert.AreEqual("Instance One B", createdInstanceOneB.InstanceName);

            Assert.AreNotSame(createdInstanceOneA, createdInstanceOneB,
                              "Different metric instances should never be the same object.");
            Assert.AreNotEqual(createdInstanceOneA, createdInstanceOneB,
                               "Different metric instances should not test as being equal. \"{0}\" vs \"{1}\".",
                               createdInstanceOneA.InstanceName, createdInstanceOneB.InstanceName);

            Assert.IsTrue(createdInstanceOneA.Key.StartsWith(createdDefinitionOne.Key),
                          "Instance Key does not start with definition Key. \"{0}\" vs \"{1}\".",
                          createdInstanceOneA.Key, createdDefinitionOne.Key);
            Assert.IsTrue(createdInstanceOneA.Key.EndsWith(createdInstanceOneA.InstanceName),
                          "Instance Key does not end with instance name. \"{0}\" vs \"{1}\".",
                          createdInstanceOneA.Key, createdInstanceOneA.InstanceName);
            Assert.IsTrue(createdInstanceOneB.Key.StartsWith(createdDefinitionOne.Key),
                          "Instance Key does not start with definition Key. \"{0}\" vs \"{1}\".",
                          createdInstanceOneB.Key, createdDefinitionOne.Key);
            Assert.IsTrue(createdInstanceOneB.Key.EndsWith(createdInstanceOneB.InstanceName),
                          "Instance Key does not end with instance name. \"{0}\" vs \"{1}\".",
                          createdInstanceOneB.Key, createdInstanceOneB.InstanceName);



            // Try a different definition, directly to an instance first.
            SampledMetric createdInstanceTwoA = SampledMetric.Register("RegistrationConsistency",
                                                                       "Methods.Unit Test Data.Consistency", "Metric Two", SamplingType.RawCount, null, "Second metric",
                                                                       "The second sampled metric definition for this test.", "Instance Two A");

            Assert.IsNotNull(createdInstanceTwoA);

            // Check it's definition, created automatically.
            SampledMetricDefinition createdDefinitionTwo = createdInstanceTwoA.Definition;

            Assert.IsNotNull(createdDefinitionTwo);

            // Get the same instance, with a different caption and description.
            SampledMetric obtainedInstanceTwoA = SampledMetric.Register("RegistrationConsistency",
                                                                        "Methods.Unit Test Data.Consistency", "Metric Two", SamplingType.RawCount, null, "The second metric",
                                                                        "This is the second sampled metric definition for this test.", "Instance Two A");

            Assert.IsNotNull(obtainedInstanceTwoA);
            Assert.AreSame(createdDefinitionTwo, obtainedInstanceTwoA.Definition,
                           "Instances of the same metric do not point to the same definition object. \"{0}\" vs \"{1}\".",
                           createdDefinitionTwo.Caption, obtainedInstanceTwoA.Definition.Caption);

            // Get the same definition another way.
            SampledMetricDefinition obtainedDefinitionTwo = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                                             "Methods.Unit Test Data.Consistency", "Metric Two", SamplingType.RawCount, null, "Metric #2",
                                                                                             "This is metric definition #2 for this test.");

            Assert.IsNotNull(obtainedDefinitionTwo);

            Assert.AreSame(createdDefinitionTwo, obtainedDefinitionTwo,
                           "Call to SampledMetricDefinition.Register() did not get the same definition as the direct instances. \"{0}\" vs \"{1}\".",
                           createdDefinitionTwo.Caption, obtainedDefinitionTwo.Caption);
            Assert.AreEqual("Second metric", obtainedDefinitionTwo.Caption);
            Assert.AreEqual("The second sampled metric definition for this test.", obtainedDefinitionTwo.Description);

            Assert.IsTrue(createdInstanceTwoA.Key.StartsWith(createdDefinitionTwo.Key),
                          "Instance Key does not start with definition Key. \"{0}\" vs \"{1}\".",
                          createdInstanceTwoA.Key, createdDefinitionTwo.Key);
            Assert.IsTrue(createdInstanceTwoA.Key.EndsWith(createdInstanceTwoA.InstanceName),
                          "Instance Key does not end with instance name. \"{0}\" vs \"{1}\".",
                          createdInstanceTwoA.Key, createdInstanceTwoA.InstanceName);

            Assert.AreNotSame(createdDefinitionOne, createdDefinitionTwo,
                              "Different metric definitions should never be the same object.");
            Assert.AreNotEqual(createdDefinitionOne, createdDefinitionTwo,
                               "Different metric definitions should not test as being equal. \"{0}\" vs \"{1}\".",
                               createdDefinitionOne.Key, createdDefinitionTwo.Key);



            // Create instance from null, then from empty string.
            SampledMetric instanceOneNull  = SampledMetric.Register(createdDefinitionOne, null);
            SampledMetric instanceOneEmpty = SampledMetric.Register(createdDefinitionOne, string.Empty);

            Assert.IsNotNull(instanceOneNull);
            Assert.IsNotNull(instanceOneEmpty);
            Assert.AreSame(instanceOneNull, instanceOneEmpty,
                           "Null instance and empty instance are not the same metric object. {0} vs {1}.",
                           (instanceOneNull.InstanceName == null) ? "(null)" : "\"" + instanceOneNull.InstanceName + "\"",
                           (instanceOneEmpty.InstanceName == null) ? "(null)" : "\"" + instanceOneEmpty.InstanceName + "\"");

            // Create instance from empty string, then from null.
            SampledMetric instanceTwoEmpty = SampledMetric.Register(createdDefinitionTwo, string.Empty);
            SampledMetric instanceTwoNull  = SampledMetric.Register(createdDefinitionTwo, null);

            Assert.IsNotNull(instanceTwoEmpty);
            Assert.IsNotNull(instanceTwoNull);
            Assert.AreSame(instanceTwoEmpty, instanceTwoNull,
                           "Empty instance and null instance are not the same metric object. {0} vs {1}.",
                           (instanceTwoEmpty.InstanceName == null) ? "(null)" : "\"" + instanceTwoEmpty.InstanceName + "\"",
                           (instanceTwoNull.InstanceName == null) ? "(null)" : "\"" + instanceTwoNull.InstanceName + "\"");

            Assert.IsTrue(instanceOneNull.IsDefault);
            Assert.IsTrue(instanceOneEmpty.IsDefault);
            Assert.IsTrue(instanceTwoEmpty.IsDefault);
            Assert.IsTrue(instanceTwoNull.IsDefault);

            Assert.IsNull(instanceOneNull.InstanceName);
            Assert.IsNull(instanceOneEmpty.InstanceName);
            Assert.IsNull(instanceTwoEmpty.InstanceName);
            Assert.IsNull(instanceTwoNull.InstanceName);



            SampledMetricDefinition createdDefinitionThree = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                                              "Methods.Unit Test Data.Consistency", "Metric Three", SamplingType.IncrementalCount, null, "Third metric",
                                                                                              "An IncrementalCount metric.");

            Assert.IsNotNull(createdDefinitionThree);
            SampledMetricDefinition obtainedDefinitionThree;

            try
            {
                obtainedDefinitionThree = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                           "Methods.Unit Test Data.Consistency", "Metric Three", SamplingType.RawCount, null, "Third metric",
                                                                           "A RawCount metric.");
                Assert.IsNotNull(obtainedDefinitionThree); // This should never actually be executed.
            }
            catch (ArgumentException ex)
            {
                Trace.TraceInformation("SampledMetricDefinition.Register() with inconsistent sampling type threw expected exception.", ex);
                obtainedDefinitionThree = null;
            }
            Assert.IsNull(obtainedDefinitionThree); // Confirm we went through the catch.

            SampledMetric createdInstanceThreeA;

            try
            {
                createdInstanceThreeA = SampledMetric.Register("RegistrationConsistency",
                                                               "Methods.Unit Test Data.Consistency", "Metric Three", SamplingType.TotalCount, null, "Third metric",
                                                               "A TotalCount metric.", "Instance Three A");
                Assert.IsNotNull(createdInstanceThreeA); // This should never actually be executed.
            }
            catch (ArgumentException ex)
            {
                Trace.TraceInformation("SampledMetric.Register() with inconsistent sampling type threw expected exception.", ex);
                createdInstanceThreeA = null;
            }
            Assert.IsNull(createdInstanceThreeA); // Confirm we went through the catch.

            obtainedDefinitionThree = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                       "Methods.Unit Test Data.Consistency", "Metric Three", SamplingType.IncrementalCount, "seconds", "Third metric",
                                                                       "An IncrementalCount of seconds metric.");
            Assert.IsNotNull(obtainedDefinitionThree);
            //Assert.IsNull(obtainedDefinitionThree.UnitCaption); // Bug: This is getting "Count of items" instead of null?

            SampledMetric createdInstanceFour = SampledMetric.Register("RegistrationConsistency",
                                                                       "Methods.Unit Test Data.Consistency", "Metric Four", SamplingType.IncrementalFraction, "hits per minute",
                                                                       "Third metric", "An IncrementalCount of seconds metric.", null);

            Assert.IsNotNull(createdInstanceFour);
            Assert.AreEqual("hits per minute", createdInstanceFour.UnitCaption);

            SampledMetricDefinition obtainedDefinitionFour = SampledMetricDefinition.Register("RegistrationConsistency",
                                                                                              "Methods.Unit Test Data.Consistency", "Metric Four", SamplingType.IncrementalFraction, "hits per hour",
                                                                                              "Third metric", "An IncrementalCount of seconds metric.");

            Assert.IsNotNull(obtainedDefinitionFour);
            Assert.AreEqual("hits per minute", obtainedDefinitionFour.UnitCaption);
        }
Example #15
0
        public void SimpleMetricUsage()
        {
            Log.TraceVerbose("Registering new sampled metric definition");
            //create one sampled metric definition using the "make a definition for the current log set" override
            SampledMetricDefinition temperatureTracking = SampledMetricDefinition.Register("SimpleMetricUsage", "Methods.Temperature", "Experiment Temperature", SamplingType.RawCount, null, "Temperature", "This is an example from iControl where we want to track the temperature of a reaction or some such thing.");

            //create a set of METRICS (definition + metric) using the static add metric capability
            Log.TraceVerbose("Registering metric instances directly");

            SampledMetric incrementalCountMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                          "IncrementalCount", SamplingType.IncrementalCount, null, "Incremental Count",
                                                                          "Unit test sampled metric using the incremental count calculation routine.", null);

            SampledMetric incrementalFractionMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                             "IncrementalFraction", SamplingType.IncrementalFraction, null, "Incremental Fraction",
                                                                             "Unit test sampled metric using the incremental fraction calculation routine.  Rare, but fun.", null);

            SampledMetric totalCountMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                    "TotalCount", SamplingType.TotalCount, null, "Total Count",
                                                                    "Unit test sampled metric using the Total Count calculation routine.  Very common.", null);

            SampledMetric totalFractionMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                       "TotalFraction", SamplingType.TotalFraction, null, "Total Fraction",
                                                                       "Unit test sampled metric using the Total Fraction calculation routine.  Rare, but rounds us out.", null);

            SampledMetric rawCountMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                  "RawCount", SamplingType.RawCount, null, "Raw Count",
                                                                  "Unit test sampled metric using the Raw Count calculation routine, which we will then average to create sample intervals.", null);

            SampledMetric rawFractionMetric = SampledMetric.Register("SimpleMetricUsage", "Methods.Unit Test Data.Direct",
                                                                     "RawFraction", SamplingType.RawFraction, null, "Raw Fraction",
                                                                     "Unit test sampled metric using the Raw Fraction calculation routine.  Fraction types aren't common.", null);

            // These should never be null, but let's check to confirm.
            Assert.IsNotNull(incrementalCountMetric);
            Assert.IsNotNull(incrementalFractionMetric);
            Assert.IsNotNull(totalCountMetric);
            Assert.IsNotNull(totalFractionMetric);
            Assert.IsNotNull(rawCountMetric);
            Assert.IsNotNull(rawFractionMetric);

            Log.TraceVerbose("And now lets log data");

            //lets add 10 values, a few milliseconds apart
            int curSamplePass = 0;

            while (curSamplePass < 10)
            {
                //the temperature tracking one is set up so we can write to instances directly from a definition.
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 1), curSamplePass);
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 2), curSamplePass);
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 3), curSamplePass);
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 4), curSamplePass);
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 5), curSamplePass);
                temperatureTracking.WriteSample(string.Format(CultureInfo.CurrentCulture, "Experiment {0}", 6), curSamplePass);

                incrementalCountMetric.WriteSample(curSamplePass * 20);
                incrementalFractionMetric.WriteSample(curSamplePass * 20, curSamplePass * 30);
                totalCountMetric.WriteSample(curSamplePass * 20);
                totalFractionMetric.WriteSample(curSamplePass * 20, curSamplePass * 30);
                rawCountMetric.WriteSample(curSamplePass);
                rawFractionMetric.WriteSample(curSamplePass, 10.0);

                curSamplePass++;
                Thread.Sleep(100);
            }
            Log.TraceVerbose("Completed logging metric samples.");
        }
Example #16
0
        public void SampledMetricsByMethodsPerformanceTest()
        {
            Log.TraceVerbose("Registering new sampled metric definitions");
            //go ahead and register a few metrics
            //int curMetricDefinitionCount = Log.MetricDefinitions.Count;

            SampledMetricDefinition incrementalCountDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "IncrementalCount",
                                                 SamplingType.IncrementalCount, null, "Incremental Count",
                                                 "Unit test sampled metric using the incremental count calculation routine.");

            SampledMetricDefinition incrementalFractionDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "IncrementalFraction",
                                                 SamplingType.IncrementalFraction, null, "Incremental Fraction",
                                                 "Unit test sampled metric using the incremental fraction calculation routine.  Rare, but fun.");

            SampledMetricDefinition totalCountDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "TotalCount",
                                                 SamplingType.TotalCount, null, "Total Count",
                                                 "Unit test sampled metric using the Total Count calculation routine.  Very common.");

            SampledMetricDefinition totalFractionDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "TotalFraction",
                                                 SamplingType.TotalFraction, null, "Total Fraction",
                                                 "Unit test sampled metric using the Total Fraction calculation routine.  Rare, but rounds us out.");

            SampledMetricDefinition rawCountDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "RawCount",
                                                 SamplingType.RawCount, null, "Raw Count",
                                                 "Unit test sampled metric using the Raw Count calculation routine, which we will then average to create sample intervals.");

            SampledMetricDefinition rawFractionDefinition =
                SampledMetricDefinition.Register("PerformanceTestsMetrics", "Performance.SampledMetrics.Methods", "RawFraction",
                                                 SamplingType.RawFraction, null, "Raw Fraction",
                                                 "Unit test sampled metric using the Raw Fraction calculation routine.  Fraction types aren't common.");

            //we should have added six new metric definitions
            //Assert.AreEqual(curMetricDefinitionCount + 6, Log.MetricDefinitions.Count, "The number of registered metric definitions hasn't increased by the right amount, tending to mean that one or more metrics didn't register.");

            // These should never be null, but let's check to confirm.
            Assert.IsNotNull(incrementalCountDefinition);
            Assert.IsNotNull(incrementalFractionDefinition);
            Assert.IsNotNull(totalCountDefinition);
            Assert.IsNotNull(totalFractionDefinition);
            Assert.IsNotNull(rawCountDefinition);
            Assert.IsNotNull(rawFractionDefinition);

            Trace.TraceInformation("Sampled metric definitions registered by methods.");

            // These should never be null, but let's check to confirm.
            Assert.IsNotNull(incrementalCountDefinition);
            Assert.IsNotNull(incrementalFractionDefinition);
            Assert.IsNotNull(totalCountDefinition);
            Assert.IsNotNull(totalFractionDefinition);
            Assert.IsNotNull(rawCountDefinition);
            Assert.IsNotNull(rawFractionDefinition);

            //and lets go ahead and create new metrics for each definition
            Log.TraceVerbose("Obtaining default metric instances from each definition");

            SampledMetric incrementalCountMetric    = SampledMetric.Register(incrementalCountDefinition, null);
            SampledMetric incrementalFractionMetric = SampledMetric.Register(incrementalFractionDefinition, null);
            SampledMetric totalCountMetric          = SampledMetric.Register(totalCountDefinition, null);
            SampledMetric totalFractionMetric       = SampledMetric.Register(totalFractionDefinition, null);
            SampledMetric rawCountMetric            = SampledMetric.Register(rawCountDefinition, null);
            SampledMetric rawFractionMetric         = SampledMetric.Register(rawFractionDefinition, null);

            // These should never be null, either, but let's check to confirm.
            Assert.IsNotNull(incrementalCountMetric);
            Assert.IsNotNull(incrementalFractionMetric);
            Assert.IsNotNull(totalCountMetric);
            Assert.IsNotNull(totalFractionMetric);
            Assert.IsNotNull(rawCountMetric);
            Assert.IsNotNull(rawFractionMetric);

            // Now, 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 < LoopsPerSampledTest; curMessage++)
            {
                //We're putting in fairly bogus data, but it will produce a consistent output.
                incrementalCountMetric.WriteSample(20);
                incrementalFractionMetric.WriteSample(20, 30);
                totalCountMetric.WriteSample(20);
                totalFractionMetric.WriteSample(20, 30);
                rawCountMetric.WriteSample(20);
                rawFractionMetric.WriteSample(20, 30);
            }
            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 = LoopsPerSampledTest * MessagesPerSampledLoop;

            Trace.TraceInformation("Sampled Metrics by Methods Test committed {0:N0} samples in {1:F3} ms (average {2:F4} ms per message).  Average loop time {3:F4} ms ({4} samples per loop) and final flush time {5:F3} ms.",
                                   messagesPerTest, testDuration.TotalMilliseconds, (testDuration.TotalMilliseconds / messagesPerTest),
                                   (loopDuration.TotalMilliseconds / LoopsPerSampledTest), MessagesPerSampledLoop,
                                   (endTime - messageEndTime).TotalMilliseconds);
        }
Example #17
0
        /*
         * /// <summary>Creates a new custom sampled metric object from the metric definition looked up with the provided key information.</summary>
         * /// <remarks>The metric definition must already exist or an exception will be raised.</remarks>
         * /// <param name="definitions">The definitions dictionary this definition is a part of</param>
         * /// <param name="metricsSystem">The metrics capture system label.</param>
         * /// <param name="categoryName">The name of the category with which this definition is associated.</param>
         * /// <param name="counterName">The name of the definition within the category.</param>
         * /// <param name="instanceName">The unique name of this instance within the metric's collection.</param>
         * internal SampledMetric(MetricDefinitionCollection definitions, string metricsSystem, string categoryName, string counterName, string instanceName)
         *  : this((SampledMetricDefinition)definitions[metricsSystem, categoryName, counterName], instanceName)
         * {
         * }
         */

        /// <summary>
        /// Create a new custom sampled metric object from the provided metric definition
        /// </summary>
        /// <remarks>The new metric will automatically be added to the metric definition's metrics collection.</remarks>
        /// <param name="definition">The metric definition for the metric instance</param>
        /// <param name="instanceName">The unique name of this instance within the metric's collection.</param>
        internal SampledMetric(SampledMetricDefinition definition, string instanceName)
            : this(definition, new Monitor.CustomSampledMetric(definition.WrappedDefinition, instanceName))
        {
            definition.Metrics.Internalize(this); // ToDo: Is this needed?
        }