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;
}
}
}
}