Skip to content

Commit

Permalink
Merge pull request #322 from Shyam-Gupta/dev/shgu/etwEvents
Browse files Browse the repository at this point in the history
Added ETW events
  • Loading branch information
AArnott authored Aug 17, 2019
2 parents 7f5f1af + a0ba0d7 commit 8cc34f1
Show file tree
Hide file tree
Showing 2 changed files with 404 additions and 8 deletions.
111 changes: 103 additions & 8 deletions src/StreamJsonRpc/JsonRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,12 +1108,20 @@ protected async Task<TResult> InvokeCoreAsync<TResult>(long? id, string targetNa
{
if (!request.IsResponseExpected)
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Verbose, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingNotification(targetName, JsonRpcEventSource.GetArgumentsString(arguments));
}

await this.TransmitAsync(request, cts.Token).ConfigureAwait(false);

return default;
}

Verify.Operation(this.readLinesTask != null, Resources.InvalidBeforeListenHasStarted);
var tcs = new TaskCompletionSource<TResult>();
string responseDetails = string.Empty;

Action<JsonRpcMessage> dispatcher = (response) =>
{
lock (this.dispatcherMapLock)
Expand All @@ -1130,6 +1138,11 @@ protected async Task<TResult> InvokeCoreAsync<TResult>(long? id, string targetNa
this.TraceSource.TraceEvent(TraceEventType.Warning, (int)TraceEvents.RequestAbandonedByRemote, "Aborting pending request \"{0}\" because the connection was lost.", id);
}

if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Warning, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.ReceivedNoResponse(id.Value);
}

if (cancellationToken.IsCancellationRequested)
{
// Consider lost connection to be result of task canceled and set state to canceled.
Expand All @@ -1142,6 +1155,11 @@ protected async Task<TResult> InvokeCoreAsync<TResult>(long? id, string targetNa
}
else if (response is JsonRpcError error)
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Warning, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.ReceivedError(id.Value, error.Error.Code);
}

if (error.Error?.Code == JsonRpcErrorCode.RequestCanceled)
{
tcs.TrySetCanceled(cancellationToken.IsCancellationRequested ? cancellationToken : CancellationToken.None);
Expand All @@ -1153,6 +1171,11 @@ protected async Task<TResult> InvokeCoreAsync<TResult>(long? id, string targetNa
}
else if (response is JsonRpcResult result)
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.ReceivedResult(id.Value);
}

tcs.TrySetResult(result.GetResult<TResult>());
}
}
Expand All @@ -1170,6 +1193,11 @@ protected async Task<TResult> InvokeCoreAsync<TResult>(long? id, string targetNa

try
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Verbose, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingRequest(id.Value, targetName, JsonRpcEventSource.GetArgumentsString(arguments));
}

await this.TransmitAsync(request, cts.Token).ConfigureAwait(false);
}
catch
Expand Down Expand Up @@ -1421,6 +1449,7 @@ private async ValueTask<JsonRpcMessage> DispatchIncomingRequestAsync(JsonRpcRequ
Requires.NotNull(request, nameof(request));

CancellationTokenSource localMethodCancellationSource = null;
long idAsLongIfPossible = request.Id is long id ? id : -1;
try
{
TargetMethod targetMethod = null;
Expand Down Expand Up @@ -1507,6 +1536,18 @@ private async ValueTask<JsonRpcMessage> DispatchIncomingRequestAsync(JsonRpcRequ
this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEvents.LocalInvocation, "Invoking {0}", targetMethod);
}

if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Verbose, System.Diagnostics.Tracing.EventKeywords.None))
{
if (request.IsResponseExpected)
{
JsonRpcEventSource.Instance.ReceivedRequest(idAsLongIfPossible, request.Method, JsonRpcEventSource.GetArgumentsString(request.Arguments));
}
else
{
JsonRpcEventSource.Instance.ReceivedNotification(request.Method, JsonRpcEventSource.GetArgumentsString(request.Arguments));
}
}

