diff options
Diffstat (limited to 'src/mscorlib/shared/System/Diagnostics/Tracing')
-rw-r--r-- | src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs | 436 | ||||
-rw-r--r-- | src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs | 18 |
2 files changed, 9 insertions, 445 deletions
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs deleted file mode 100644 index b1f946464e..0000000000 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs +++ /dev/null @@ -1,436 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -#if ES_BUILD_PCL - using System.Threading.Tasks; -#endif - -#if ES_BUILD_STANDALONE -namespace Microsoft.Diagnostics.Tracing -#else -namespace System.Diagnostics.Tracing -#endif -{ - /// <summary> - /// Provides the ability to collect statistics through EventSource - /// </summary> - public class EventCounter - { - /// <summary> - /// Initializes a new instance of the <see cref="EventCounter"/> class. - /// </summary> - /// <param name="name">The name.</param> - /// <param name="eventSource">The event source.</param> - public EventCounter(string name, EventSource eventSource) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - if (eventSource == null) - { - throw new ArgumentNullException(nameof(eventSource)); - } - - InitializeBuffer(); - _name = name; - EventCounterGroup.AddEventCounter(eventSource, this); - } - - /// <summary> - /// Writes the metric. - /// </summary> - /// <param name="value">The value.</param> - public void WriteMetric(float value) - { - Enqueue(value); - } - - #region private implementation - - private readonly string _name; - - #region Buffer Management - - // Values buffering - private const int BufferedSize = 10; - private const float UnusedBufferSlotValue = float.NegativeInfinity; - private const int UnsetIndex = -1; - private volatile float[] _bufferedValues; - private volatile int _bufferedValuesIndex; - - private void InitializeBuffer() - { - _bufferedValues = new float[BufferedSize]; - for (int i = 0; i < _bufferedValues.Length; i++) - { - _bufferedValues[i] = UnusedBufferSlotValue; - } - } - - private void Enqueue(float value) - { - // It is possible that two threads read the same bufferedValuesIndex, but only one will be able to write the slot, so that is okay. - int i = _bufferedValuesIndex; - while (true) - { - float result = Interlocked.CompareExchange(ref _bufferedValues[i], value, UnusedBufferSlotValue); - i++; - if (_bufferedValues.Length <= i) - { - // It is possible that two threads both think the buffer is full, but only one get to actually flush it, the other - // will eventually enter this code path and potentially calling Flushing on a buffer that is not full, and that's okay too. - lock (_bufferedValues) - { - Flush(); - } - i = 0; - } - - if (result == UnusedBufferSlotValue) - { - // CompareExchange succeeded - _bufferedValuesIndex = i; - return; - } - } - } - - private void Flush() - { - for (int i = 0; i < _bufferedValues.Length; i++) - { - var value = Interlocked.Exchange(ref _bufferedValues[i], UnusedBufferSlotValue); - if (value != UnusedBufferSlotValue) - { - OnMetricWritten(value); - } - } - - _bufferedValuesIndex = 0; - } - - #endregion // Buffer Management - - #region Statistics Calculation - - // Statistics - private int _count; - private float _sum; - private float _sumSquared; - private float _min; - private float _max; - - private void OnMetricWritten(float value) - { - _sum += value; - _sumSquared += value * value; - if (_count == 0 || value > _max) - { - _max = value; - } - - if (_count == 0 || value < _min) - { - _min = value; - } - - _count++; - } - - internal EventCounterPayload GetEventCounterPayload() - { - lock (_bufferedValues) - { - Flush(); - EventCounterPayload result = new EventCounterPayload(); - result.Name = _name; - result.Count = _count; - result.Mean = _sum / _count; - result.StandardDerivation = (float)Math.Sqrt(_sumSquared / _count - _sum * _sum / _count / _count); - result.Min = _min; - result.Max = _max; - ResetStatistics(); - return result; - } - } - - private void ResetStatistics() - { - _count = 0; - _sum = 0; - _sumSquared = 0; - _min = 0; - _max = 0; - } - - #endregion // Statistics Calculation - - #endregion // private implementation - } - - #region internal supporting classes - - [EventData] - internal class EventCounterPayload : IEnumerable<KeyValuePair<string, object>> - { - public string Name { get; set; } - - public float Mean { get; set; } - - public float StandardDerivation { get; set; } - - public int Count { get; set; } - - public float Min { get; set; } - - public float Max { get; set; } - - public float IntervalSec { get; internal set; } - - #region Implementation of the IEnumerable interface - - public IEnumerator<KeyValuePair<string, object>> GetEnumerator() - { - return ForEnumeration.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ForEnumeration.GetEnumerator(); - } - - private IEnumerable<KeyValuePair<string, object>> ForEnumeration - { - get - { - yield return new KeyValuePair<string, object>("Name", Name); - yield return new KeyValuePair<string, object>("Mean", Mean); - yield return new KeyValuePair<string, object>("StandardDerivation", StandardDerivation); - yield return new KeyValuePair<string, object>("Count", Count); - yield return new KeyValuePair<string, object>("Min", Min); - yield return new KeyValuePair<string, object>("Max", Max); - } - } - - #endregion // Implementation of the IEnumerable interface - } - - internal class EventCounterGroup : IDisposable - { - private readonly EventSource _eventSource; - private readonly int _eventSourceIndex; - private readonly List<EventCounter> _eventCounters; - - internal EventCounterGroup(EventSource eventSource, int eventSourceIndex) - { - _eventSource = eventSource; - _eventSourceIndex = eventSourceIndex; - _eventCounters = new List<EventCounter>(); - RegisterCommandCallback(); - } - - private void Add(EventCounter eventCounter) - { - _eventCounters.Add(eventCounter); - } - - #region EventSource Command Processing - - private void RegisterCommandCallback() - { - _eventSource.EventCommandExecuted += OnEventSourceCommand; - } - - private void OnEventSourceCommand(object sender, EventCommandEventArgs e) - { - if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update) - { - string valueStr; - float value; - if (e.Arguments.TryGetValue("EventCounterIntervalSec", out valueStr) && float.TryParse(valueStr, out value)) - { - EnableTimer(value); - } - } - } - - #endregion // EventSource Command Processing - - #region Global EventCounterGroup Array management - - private static EventCounterGroup[] s_eventCounterGroups; - - internal static void AddEventCounter(EventSource eventSource, EventCounter eventCounter) - { - int eventSourceIndex = EventListener.EventSourceIndex(eventSource); - - EventCounterGroup.EnsureEventSourceIndexAvailable(eventSourceIndex); - EventCounterGroup eventCounterGroup = GetEventCounterGroup(eventSource); - eventCounterGroup.Add(eventCounter); - } - - private static void EnsureEventSourceIndexAvailable(int eventSourceIndex) - { - if (EventCounterGroup.s_eventCounterGroups == null) - { - EventCounterGroup.s_eventCounterGroups = new EventCounterGroup[eventSourceIndex + 1]; - } - else if (eventSourceIndex >= EventCounterGroup.s_eventCounterGroups.Length) - { - EventCounterGroup[] newEventCounterGroups = new EventCounterGroup[eventSourceIndex + 1]; - Array.Copy(EventCounterGroup.s_eventCounterGroups, 0, newEventCounterGroups, 0, EventCounterGroup.s_eventCounterGroups.Length); - EventCounterGroup.s_eventCounterGroups = newEventCounterGroups; - } - } - - private static EventCounterGroup GetEventCounterGroup(EventSource eventSource) - { - int eventSourceIndex = EventListener.EventSourceIndex(eventSource); - EventCounterGroup result = EventCounterGroup.s_eventCounterGroups[eventSourceIndex]; - if (result == null) - { - result = new EventCounterGroup(eventSource, eventSourceIndex); - EventCounterGroup.s_eventCounterGroups[eventSourceIndex] = result; - } - - return result; - } - - #endregion // Global EventCounterGroup Array management - - #region Timer Processing - - private DateTime _timeStampSinceCollectionStarted; - private int _pollingIntervalInMilliseconds; - private Timer _pollingTimer; - - private void EnableTimer(float pollingIntervalInSeconds) - { - if (pollingIntervalInSeconds == 0) - { - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - - _pollingIntervalInMilliseconds = 0; - } - else if (_pollingIntervalInMilliseconds == 0 || pollingIntervalInSeconds < _pollingIntervalInMilliseconds) - { - _pollingIntervalInMilliseconds = (int)(pollingIntervalInSeconds * 1000); - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - - _timeStampSinceCollectionStarted = DateTime.Now; - _pollingTimer = new Timer(OnTimer, null, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds); - } - } - - private void OnTimer(object state) - { - if (_eventSource.IsEnabled()) - { - DateTime now = DateTime.Now; - TimeSpan elapsed = now - _timeStampSinceCollectionStarted; - lock (_pollingTimer) - { - foreach (var eventCounter in _eventCounters) - { - EventCounterPayload payload = eventCounter.GetEventCounterPayload(); - payload.IntervalSec = (float)elapsed.TotalSeconds; - _eventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new { Payload = payload }); - } - - - _timeStampSinceCollectionStarted = now; - } - } - else - { - _pollingTimer.Dispose(); - _pollingTimer = null; - EventCounterGroup.s_eventCounterGroups[_eventSourceIndex] = null; - } - } - - #region PCL timer hack - -#if ES_BUILD_PCL - internal delegate void TimerCallback(object state); - - internal sealed class Timer : CancellationTokenSource, IDisposable - { - private int _period; - private TimerCallback _callback; - private object _state; - - internal Timer(TimerCallback callback, object state, int dueTime, int period) - { - _callback = callback; - _state = state; - _period = period; - Schedule(dueTime); - } - - private void Schedule(int dueTime) - { - Task.Delay(dueTime, Token).ContinueWith(OnTimer, null, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default); - } - - private void OnTimer(Task t, object s) - { - Schedule(_period); - _callback(_state); - } - - public new void Dispose() { base.Cancel(); } - } -#endif - #endregion // PCL timer hack - - #endregion // Timer Processing - - #region Implementation of the IDisposable interface - - private bool _disposed = false; - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - } - - _disposed = true; - } - - #endregion // Implementation of the IDisposable interface - } - - #endregion // internal supporting classes -} diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs index 57d550dc8c..e18574c1b4 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs @@ -555,21 +555,21 @@ namespace System.Diagnostics.Tracing { #if (!ES_BUILD_PCL && !ES_BUILD_PN && !FEATURE_PAL) string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}"; - if (Marshal.SizeOf(typeof(IntPtr)) == 8) - regKey = @"Software" + @"\Wow6432Node" + regKey; + if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8) + regKey = @"HKEY_LOCAL_MACHINE\Software" + @"\Wow6432Node" + regKey; else - regKey = @"Software" + regKey; + regKey = @"HKEY_LOCAL_MACHINE\Software" + regKey; string valueName = "ControllerData_Session_" + etwSessionId.ToString(CultureInfo.InvariantCulture); - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey, writable: false)) - { - data = key.GetValue(valueName) as byte[]; - } - + // we need to assert this permission for partial trust scenarios +#if !CORECLR + (new RegistryPermission(RegistryPermissionAccess.Read, regKey)).Assert(); +#endif + data = Microsoft.Win32.Registry.GetValue(regKey, valueName, null) as byte[]; if (data != null) { - // We only used the persisted data from the registry for updates. + // We only used the persisted data from the registry for updates. command = ControllerCommand.Update; return true; } |