Created
March 14, 2021 19:14
-
-
Save ladeak/9889acc08821de73d675c22679704425 to your computer and use it in GitHub Desktop.
ActivityLogWriter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.Logging; | |
namespace ConsoleApp2 | |
{ | |
public class ActivityLogWriter : IActivityWriter | |
{ | |
private readonly ILogger<ActivityLogWriter> _logger; | |
public ActivityLogWriter(ILogger<ActivityLogWriter> logger) | |
{ | |
_logger = logger; | |
} | |
public ValueTask Write(Activity activity) | |
{ | |
_logger.LogInformation($"Name: { activity.OperationName}, Duration: {activity.Duration}"); | |
return ValueTask.CompletedTask; | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using Microsoft.Extensions.Logging; | |
using Microsoft.Extensions.Logging.Abstractions; | |
namespace ConsoleApp2 | |
{ | |
public partial class Program | |
{ | |
public class ActivityTraceBuilder | |
{ | |
private readonly Func<string, bool> _sourceFilter; | |
private readonly Action<Activity> _onActivity; | |
private readonly IActivityWriter _writer; | |
private readonly ILoggerFactory _loggerFactory; | |
private ActivityTraceBuilder(Func<string, bool> sourceFilter, Action<Activity> onActivity, IActivityWriter writer, ILoggerFactory loggerFactory) | |
{ | |
_sourceFilter = sourceFilter; | |
_onActivity = onActivity; | |
_writer = writer; | |
_loggerFactory = loggerFactory; | |
} | |
public static ActivityTraceBuilder Create(IActivityWriter writer) => new ActivityTraceBuilder(null, null, writer, null); | |
public static ActivityTraceBuilder CreateCaptureToLog(ILoggerFactory loggerFactory) => new ActivityTraceBuilder(null, null, new ActivityLogWriter(loggerFactory.CreateLogger<ActivityLogWriter>()), loggerFactory); | |
public ActivityTraceBuilder WithFilter(Func<string, bool> sourceFilter) => new ActivityTraceBuilder(sourceFilter, _onActivity, _writer, _loggerFactory); | |
public ActivityTraceBuilder WithOnActivity(Action<Activity> onActivity) => new ActivityTraceBuilder(_sourceFilter, onActivity, _writer, _loggerFactory); | |
public ActivityTraceBuilder WithLogger(ILoggerFactory loggerFactory) => new ActivityTraceBuilder(_sourceFilter, _onActivity, _writer, loggerFactory); | |
public ChannledActivityListener Build() | |
{ | |
return new ChannledActivityListener(_sourceFilter, _onActivity, _writer, _loggerFactory?.CreateLogger<ChannledActivityListener>() ?? NullLogger<ChannledActivityListener>.Instance); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Threading; | |
using System.Threading.Channels; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.Logging; | |
namespace ConsoleApp2 | |
{ | |
public class ChannledActivityListener : IDisposable, IAsyncDisposable | |
{ | |
private readonly ActivityListener _listener; | |
private readonly Action<Activity> _onActivity; | |
private readonly IActivityWriter _writer; | |
private readonly ILogger<ChannledActivityListener> _logger; | |
private readonly Channel<Activity> _channel = Channel.CreateBounded<Activity>(new BoundedChannelOptions(128) { SingleReader = true, FullMode = BoundedChannelFullMode.Wait }); | |
private readonly TaskCompletionSource _taskCompletionSource = new TaskCompletionSource(); | |
public ChannledActivityListener(Func<string, bool> sourceFilter, Action<Activity> onActivity, IActivityWriter writer, ILogger<ChannledActivityListener> logger) | |
{ | |
_writer = writer ?? throw new ArgumentNullException(nameof(writer)); | |
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | |
_listener = new ActivityListener(); | |
_listener.ShouldListenTo = source => sourceFilter?.Invoke(source.Name) ?? true; | |
_onActivity = onActivity; | |
_listener.ActivityStopped = OnActivityComplete; | |
_listener.Sample = new SampleActivity<ActivityContext>((ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData); | |
_ = Run(); | |
ActivitySource.AddActivityListener(_listener); | |
} | |
public async Task Run(CancellationToken token = default) | |
{ | |
try | |
{ | |
while (await _channel.Reader.WaitToReadAsync(token)) | |
{ | |
while (!token.IsCancellationRequested && _channel.Reader.TryRead(out var activity)) | |
{ | |
await _writer.Write(activity); | |
} | |
} | |
} | |
finally | |
{ | |
_taskCompletionSource.SetResult(); | |
} | |
} | |
public void OnActivityComplete(Activity activity) | |
{ | |
_onActivity?.Invoke(activity); | |
if (!_channel.Writer.TryWrite(activity)) | |
{ | |
_logger.LogError("Bounded channel returns false, when the queue is full"); | |
} | |
} | |
public void Dispose() | |
{ | |
_channel.Writer.TryComplete(); | |
_channel.Reader.Completion.GetAwaiter().GetResult(); | |
_taskCompletionSource.Task.GetAwaiter().GetResult(); | |
_listener.Dispose(); | |
} | |
public async ValueTask DisposeAsync() | |
{ | |
_listener.Dispose(); | |
_channel.Writer.TryComplete(); | |
await _channel.Reader.Completion; | |
await _taskCompletionSource.Task; | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
using System.Threading.Tasks; | |
namespace ConsoleApp2 | |
{ | |
public interface IActivityWriter | |
{ | |
ValueTask Write(Activity activity); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment