1+ using System . Diagnostics ;
2+ using System . Text . Json ;
3+ using Microsoft . AspNetCore . SignalR ;
4+ using Microsoft . Extensions . Logging ;
5+
6+ namespace SharedKernel . Logging ;
7+
8+ internal sealed class SignalRLoggingHubFilter ( ILogger < SignalRLoggingHubFilter > logger ) : IHubFilter
9+ {
10+ public async ValueTask < object ? > InvokeMethodAsync ( HubInvocationContext invocationContext ,
11+ Func < HubInvocationContext , ValueTask < object ? > > next )
12+ {
13+ var start = Stopwatch . GetTimestamp ( ) ;
14+
15+ // Basic context info
16+ var hubName = invocationContext . Hub . GetType ( )
17+ . Name ;
18+ var connectionId = invocationContext . Context . ConnectionId ;
19+ var userId = invocationContext . Context . UserIdentifier ;
20+ var methodName = invocationContext . HubMethodName ;
21+
22+ // Redact arguments
23+ var serializedArgs = JsonSerializer . Serialize ( invocationContext . HubMethodArguments ) ;
24+ var redactedArgs = RedactionHelper . ParseAndRedactJson ( serializedArgs ) ;
25+
26+ object ? result = null ;
27+ Exception ? exception = null ;
28+
29+ try
30+ {
31+ // Invoke the actual hub method
32+ result = await next ( invocationContext ) ;
33+ }
34+ catch ( Exception ex )
35+ {
36+ exception = ex ;
37+ }
38+
39+ var elapsedMs = Stopwatch . GetElapsedTime ( start )
40+ . TotalMilliseconds ;
41+
42+ if ( exception is not null )
43+ {
44+ logger . LogError ( exception ,
45+ "[SignalR] Hub {HubName}, ConnId {ConnectionId}, UserId {UserId} - Method {MethodName} threw an exception after {ElapsedMs}ms. " +
46+ "Inbound Args: {Args}" ,
47+ hubName ,
48+ connectionId ,
49+ userId ,
50+ methodName ,
51+ elapsedMs ,
52+ redactedArgs ) ;
53+ throw exception ;
54+ }
55+
56+ // Redact return value, if any
57+ var redactedResult = string . Empty ;
58+ if ( result is not null )
59+ {
60+ var serializedResult = JsonSerializer . Serialize ( result ) ;
61+ var redactedObj = RedactionHelper . ParseAndRedactJson ( serializedResult ) ;
62+ redactedResult = JsonSerializer . Serialize ( redactedObj ) ;
63+ }
64+
65+ logger . LogInformation (
66+ "[SignalR] Hub {HubName}, ConnId {ConnectionId}, UserId {UserId} - Method {MethodName} completed in {ElapsedMs}ms. " +
67+ "Inbound Args: {Args}, Outbound Result: {Result}" ,
68+ hubName ,
69+ connectionId ,
70+ userId ,
71+ methodName ,
72+ elapsedMs ,
73+ redactedArgs ,
74+ redactedResult ) ;
75+
76+ return result ;
77+ }
78+ }
0 commit comments