// Yield now so method invocation is async and we can proceed to handle other requests meanwhile.
// IMPORTANT: This should be the first await in this async method,
// and no other await should be between this one and actually invoking the target method.
Expand All @@ -1522,6 +1563,11 @@ private async ValueTask<JsonRpcMessage> DispatchIncomingRequestAsync(JsonRpcRequ

if (!(result is Task resultingTask))
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingResult(idAsLongIfPossible);
}

return new JsonRpcResult
{
Id = request.Id,
Expand All @@ -1546,7 +1592,14 @@ private async ValueTask<JsonRpcMessage> DispatchIncomingRequestAsync(JsonRpcRequ
}
catch (Exception ex) when (!this.IsFatalException(StripExceptionToInnerException(ex)))
{
return this.CreateError(request, ex);
JsonRpcError error = this.CreateError(request, ex);

if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Warning, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingError(idAsLongIfPossible, error.Error.Code);
}

return error;
}
finally
{
Expand All @@ -1573,6 +1626,7 @@ private JsonRpcMessage HandleInvocationTaskResult(JsonRpcRequest request, Task t
throw new ArgumentException(Resources.TaskNotCompleted, nameof(t));
}

JsonRpcMessage result;
if (t.IsFaulted)
{
var exception = StripExceptionToInnerException(t.Exception);
Expand All @@ -1586,12 +1640,11 @@ private JsonRpcMessage HandleInvocationTaskResult(JsonRpcRequest request, Task t
this.OnJsonRpcDisconnected(e);
}

return this.CreateError(request, t.Exception);
result = this.CreateError(request, t.Exception);
}

if (t.IsCanceled)
else if (t.IsCanceled)
{
return new JsonRpcError
result = new JsonRpcError
{
Id = request.Id,
Error = new JsonRpcError.ErrorDetail
Expand All @@ -1601,11 +1654,31 @@ private JsonRpcMessage HandleInvocationTaskResult(JsonRpcRequest request, Task t
},
};
}
else
{
result = new JsonRpcResult
{
Id = request.Id,
};
}

return new JsonRpcResult
long idIfPossible = request.Id is long id ? id : -1;
if (result is JsonRpcError error)
{
Id = request.Id,
};
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Warning, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingError(idIfPossible, error.Error.Code);
}
}
else
{
if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingResult(idIfPossible);
}
}

return result;
}

private JsonRpcMessage HandleInvocationTaskOfTResult(JsonRpcRequest request, Task t)
Expand Down Expand Up @@ -1875,6 +1948,11 @@ private async Task HandleCancellationNotificationAsync(JsonRpcRequest request)
this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEvents.ReceivedCancellation, "Cancellation request received for \"{0}\".", id);
}

if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.ReceivedCancellationRequest(id is long v ? v : -1);
}

CancellationTokenSource cts;
lock (this.dispatcherMapLock)
{
Expand Down Expand Up @@ -1934,6 +2012,12 @@ private void CancelPendingOutboundRequest(object state)
{ "id", state },
},
};

if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
{
JsonRpcEventSource.Instance.SendingCancellationRequest(state is long v ? v : -1);
}

await this.TransmitAsync(cancellationMessage, this.DisconnectedToken).ConfigureAwait(false);
}
}).Forget();
Expand Down Expand Up @@ -1992,7 +2076,18 @@ private async ValueTask TransmitAsync(JsonRpcMessage message, CancellationToken
try
{
this.TraceMessageSent(message);
bool etwEnabled = JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None);
if (etwEnabled)
{
JsonRpcEventSource.Instance.TransmissionQueued();
}

await this.MessageHandler.WriteAsync(message, cancellationToken).ConfigureAwait(false);

if (etwEnabled)
{
JsonRpcEventSource.Instance.TransmissionCompleted();
}
}
catch (Exception exception)
{
Expand Down
Loading

0 comments on commit 8cc34f1

Please sign in to comment.