Last active
August 18, 2021 04:26
-
-
Save itn3000/759d96d8bb4a7671770606de1b411950 to your computer and use it in GitHub Desktop.
System.IO.Stream with ActivitySource
This file contains hidden or 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.IO; | |
| using System.Diagnostics; | |
| using System; | |
| using System.Threading.Tasks; | |
| using System.Threading; | |
| namespace Diagnosticable | |
| { | |
| public class DiagnosticableStream : Stream | |
| { | |
| bool Disposed; | |
| Stream Upstream; | |
| bool LeaveOpen; | |
| string Name; | |
| static readonly ActivitySource m_Source = new ActivitySource("DiagnosticableStream"); | |
| public DiagnosticableStream(Stream upstream, bool leaveOpen, string name) | |
| { | |
| Upstream = upstream; | |
| LeaveOpen = leaveOpen; | |
| Name = name; | |
| Disposed = false; | |
| } | |
| public override bool CanRead => Upstream.CanRead; | |
| public override bool CanSeek => Upstream.CanSeek; | |
| public override bool CanWrite => Upstream.CanWrite; | |
| public override long Length => Upstream.Length; | |
| public override long Position | |
| { | |
| get | |
| { | |
| using var act = m_Source.StartActivity("PositionSet"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("value", Position); | |
| } | |
| try | |
| { | |
| return Upstream.Position; | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return Upstream.Position; | |
| } | |
| } | |
| set | |
| { | |
| using var act = m_Source.StartActivity("PositionGet"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| Upstream.Position = value; | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.Position = value; | |
| } | |
| } | |
| } | |
| public override void Flush() | |
| { | |
| using var act = m_Source.StartActivity("Flush"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| Upstream.Flush(); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.Flush(); | |
| } | |
| } | |
| public override async Task FlushAsync(CancellationToken cancellationToken) | |
| { | |
| using var act = m_Source.StartActivity("CopyToAsync"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| await Upstream.FlushAsync(cancellationToken).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| await Upstream.FlushAsync(cancellationToken).ConfigureAwait(false); | |
| } | |
| } | |
| public override int Read(byte[] buffer, int offset, int count) | |
| { | |
| using var act = m_Source.StartActivity("Read"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("offset", offset.ToString()); | |
| act.AddTag("count", count.ToString()); | |
| } | |
| try | |
| { | |
| return Upstream.Read(buffer, offset, count); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return Upstream.Read(buffer, offset, count); | |
| } | |
| } | |
| public override int Read(Span<byte> buffer) | |
| { | |
| using var act = m_Source.StartActivity("ReadSpan"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("length", buffer.Length.ToString()); | |
| } | |
| try | |
| { | |
| return Upstream.Read(buffer); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return Upstream.Read(buffer); | |
| } | |
| } | |
| public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | |
| { | |
| using var act = m_Source.StartActivity("ReadAsync"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("offset", offset.ToString()); | |
| act.AddTag("count", count.ToString()); | |
| } | |
| try | |
| { | |
| return await Upstream.ReadAsync(buffer, offset, count).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return await Upstream.ReadAsync(buffer, offset, count).ConfigureAwait(false); | |
| } | |
| } | |
| public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) | |
| { | |
| using var act = m_Source.StartActivity("ReadAsyncMemory"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("length", buffer.Length.ToString()); | |
| } | |
| try | |
| { | |
| return await Upstream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return await Upstream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); | |
| } | |
| } | |
| public override long Seek(long offset, SeekOrigin origin) | |
| { | |
| using var act = m_Source.StartActivity("Seek"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("offset", offset.ToString()); | |
| act.AddTag("origin", string.Intern(origin.ToString())); | |
| } | |
| try | |
| { | |
| return Upstream.Seek(offset, origin); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return Upstream.Seek(offset, origin); | |
| } | |
| } | |
| public override void SetLength(long value) | |
| { | |
| using var act = m_Source.StartActivity("SetLength"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("length", value.ToString()); | |
| } | |
| try | |
| { | |
| Upstream.SetLength(value); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.SetLength(value); | |
| } | |
| } | |
| public override void Write(byte[] buffer, int offset, int count) | |
| { | |
| using var act = m_Source.StartActivity("Write"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("offset", offset.ToString()); | |
| act.AddTag("count", count.ToString()); | |
| } | |
| try | |
| { | |
| Upstream.Write(buffer, offset, count); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.Write(buffer, offset, count); | |
| } | |
| } | |
| public override void Write(ReadOnlySpan<byte> buffer) | |
| { | |
| using var act = m_Source.StartActivity("WriteSpan"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("length", buffer.Length.ToString()); | |
| } | |
| try | |
| { | |
| Upstream.Write(buffer); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.Write(buffer); | |
| } | |
| } | |
| public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | |
| { | |
| using var act = m_Source.StartActivity("WriteAsync"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("offset", offset.ToString()); | |
| act.AddTag("count", count.ToString()); | |
| } | |
| try | |
| { | |
| await Upstream.WriteAsync(buffer, offset, count).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| await Upstream.WriteAsync(buffer, offset, count).ConfigureAwait(false); | |
| } | |
| } | |
| public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) | |
| { | |
| using var act = m_Source.StartActivity("WriteAsyncMemory"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("length", buffer.Length.ToString()); | |
| } | |
| try | |
| { | |
| await Upstream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| await Upstream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); | |
| } | |
| } | |
| public override void CopyTo(Stream destination, int bufferSize) | |
| { | |
| using var act = m_Source.StartActivity("CopyTo"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("bufferSize", bufferSize.ToString()); | |
| } | |
| try | |
| { | |
| Upstream.CopyTo(destination, bufferSize); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.CopyTo(destination, bufferSize); | |
| } | |
| } | |
| public override async Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) | |
| { | |
| using var act = m_Source.StartActivity("CopyToAsync"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("bufferSize", bufferSize.ToString()); | |
| } | |
| try | |
| { | |
| await Upstream.CopyToAsync(destination, bufferSize).ConfigureAwait(false); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| await Upstream.CopyToAsync(destination, bufferSize).ConfigureAwait(false); | |
| } | |
| } | |
| public override int ReadByte() | |
| { | |
| using var act = m_Source.StartActivity("ReadByte"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| return Upstream.ReadByte(); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| return Upstream.ReadByte(); | |
| } | |
| } | |
| public override void WriteByte(byte value) | |
| { | |
| using var act = m_Source.StartActivity("WriteByte"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| if (act.IsAllDataRequested) | |
| { | |
| act.AddTag("value", value.ToString()); | |
| } | |
| try | |
| { | |
| Upstream.WriteByte(value); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.WriteByte(value); | |
| } | |
| } | |
| protected override void Dispose(bool disposing) | |
| { | |
| if (!LeaveOpen && !Disposed) | |
| { | |
| Disposed = true; | |
| using var act = m_Source.StartActivity("Dispose"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| Upstream.Dispose(); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| Upstream.Dispose(); | |
| } | |
| } | |
| } | |
| public override async ValueTask DisposeAsync() | |
| { | |
| if (!LeaveOpen && !Disposed) | |
| { | |
| Disposed = true; | |
| using var act = m_Source.StartActivity("DisposeAsync"); | |
| if (act != null) | |
| { | |
| act.AddTag("name", Name); | |
| try | |
| { | |
| await Upstream.DisposeAsync(); | |
| } | |
| catch (Exception e) | |
| { | |
| act.AddTag("Exception", e.ToString()); | |
| throw; | |
| } | |
| } | |
| else | |
| { | |
| await Upstream.DisposeAsync(); | |
| } | |
| } | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently,
Exceptiontag is onlye.ToString(). Is it better to add event instead of tag?