<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.6.0-rc1.19456.4" />

DiagnosticSourceEventSource

using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; namespace System.Diagnostics { [EventSource(Name = "Microsoft-Diagnostics-DiagnosticSource")] internal class DiagnosticSourceEventSource : EventSource { public class Keywords { public const EventKeywords Messages = (EventKeywords)1; public const EventKeywords Events = (EventKeywords)2; public const EventKeywords IgnoreShortCutKeywords = (EventKeywords)2048; public const EventKeywords AspNetCoreHosting = (EventKeywords)4096; public const EventKeywords EntityFrameworkCoreCommands = (EventKeywords)8192; } internal class FilterAndTransform { public FilterAndTransform Next; private IDisposable _diagnosticsListenersSubscription; private Subscriptions _liveSubscriptions; private bool _noImplicitTransforms; private ImplicitTransformEntry _firstImplicitTransformsEntry; private ConcurrentDictionary<Type, TransformSpec> _implicitTransformsTable; private TransformSpec _explicitTransforms; private DiagnosticSourceEventSource _eventSource; public static void CreateFilterAndTransformList(ref FilterAndTransform specList, string filterAndPayloadSpecs, DiagnosticSourceEventSource eventSource) { DestroyFilterAndTransformList(ref specList); if (filterAndPayloadSpecs == null) filterAndPayloadSpecs = ""; int num = filterAndPayloadSpecs.Length; while (true) { if (0 < num && char.IsWhiteSpace(filterAndPayloadSpecs[num - 1])) num--; else { int num2 = filterAndPayloadSpecs.LastIndexOf('\n', num - 1, num); int i = 0; if (0 <= num2) i = num2 + 1; for (; i < num && char.IsWhiteSpace(filterAndPayloadSpecs[i]); i++) { } specList = new FilterAndTransform(filterAndPayloadSpecs, i, num, eventSource, specList); num = num2; if (num < 0) break; } } } public static void DestroyFilterAndTransformList(ref FilterAndTransform specList) { FilterAndTransform filterAndTransform = specList; specList = null; while (filterAndTransform != null) { filterAndTransform.Dispose(); filterAndTransform = filterAndTransform.Next; } } public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, DiagnosticSourceEventSource eventSource, FilterAndTransform next) { Next = next; _eventSource = eventSource; string listenerNameFilter = null; string eventNameFilter = null; string text = null; int num = startIdx; int num2 = endIdx; int num3 = filterAndPayloadSpec.IndexOf(':', startIdx, endIdx - startIdx); if (0 <= num3) { num2 = num3; num = num3 + 1; } int num4 = filterAndPayloadSpec.IndexOf('/', startIdx, num2 - startIdx); if (0 <= num4) { listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, num4 - startIdx); int num5 = filterAndPayloadSpec.IndexOf('@', num4 + 1, num2 - num4 - 1); if (0 <= num5) { text = filterAndPayloadSpec.Substring(num5 + 1, num2 - num5 - 1); eventNameFilter = filterAndPayloadSpec.Substring(num4 + 1, num5 - num4 - 1); } else eventNameFilter = filterAndPayloadSpec.Substring(num4 + 1, num2 - num4 - 1); } else if (startIdx < num2) { listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, num2 - startIdx); } _eventSource.Message("DiagnosticSource: Enabling '" + (listenerNameFilter ?? "*") + "/" + (eventNameFilter ?? "*") + "'"); if (num < endIdx && filterAndPayloadSpec[num] == '-') { _eventSource.Message("DiagnosticSource: suppressing implicit transforms."); _noImplicitTransforms = true; num++; } if (num < endIdx) { while (true) { int num6 = num; int num7 = filterAndPayloadSpec.LastIndexOf(';', endIdx - 1, endIdx - num); if (0 <= num7) num6 = num7 + 1; if (num6 < endIdx) { if (_eventSource.IsEnabled(EventLevel.Informational, (EventKeywords)1)) _eventSource.Message("DiagnosticSource: Parsing Explicit Transform '" + filterAndPayloadSpec.Substring(num6, endIdx - num6) + "'"); _explicitTransforms = new TransformSpec(filterAndPayloadSpec, num6, endIdx, _explicitTransforms); } if (num == num6) break; endIdx = num7; } } Action<string, string, IEnumerable<KeyValuePair<string, string>>> writeEvent = null; if (text != null && text.Contains("Activity")) { MethodInfo declaredMethod = typeof(DiagnosticSourceEventSource).GetTypeInfo().GetDeclaredMethod(text); if ((object)declaredMethod != null) try { writeEvent = (Action<string, string, IEnumerable<KeyValuePair<string, string>>>)declaredMethod.CreateDelegate(typeof(Action<string, string, IEnumerable<KeyValuePair<string, string>>>), _eventSource); } catch (Exception) { } if (writeEvent == null) _eventSource.Message("DiagnosticSource: Could not find Event to log Activity " + text); } if (writeEvent == null) writeEvent = _eventSource.Event; _diagnosticsListenersSubscription = DiagnosticListener.AllListeners.Subscribe(new CallbackObserver<DiagnosticListener>(delegate(DiagnosticListener newListener) { if (listenerNameFilter == null || listenerNameFilter == newListener.Name) { _eventSource.NewDiagnosticListener(newListener.Name); Predicate<string> isEnabled = null; if (eventNameFilter != null) isEnabled = ((string eventName) => eventNameFilter == eventName); IDisposable subscription = newListener.Subscribe(new CallbackObserver<KeyValuePair<string, object>>(delegate(KeyValuePair<string, object> evnt) { if (eventNameFilter == null || !(eventNameFilter != evnt.Key)) { List<KeyValuePair<string, string>> arg = Morph(evnt.Value); string key = evnt.Key; writeEvent(newListener.Name, key, arg); } }), isEnabled); _liveSubscriptions = new Subscriptions(subscription, _liveSubscriptions); } })); } private void Dispose() { if (_diagnosticsListenersSubscription != null) { _diagnosticsListenersSubscription.Dispose(); _diagnosticsListenersSubscription = null; } if (_liveSubscriptions != null) { Subscriptions subscriptions = _liveSubscriptions; _liveSubscriptions = null; while (subscriptions != null) { subscriptions.Subscription.Dispose(); subscriptions = subscriptions.Next; } } } public List<KeyValuePair<string, string>> Morph(object args) { List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); if (args != null) { if (!_noImplicitTransforms) { Type type2 = args.GetType(); ImplicitTransformEntry firstImplicitTransformsEntry = _firstImplicitTransformsEntry; TransformSpec transformSpec; if (firstImplicitTransformsEntry != null && (object)firstImplicitTransformsEntry.Type == type2) transformSpec = firstImplicitTransformsEntry.Transforms; else if (firstImplicitTransformsEntry == null) { transformSpec = MakeImplicitTransforms(type2); Interlocked.CompareExchange(ref _firstImplicitTransformsEntry, new ImplicitTransformEntry { Type = type2, Transforms = transformSpec }, null); } else { if (_implicitTransformsTable == null) Interlocked.CompareExchange(ref _implicitTransformsTable, new ConcurrentDictionary<Type, TransformSpec>(1, 8), null); transformSpec = _implicitTransformsTable.GetOrAdd(type2, (Type type) => MakeImplicitTransforms(type)); } if (transformSpec != null) { for (TransformSpec transformSpec2 = transformSpec; transformSpec2 != null; transformSpec2 = transformSpec2.Next) { list.Add(transformSpec2.Morph(args)); } } } if (_explicitTransforms != null) { for (TransformSpec transformSpec3 = _explicitTransforms; transformSpec3 != null; transformSpec3 = transformSpec3.Next) { KeyValuePair<string, string> item = transformSpec3.Morph(args); if (item.Value != null) list.Add(item); } } } return list; } private static TransformSpec MakeImplicitTransforms(Type type) { TransformSpec transformSpec = null; TypeInfo typeInfo = type.GetTypeInfo(); foreach (PropertyInfo declaredProperty in typeInfo.DeclaredProperties) { Type propertyType = declaredProperty.PropertyType; transformSpec = new TransformSpec(declaredProperty.Name, 0, declaredProperty.Name.Length, transformSpec); } return Reverse(transformSpec); } private static TransformSpec Reverse(TransformSpec list) { TransformSpec transformSpec = null; while (list != null) { TransformSpec next = list.Next; list.Next = transformSpec; transformSpec = list; list = next; } return transformSpec; } } internal class ImplicitTransformEntry { public Type Type; public TransformSpec Transforms; } internal class TransformSpec { internal class PropertySpec { private class PropertyFetch { private sealed class TypedFetchProperty<TObject, TProperty> : PropertyFetch { private readonly Func<TObject, TProperty> _propertyFetch; public TypedFetchProperty(Type type, PropertyInfo property) : base(type) { _propertyFetch = (Func<TObject, TProperty>)property.GetMethod.CreateDelegate(typeof(Func<TObject, TProperty>)); } public override object Fetch(object obj) { return _propertyFetch((TObject)obj); } } internal Type Type { get; } protected PropertyFetch(Type type) { Type = type; } public static PropertyFetch FetcherForProperty(Type type, PropertyInfo propertyInfo) { if ((object)propertyInfo == null) return new PropertyFetch(type); Type typeFromHandle = typeof(TypedFetchProperty<, >); Type type2 = typeFromHandle.GetTypeInfo().MakeGenericType(new Type[2] { propertyInfo.DeclaringType, propertyInfo.PropertyType }); return (PropertyFetch)Activator.CreateInstance(type2, type, propertyInfo); } public virtual object Fetch(object obj) { return null; } } public PropertySpec Next; private string _propertyName; private volatile PropertyFetch _fetchForExpectedType; public PropertySpec(string propertyName, PropertySpec next = null) { Next = next; _propertyName = propertyName; } public object Fetch(object obj) { Type type = obj.GetType(); PropertyFetch propertyFetch = _fetchForExpectedType; if (propertyFetch == null || (object)propertyFetch.Type != type) propertyFetch = (_fetchForExpectedType = PropertyFetch.FetcherForProperty(type, type.GetTypeInfo().GetDeclaredProperty(_propertyName))); return propertyFetch.Fetch(obj); } } public TransformSpec Next; private string _outputName; private PropertySpec _fetches; public TransformSpec(string transformSpec, int startIdx, int endIdx, TransformSpec next = null) { Next = next; int num = transformSpec.IndexOf('=', startIdx, endIdx - startIdx); if (0 <= num) { _outputName = transformSpec.Substring(startIdx, num - startIdx); startIdx = num + 1; } while (startIdx < endIdx) { int num2 = transformSpec.LastIndexOf('.', endIdx - 1, endIdx - startIdx); int num3 = startIdx; if (0 <= num2) num3 = num2 + 1; string text = transformSpec.Substring(num3, endIdx - num3); _fetches = new PropertySpec(text, _fetches); if (_outputName == null) _outputName = text; endIdx = num2; } } public KeyValuePair<string, string> Morph(object obj) { for (PropertySpec propertySpec = _fetches; propertySpec != null; propertySpec = propertySpec.Next) { if (obj != null) obj = propertySpec.Fetch(obj); } return new KeyValuePair<string, string>(_outputName, obj?.ToString()); } } internal class CallbackObserver<T> : IObserver<T> { private Action<T> _callback; public CallbackObserver(Action<T> callback) { _callback = callback; } public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(T value) { _callback(value); } } internal class Subscriptions { public IDisposable Subscription; public Subscriptions Next; public Subscriptions(IDisposable subscription, Subscriptions next) { Subscription = subscription; Next = next; } } public static DiagnosticSourceEventSource Logger = new DiagnosticSourceEventSource(); private readonly string AspNetCoreHostingKeywordValue = "Microsoft.AspNetCore/Microsoft.AspNetCore.Hosting.BeginRequest@Activity1Start:-httpContext.Request.Method;httpContext.Request.Host;httpContext.Request.Path;httpContext.Request.QueryString\nMicrosoft.AspNetCore/Microsoft.AspNetCore.Hosting.EndRequest@Activity1Stop:-httpContext.TraceIdentifier;httpContext.Response.StatusCode"; private readonly string EntityFrameworkCoreCommandsKeywordValue = "Microsoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.BeforeExecuteCommand@Activity2Start:-Command.Connection.DataSource;Command.Connection.Database;Command.CommandText\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.AfterExecuteCommand@Activity2Stop:-"; private volatile bool _false; private FilterAndTransform _specs; [Event(1, Keywords = (EventKeywords)1)] public void Message(string Message) { WriteEvent(1, Message); } [Event(2, Keywords = (EventKeywords)2)] private void Event(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(2, SourceName, EventName, Arguments); } [Event(3, Keywords = (EventKeywords)2)] private void EventJson(string SourceName, string EventName, string ArgmentsJson) { WriteEvent(3, SourceName, EventName, ArgmentsJson); } [Event(4, Keywords = (EventKeywords)2)] private void Activity1Start(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(4, SourceName, EventName, Arguments); } [Event(5, Keywords = (EventKeywords)2)] private void Activity1Stop(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(5, SourceName, EventName, Arguments); } [Event(6, Keywords = (EventKeywords)2)] private void Activity2Start(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(6, SourceName, EventName, Arguments); } [Event(7, Keywords = (EventKeywords)2)] private void Activity2Stop(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(7, SourceName, EventName, Arguments); } [Event(8, Keywords = (EventKeywords)2, ActivityOptions = EventActivityOptions.Recursive)] private void RecursiveActivity1Start(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(8, SourceName, EventName, Arguments); } [Event(9, Keywords = (EventKeywords)2, ActivityOptions = EventActivityOptions.Recursive)] private void RecursiveActivity1Stop(string SourceName, string EventName, IEnumerable<KeyValuePair<string, string>> Arguments) { WriteEvent(9, SourceName, EventName, Arguments); } [Event(10, Keywords = (EventKeywords)2)] private void NewDiagnosticListener(string SourceName) { WriteEvent(10, SourceName); } private DiagnosticSourceEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat) { } [NonEvent] protected override void OnEventCommand(EventCommandEventArgs command) { BreakPointWithDebuggerFuncEval(); lock (this) { if ((command.Command == EventCommand.Update || command.Command == EventCommand.Enable) && IsEnabled(EventLevel.Informational, (EventKeywords)2)) { command.Arguments.TryGetValue("FilterAndPayloadSpecs", out string value); if (!IsEnabled(EventLevel.Informational, (EventKeywords)2048)) { if (IsEnabled(EventLevel.Informational, (EventKeywords)4096)) value = NewLineSeparate(value, AspNetCoreHostingKeywordValue); if (IsEnabled(EventLevel.Informational, (EventKeywords)8192)) value = NewLineSeparate(value, EntityFrameworkCoreCommandsKeywordValue); } FilterAndTransform.CreateFilterAndTransformList(ref _specs, value, this); } else if (command.Command == EventCommand.Update || command.Command == EventCommand.Disable) { FilterAndTransform.DestroyFilterAndTransformList(ref _specs); } } } private static string NewLineSeparate(string str1, string str2) { if (string.IsNullOrEmpty(str1)) return str2; return str1 + "\n" + str2; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] [NonEvent] private void BreakPointWithDebuggerFuncEval() { new object(); while (_false) { _false = false; } } } }