Skip to content

Instantly share code, notes, and snippets.

@davidfowl
Last active April 6, 2024 20:17
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidfowl/54a9e8b98de8a50eb017b64dd70b379a to your computer and use it in GitHub Desktop.
Save davidfowl/54a9e8b98de8a50eb017b64dd70b379a to your computer and use it in GitHub Desktop.
Using Yarp.Telemetry.Consumption to track outbound network events (this package isn't tied to YARP)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Yarp.Telemetry.Consumption" Version="2.0.1" />
</ItemGroup>
</Project>
using System.Diagnostics;
using System.Net.Sockets;
using System.Security.Authentication;
using Yarp.Telemetry.Consumption;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTelemetryConsumer<TelemetryConsumer>();
var app = builder.Build();
app.MapGet("/", async () =>
{
var events = new EventList();
TelemetryConsumer.Events = events;
var client = new HttpClient();
try
{
await client.GetAsync("https://www.microsoft.com");
}
finally
{
foreach (var (Timestamp, Event) in events.GetRelativeEvents())
{
Console.WriteLine($"{Timestamp} - {Event}");
}
}
});
app.Run();
public class EventList
{
private readonly List<(long Timestamp, string Event)> _events = new();
public void Add(string name)
{
_events.Add((Stopwatch.GetTimestamp(), name));
}
public IEnumerable<(double Timestamp, string Event)> GetRelativeEvents()
{
foreach (var (timestamp, name) in _events)
{
yield return (Stopwatch.GetElapsedTime(_events[0].Timestamp, timestamp).TotalMilliseconds, name);
}
}
}
public sealed class TelemetryConsumer : IHttpTelemetryConsumer, INameResolutionTelemetryConsumer, INetSecurityTelemetryConsumer, ISocketsTelemetryConsumer
{
private static AsyncLocal<EventList> _events = new();
public static EventList Events
{
set => _events.Value = value;
}
private static void AddEvent(string name)
{
_events.Value?.Add(name);
}
public void OnConnectStart(DateTime timestamp, string address)
{
AddEvent($"OnConnectStart(address={address})");
}
public void OnConnectStop(DateTime timestamp)
{
AddEvent("OnConnectStop");
}
public void OnConnectFailed(DateTime timestamp, SocketError error, string exceptionMessage)
{
AddEvent($"OnConnectFailed(error={error}, exceptionMessage={exceptionMessage})");
}
public void OnResolutionStart(DateTime timestamp, string hostNameOrAddress)
{
AddEvent($"OnResolutionStart(hostNameOrAddress={hostNameOrAddress})");
}
public void OnResolutionStop(DateTime timestamp)
{
AddEvent("OnResolutionStop");
}
public void OnResolutionFailed(DateTime timestamp)
{
AddEvent("OnResolutionFailed");
}
public void OnHandshakeStart(DateTime timestamp, bool isServer, string targetHost)
{
AddEvent($"OnHandshakeStart(isServer={isServer}, targetHost={targetHost})");
}
public void OnHandshakeStop(DateTime timestamp, SslProtocols protocol)
{
AddEvent($"OnHandshakeStop(protocol={protocol})");
}
public void OnHandshakeFailed(DateTime timestamp, bool isServer, string targetHost, string exceptionMessage)
{
AddEvent($"OnHandshakeFailed(isServer={isServer}, targetHost={targetHost}, exceptionMessage={exceptionMessage})");
}
public void OnRequestStart(DateTime timestamp, string scheme, string host, int port, string pathAndQuery, int versionMajor, int versionMinor, HttpVersionPolicy versionPolicy)
{
AddEvent($"OnRequestStart(scheme={scheme}, host={host}, port={port}, pathAndQuery={pathAndQuery}, versionMajor={versionMajor}, versionMinor={versionMinor}, {versionPolicy})");
}
public void OnRequestStop(DateTime timestamp)
{
AddEvent("OnRequestStop");
}
public void OnConnectionEstablished(DateTime timestamp, int versionMajor, int versionMinor)
{
AddEvent($"OnConnectionEstablished(versionMajor={versionMajor}, versionMinor={versionMinor})");
}
public void OnRequestLeftQueue(DateTime timestamp, TimeSpan timeOnQueue, int versionMajor, int versionMinor)
{
AddEvent($"OnRequestLeftQueue(timeOnQueue={timeOnQueue.TotalMilliseconds}ms, versionMajor={versionMinor}, versionMinor={versionMinor})");
}
public void OnRequestHeadersStart(DateTime timestamp)
{
AddEvent("OnRequestHeadersStart");
}
public void OnRequestHeadersStop(DateTime timestamp)
{
AddEvent("OnRequestHeadersStop");
}
public void OnRequestContentStart(DateTime timestamp)
{
AddEvent("OnRequestContentStart");
}
public void OnRequestContentStop(DateTime timestamp, long contentLength)
{
AddEvent($"OnRequestContentStart(contentLength={contentLength})");
}
public void OnResponseHeadersStart(DateTime timestamp)
{
AddEvent("OnResponseHeadersStart");
}
public void OnResponseHeadersStop(DateTime timestamp)
{
AddEvent("OnResponseHeadersStop");
}
}
@davidfowl
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment