public static Dictionary <string, string> ParseHeaders( ServiceRemotingMessageHeaders messageHeaders, out string operationId) { var result = new Dictionary <string, string>(); if (messageHeaders.TryGetHeaderValue(HeaderListHeaderName, out string listString)) { string[] list = listString.Split(';'); foreach (string name in list) { if (messageHeaders.TryGetHeaderValue(CorrelationHeader.MakeHeader(name), out string value)) { result[name] = value; } } } if (result.TryGetValue(KnownProperty.OperationId, out string operationIdString)) { operationId = operationIdString; result.Remove(KnownProperty.OperationId); } else { operationId = Guid.NewGuid().ToString(); } return(result); }
private async Task <byte[]> HandleAndTrackRequestAsync(ServiceRemotingMessageHeaders messageHeaders, Func <Task <byte[]> > doHandleRequest) { Dictionary <string, string> contextProperties = CorrelationHeader.ParseHeaders(messageHeaders, out string operationId); // Create and prepare activity and RequestTelemetry objects to track this request. //RequestTelemetry rt = new RequestTelemetry(); /*if (messageHeaders.TryGetHeaderValue(ServiceRemotingLoggingStrings.ParentIdHeaderName, out string parentId)) * { * rt.Context.Operation.ParentId = parentId; * rt.Context.Operation.Id = GetOperationId(parentId); * }*/ // Do our best effort in setting the request name. string methodName = null; if (this._isActorService && messageHeaders.TryGetActorMethodAndInterfaceIds(out int methodId, out int interfaceId)) { methodName = this._methodNameProvider.GetMethodName(interfaceId, methodId); // Weird case, we couldn't find the method in the map. Just use the numerical id as the method name if (string.IsNullOrEmpty(methodName)) { methodName = methodId.ToString(); } } else { methodName = this._methodNameProvider.GetMethodName(messageHeaders.InterfaceId, messageHeaders.MethodId); // Weird case, we couldn't find the method in the map. Just use the numerical id as the method name if (string.IsNullOrEmpty(methodName)) { methodName = messageHeaders.MethodId.ToString(); } } //rt.Name = methodName; /*if (messageHeaders.TryGetHeaderValue(ServiceRemotingLoggingStrings.CorrelationContextHeaderName, out byte[] correlationBytes)) * { * var baggageBytesStream = new MemoryStream(correlationBytes, writable: false); * var dictionaryReader = XmlDictionaryReader.CreateBinaryReader(baggageBytesStream, XmlDictionaryReaderQuotas.Max); * var baggage = this.baggageSerializer.Value.ReadObject(dictionaryReader) as IEnumerable<KeyValuePair<string, string>>; * * foreach (KeyValuePair<string, string> pair in baggage) * { * rt.Context.Properties.Add(pair.Key, pair.Value); * } * }*/ // Call StartOperation, this will create a new activity with the current activity being the parent. // Since service remoting doesn't really have an URL like HTTP URL, we will do our best approximate that for // the Name, Type, Data, and Target properties //var operation = telemetryClient.StartOperation<RequestTelemetry>(rt); string currentOperationId = _switchOperationContext ? Guid.NewGuid().ToString() : operationId; using (L.Context(contextProperties)) using (L.Operation(currentOperationId)) { try { byte[] result = await doHandleRequest().ConfigureAwait(false); return(result); } catch (Exception e) { //telemetryClient.TrackException(e); //operation.Telemetry.Success = false; throw; } finally { // Stopping the operation, this will also pop the activity created by StartOperation off the activity stack. //telemetryClient.StopOperation(operation); } } }