ActivitySource
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
namespace System.Diagnostics
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public sealed class ActivitySource : IDisposable
{
internal delegate bool Function<T, TParent> (T item, ref ActivityCreationOptions<TParent> data, ref ActivityDataRequest dataRequest, ref bool? ctxInitialized, ref ActivityCreationOptions<ActivityContext> dataWithContext);
private static readonly SynchronizedList<ActivitySource> s_activeSources = new SynchronizedList<ActivitySource>();
private static readonly SynchronizedList<ActivityListener> s_allListeners = new SynchronizedList<ActivityListener>();
private SynchronizedList<ActivityListener> _listeners;
public string Name { get; }
[System.Runtime.CompilerServices.Nullable(2)]
public string Version {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
}
public ActivitySource(string name, [System.Runtime.CompilerServices.Nullable(2)] string version = "")
{
if (name == null)
throw new ArgumentNullException("name");
Name = name;
Version = version;
s_activeSources.Add(this);
if (s_allListeners.Count > 0)
s_allListeners.EnumWithAction(delegate(ActivityListener listener, object source) {
Func<ActivitySource, bool> shouldListenTo = listener.ShouldListenTo;
if (shouldListenTo != null) {
ActivitySource activitySource = (ActivitySource)source;
if (shouldListenTo(activitySource))
activitySource.AddListener(listener);
}
}, this);
}
public bool HasListeners()
{
SynchronizedList<ActivityListener> listeners = _listeners;
if (listeners != null)
return listeners.Count > 0;
return false;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
public Activity StartActivity(string name, ActivityKind kind = ActivityKind.Internal)
{
return StartActivity(name, kind, default(ActivityContext), null, null, null, default(DateTimeOffset));
}
[System.Runtime.CompilerServices.NullableContext(2)]
public Activity StartActivity([System.Runtime.CompilerServices.Nullable(1)] string name, ActivityKind kind, ActivityContext parentContext, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
0,
1,
2
})] IEnumerable<KeyValuePair<string, object>> tags = null, IEnumerable<ActivityLink> links = null, DateTimeOffset startTime = default(DateTimeOffset))
{
return StartActivity(name, kind, parentContext, null, tags, links, startTime);
}
[return: System.Runtime.CompilerServices.Nullable(2)]
public Activity StartActivity(string name, ActivityKind kind, string parentId, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
0,
1,
2
})] IEnumerable<KeyValuePair<string, object>> tags = null, [System.Runtime.CompilerServices.Nullable(2)] IEnumerable<ActivityLink> links = null, DateTimeOffset startTime = default(DateTimeOffset))
{
return StartActivity(name, kind, default(ActivityContext), parentId, tags, links, startTime);
}
private Activity StartActivity(string name, ActivityKind kind, ActivityContext context, string parentId, IEnumerable<KeyValuePair<string, object>> tags, IEnumerable<ActivityLink> links, DateTimeOffset startTime)
{
SynchronizedList<ActivityListener> listeners = _listeners;
if (listeners == null || listeners.Count == 0)
return null;
Activity activity = null;
ActivityDataRequest dataRequest = ActivityDataRequest.None;
bool? ctxInitialized = null;
ActivityCreationOptions<ActivityContext> dataWithContext2 = default(ActivityCreationOptions<ActivityContext>);
if (parentId != null) {
ActivityCreationOptions<string> data2 = new ActivityCreationOptions<string>(this, name, parentId, kind, tags, links);
listeners.EnumWithFunc(delegate(ActivityListener listener, ref ActivityCreationOptions<string> data, ref ActivityDataRequest request, ref bool? canUseContext, ref ActivityCreationOptions<ActivityContext> dataWithContext) {
GetRequestedData<string> getRequestedDataUsingParentId = listener.GetRequestedDataUsingParentId;
if (getRequestedDataUsingParentId != null) {
ActivityDataRequest activityDataRequest2 = getRequestedDataUsingParentId(ref data);
if (activityDataRequest2 > request)
request = activityDataRequest2;
return request != ActivityDataRequest.AllDataAndRecorded;
}
GetRequestedData<ActivityContext> getRequestedDataUsingContext2 = listener.GetRequestedDataUsingContext;
if (getRequestedDataUsingContext2 != null) {
if (!canUseContext.HasValue) {
canUseContext = Activity.TryConvertIdToContext(parentId, out ActivityContext context2);
if (canUseContext.Value)
dataWithContext = new ActivityCreationOptions<ActivityContext>(data.Source, data.Name, context2, data.Kind, data.Tags, data.Links);
}
if (canUseContext.Value) {
ActivityDataRequest activityDataRequest3 = getRequestedDataUsingContext2(ref dataWithContext);
if (activityDataRequest3 > request)
request = activityDataRequest3;
return request != ActivityDataRequest.AllDataAndRecorded;
}
}
return true;
}, ref data2, ref dataRequest, ref ctxInitialized, ref dataWithContext2);
} else {
ActivityContext parent = (context == default(ActivityContext) && Activity.Current != null) ? Activity.Current.Context : context;
dataWithContext2 = new ActivityCreationOptions<ActivityContext>(this, name, parent, kind, tags, links);
listeners.EnumWithFunc(delegate(ActivityListener listener, ref ActivityCreationOptions<ActivityContext> data, ref ActivityDataRequest request, ref bool? canUseContext, ref ActivityCreationOptions<ActivityContext> dataWithContext) {
GetRequestedData<ActivityContext> getRequestedDataUsingContext = listener.GetRequestedDataUsingContext;
if (getRequestedDataUsingContext != null) {
if (listener.AutoGenerateRootContextTraceId && !canUseContext.HasValue && data.Parent == default(ActivityContext)) {
ActivityContext parent2 = new ActivityContext(ActivityTraceId.CreateRandom(), default(ActivitySpanId), ActivityTraceFlags.None, null, false);
dataWithContext = new ActivityCreationOptions<ActivityContext>(data.Source, data.Name, parent2, data.Kind, data.Tags, data.Links);
canUseContext = true;
}
ActivityDataRequest activityDataRequest = getRequestedDataUsingContext(ref data);
if (activityDataRequest > request)
request = activityDataRequest;
return request != ActivityDataRequest.AllDataAndRecorded;
}
return true;
}, ref dataWithContext2, ref dataRequest, ref ctxInitialized, ref dataWithContext2);
}
if (dataRequest != 0) {
if (ctxInitialized.HasValue && ctxInitialized.Value) {
context = dataWithContext2.Parent;
parentId = null;
}
activity = Activity.CreateAndStart(this, name, kind, parentId, context, tags, links, startTime, dataRequest);
listeners.EnumWithAction(delegate(ActivityListener listener, object obj) {
listener.ActivityStarted?.Invoke((Activity)obj);
}, activity);
}
return activity;
}
public void Dispose()
{
_listeners = null;
s_activeSources.Remove(this);
}
public static void AddActivityListener(ActivityListener listener)
{
if (listener == null)
throw new ArgumentNullException("listener");
if (s_allListeners.AddIfNotExist(listener))
s_activeSources.EnumWithAction(delegate(ActivitySource source, object obj) {
Func<ActivitySource, bool> shouldListenTo = ((ActivityListener)obj).ShouldListenTo;
if (shouldListenTo != null && shouldListenTo(source))
source.AddListener((ActivityListener)obj);
}, listener);
}
internal void AddListener(ActivityListener listener)
{
if (_listeners == null)
Interlocked.CompareExchange(ref _listeners, new SynchronizedList<ActivityListener>(), null);
_listeners.AddIfNotExist(listener);
}
internal static void DetachListener(ActivityListener listener)
{
s_allListeners.Remove(listener);
s_activeSources.EnumWithAction(delegate(ActivitySource source, object obj) {
source._listeners?.Remove((ActivityListener)obj);
}, listener);
}
internal void NotifyActivityStart(Activity activity)
{
SynchronizedList<ActivityListener> listeners = _listeners;
if (listeners != null && listeners.Count > 0)
listeners.EnumWithAction(delegate(ActivityListener listener, object obj) {
listener.ActivityStarted?.Invoke((Activity)obj);
}, activity);
}
internal void NotifyActivityStop(Activity activity)
{
SynchronizedList<ActivityListener> listeners = _listeners;
if (listeners != null && listeners.Count > 0)
listeners.EnumWithAction(delegate(ActivityListener listener, object obj) {
listener.ActivityStopped?.Invoke((Activity)obj);
}, activity);
}
}
}