protected virtual void Dispose(bool disposing) // Or override, if we had a base class implementing it also. { //base.Dispose(disposing); // But we have no base, so this doesn't exist. if (disposing) { SampledMetric.Write(this); // Write one last sample when we're disposed. } m_EndThread = true; // This needs to be done by the finalizer as well as when disposed. }
public void SampledAttributeReflectionExample() { // // General example usage. // // Optional registration in advance (time-consuming reflection walk to find attributes the first time). // Either of these two approaches will dig into base types and all interfaces seen at the top level. SampledMetric.Register(typeof(UserSampledAttributedClass)); // Can be registered from the Type itself. // Or... UserSampledAttributedClass anyUserSampledAttributedInstance = new UserSampledAttributedClass("any-prototype"); SampledMetric.Register(anyUserSampledAttributedInstance); // Can register from a live instance (gets its Type automatically). // Elsewhere... UserSampledAttributedClass userSampledAttributedInstance = new UserSampledAttributedClass("automatic-instance-name"); // then... // To sample all valid sampled metrics defined by attributes (at all inheritance levels) for a data object instance: // This will determine the instance name automatically from the member marked with the EventMetricInstanceName attribute. // Null will be used as the instance name (the "default instance") if the attribute is not found for a particular metric. SampledMetric.Write(userSampledAttributedInstance); // The recommended typical usage. // Or... To specify a different fallback instance name if an EventMetricInstanceName attribute isn't found: SampledMetric.Write(userSampledAttributedInstance, "fallback-instance-if-not-assigned"); // // Specific example usage for example class above. // Generate some meaningful data in the log to look at. // int[] testDataArray = new[] { 1, 5, 3, -4, 2, 7, -3, -2, 9, 4, -5, -1, 3, -7, 2, 4, -2, 8, 10, -4, 2 }; // Using the "default" instance here. This will Dispose it for us when it exits the block. using (UserSampledAttributedClass realUsageInstance = new UserSampledAttributedClass(null)) { SampledMetric.Register(realUsageInstance); // Registering from the live object also registers the metric instance. realUsageInstance.StartPolling(); // Start polling thread for this one. foreach (int dataValue in testDataArray) { realUsageInstance.ApplyDelta(dataValue); // This method also fires off an event metric sample for us. Thread.Sleep(50 + (5 * dataValue)); // Sleep for a little while to space out the data, not entirely evenly for this example. } } Thread.Sleep(1000); // Give it some time to complete. }
private void SamplePollingThreadStart() { Trace.TraceInformation("Example polling thread ({0}) started", m_InstanceName ?? "null"); while (m_EndThread == false) { SampledMetric.Write(this); // Write a sample of all sampled metrics defined by attributes on this object. Thread.Sleep(100); // Sleep for 0.1 seconds before sampling again. } Trace.TraceInformation("Example polling thread ({0}) ending", m_InstanceName ?? "null"); m_PollingThread = null; // Exiting thread, mark us as no longer polling. }
private void HandleConnection(string name, ConnectionEndEventData eventData) { ConnectionMetric metric; if (name == RelationalEventId.ConnectionOpened.Name) { metric = new ConnectionMetric(eventData) { Action = "Open", ConnectionDelta = 1, Duration = eventData.Duration }; _connectionNames.TryAdd(eventData.ConnectionId, metric.InstanceName); } else if (name == RelationalEventId.ConnectionClosed.Name) { // *sigh*. We've found the server names don't always match between open and close //so look up our cached value.. if (_connectionNames.TryRemove(eventData.ConnectionId, out string instanceName)) { metric = new ConnectionMetric(eventData, instanceName) { Action = "Closed", ConnectionDelta = -1, Duration = eventData.Duration }; } else { // we ignore the else clause because it's not a "matching" event. return; } } else { return; } EventMetric.Write(metric); SampledMetric.Write(metric); }
/// <summary> /// Record a snapshot cache metric using an object /// </summary> /// <param name="pagesLoaded"></param> public static void RecordCacheMetricByObject(int pagesLoaded) { //by using an object with the appropriate attributes we can do it in one line - even though it writes multiple values. SampledMetric.Write(new CacheSampledMetric(pagesLoaded)); }