Skip to content

Commit

Permalink
Rename SignalR transport metrics to be consistent with OpenTelemetry (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Aug 5, 2023
1 parent f1cbb0c commit 4fe394c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ public HttpConnectionsMetrics(IMeterFactory meterFactory)
_meter = meterFactory.Create(MeterName);

_connectionDuration = _meter.CreateHistogram<double>(
"signalr-http-transport-connection-duration",
"signalr.server.connection.duration",
unit: "s",
description: "The duration of connections on the server.");

_currentConnectionsCounter = _meter.CreateUpDownCounter<long>(
"signalr-http-transport-current-connections",
"signalr.server.active_connections",
unit: "{connection}",
description: "Number of connections that are currently active on the server.");
}

Expand All @@ -46,8 +47,8 @@ public void ConnectionStop(in MetricsContext metricsContext, HttpTransportType t
{
var duration = Stopwatch.GetElapsedTime(startTimestamp, currentTimestamp);
_connectionDuration.Record(duration.TotalSeconds,
new KeyValuePair<string, object?>("status", status.ToString()),
new KeyValuePair<string, object?>("transport", transportType.ToString()));
new KeyValuePair<string, object?>("signalr.connection.status", ResolveStopStatus(status)),
new KeyValuePair<string, object?>("signalr.transport", ResolveTransportType(transportType)));
}
}

Expand All @@ -58,7 +59,7 @@ public void ConnectionTransportStart(in MetricsContext metricsContext, HttpTrans
// Tags must match transport end.
if (metricsContext.CurrentConnectionsCounterEnabled)
{
_currentConnectionsCounter.Add(1, new KeyValuePair<string, object?>("transport", transportType.ToString()));
_currentConnectionsCounter.Add(1, new KeyValuePair<string, object?>("signalr.transport", ResolveTransportType(transportType)));
}
}

Expand All @@ -70,11 +71,33 @@ public void TransportStop(in MetricsContext metricsContext, HttpTransportType tr
// If the transport type is none then the transport was never started for this connection.
if (transportType != HttpTransportType.None)
{
_currentConnectionsCounter.Add(-1, new KeyValuePair<string, object?>("transport", transportType.ToString()));
_currentConnectionsCounter.Add(-1, new KeyValuePair<string, object?>("signalr.transport", ResolveTransportType(transportType)));
}
}
}

private static string ResolveTransportType(HttpTransportType transportType)
{
return transportType switch
{
HttpTransportType.ServerSentEvents => "server_sent_events",
HttpTransportType.LongPolling => "long_polling",
HttpTransportType.WebSockets => "web_sockets",
_ => throw new InvalidOperationException("Unexpected value: " + transportType)
};
}

private static string ResolveStopStatus(HttpConnectionStopStatus connectionStopStatus)
{
return connectionStopStatus switch
{
HttpConnectionStopStatus.NormalClosure => "normal_closure",
HttpConnectionStopStatus.Timeout => "timeout",
HttpConnectionStopStatus.AppShutdown => "app_shutdown",
_ => throw new InvalidOperationException("Unexpected value: " + connectionStopStatus)
};
}

public void Dispose()
{
_meter.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1094,8 +1094,8 @@ public async Task Metrics()
using (StartVerifiableLog())
{
var testMeterFactory = new TestMeterFactory();
using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr.server.connection.duration");
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr.server.active_connections");

var metrics = new HttpConnectionsMetrics(testMeterFactory);
var manager = CreateConnectionManager(LoggerFactory, metrics);
Expand All @@ -1122,8 +1122,8 @@ public async Task Metrics()
var exists = manager.TryGetConnection(connection.ConnectionId, out _);
Assert.False(exists);

Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m => AssertDuration(m, HttpConnectionStopStatus.NormalClosure, HttpTransportType.LongPolling));
Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertTransport(m, 1, HttpTransportType.LongPolling), m => AssertTransport(m, -1, HttpTransportType.LongPolling));
Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m => AssertDuration(m, "normal_closure", "long_polling"));
Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertTransport(m, 1, "long_polling"), m => AssertTransport(m, -1, "long_polling"));
}
}

Expand All @@ -1150,8 +1150,8 @@ public async Task Metrics_ListenStartAfterConnection_Empty()
await dispatcher.ExecuteAsync(context, new HttpConnectionDispatcherOptions(), app);
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);

using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr.server.connection.duration");
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr.server.active_connections");

await dispatcher.ExecuteAsync(context, new HttpConnectionDispatcherOptions(), app);

Expand All @@ -1166,17 +1166,17 @@ public async Task Metrics_ListenStartAfterConnection_Empty()
}
}

private static void AssertTransport(CollectedMeasurement<long> measurement, long expected, HttpTransportType transportType)
private static void AssertTransport(CollectedMeasurement<long> measurement, long expected, string transportType)
{
Assert.Equal(expected, measurement.Value);
Assert.Equal(transportType.ToString(), (string)measurement.Tags["transport"]);
Assert.Equal(transportType.ToString(), (string)measurement.Tags["signalr.transport"]);
}

private static void AssertDuration(CollectedMeasurement<double> measurement, HttpConnectionStopStatus status, HttpTransportType transportType)
private static void AssertDuration(CollectedMeasurement<double> measurement, string status, string transportType)
{
Assert.True(measurement.Value > 0);
Assert.Equal(status.ToString(), (string)measurement.Tags["status"]);
Assert.Equal(transportType.ToString(), (string)measurement.Tags["transport"]);
Assert.Equal(status.ToString(), (string)measurement.Tags["signalr.connection.status"]);
Assert.Equal(transportType.ToString(), (string)measurement.Tags["signalr.transport"]);
}

[Fact]
Expand Down

0 comments on commit 4fe394c

Please sign in to comment.