private void PushEvent(ServiceCallEvent e) { lock (_service_call_queue_lock) { serviceCallQueue.Enqueue(e); } }
private void SetCallEventRequestData(ServiceCallEvent callEvent, HttpServiceRequest requestData) { callEvent.ClientMetadata = requestData.TracingData; callEvent.ServiceMethod = requestData.Target?.MethodName; callEvent.RequestId = requestData.TracingData?.RequestID; callEvent.SpanId = requestData.TracingData?.SpanID; callEvent.ParentSpanId = requestData.TracingData?.ParentSpanID; }
private void SetCallEventRequestData(ServiceCallEvent callEvent, HttpServiceRequest requestData) { callEvent.ClientMetadata = requestData.TracingData; callEvent.ServiceMethod = requestData.Target?.MethodName; callEvent.RequestId = requestData.TracingData?.RequestID; callEvent.SpanId = requestData.TracingData?.SpanID; callEvent.ParentSpanId = requestData.TracingData?.ParentSpanID; callEvent.ContextUnencryptedTags = requestData.TracingData?.Tags?.GetUnencryptedTags(); callEvent.ContextTagsEncrypted = requestData.TracingData?.Tags?.GetEncryptedTags(); callEvent.UnknownTracingData = requestData.TracingData?.AdditionalProperties; }
public void TryPublish(ServiceCallEvent callEvent, IEnumerable <DictionaryEntry> arguments, ServiceMethod serviceMethod) { EndPointMetadata metaData = _serviceEndPointDefinition.GetMetaData(serviceMethod); callEvent.Params = arguments.SelectMany(_ => ExtractParamValues(_, metaData)).Select(_ => new Param { Name = _.name, Value = _.value, Sensitivity = _.sensitivity, }); _eventPublisher.TryPublish(callEvent); }
public void TryPublish(ServiceCallEvent callEvent, object[] arguments, ServiceMethod serviceMethod) { try { if (arguments != null) { callEvent.Params = ExtractParamValues(arguments, serviceMethod); } } catch (Exception e) { _log.Error("Can not extract params from request", exception: e, unencryptedTags: new { serviceInterfaceMethod = serviceMethod.ServiceInterfaceMethod.Name }); } _eventPublisher.TryPublish(callEvent); }
/// <summary> /// IUnityUpdatable update method, that will be called by uOS to process events /// inside Unity's thread. /// </summary> public void Update() { // Processes async events... lock (_service_call_queue_lock) { while (serviceCallQueue.Count > 0) { ServiceCallEvent e = serviceCallQueue.Dequeue(); e.callback(e.info, e.response, e.exception); } } // Updates server and radar. server.Update(); if (radar != null) { radar.Update(); } }
public async Task PublishExceptionEvent_WhileShouldExcludeStackTraceForFlume() { var evt = new ServiceCallEvent { Exception = new ArgumentException("Test Test").ThrowAndCatch() }; var serializedEvent = SerializerWithoutStackTrace.Serialize(evt).ToDictionary(_ => _.Name, _ => _.Value); serializedEvent.ShouldContainKey(EventConsts.exMessage); serializedEvent[EventConsts.exMessage].ShouldBe("Test Test"); serializedEvent.ShouldContainKey(EventConsts.exOneWordMessage); serializedEvent[EventConsts.exOneWordMessage].ShouldBe("Test_Test"); serializedEvent.ShouldContainKey(EventConsts.exType); serializedEvent[EventConsts.exType].ShouldBe(typeof(ArgumentException).FullName); serializedEvent.ShouldNotContainKey(EventConsts.exInnerMessages); serializedEvent.ShouldNotContainKey(EventConsts.exStackTrace); }
private async Task WriteResponseAndMeasureTime(HttpListenerContext context, byte[] body, ServiceCallEvent serviceCallEvent = null) { Stopwatch sw = new Stopwatch(); sw.Start(); await context.Response.OutputStream.WriteAsync(body, 0, body.Length); sw.Stop(); if (serviceCallEvent != null) { serviceCallEvent.ClientResponseTime = sw.Elapsed.TotalMilliseconds; } }
/// <summary> /// Writes to response output stream and returns response time /// </summary> /// <param name="context"></param> /// <param name="data"></param> /// <param name="httpStatus"></param> /// <param name="contentType"></param> /// <returns>double? - response time</returns> private async Task <bool> TryWriteResponse(HttpListenerContext context, string data, HttpStatusCode httpStatus = HttpStatusCode.OK, string contentType = "application/json", ServiceCallEvent serviceCallEvent = null) { context.Response.Headers.Add(GigyaHttpHeaders.ProtocolVersion, HttpServiceRequest.ProtocolVersion); var body = Encoding.UTF8.GetBytes(data ?? ""); context.Response.StatusCode = (int)httpStatus; context.Response.ContentLength64 = body.Length; context.Response.ContentType = contentType; context.Response.Headers.Add(GigyaHttpHeaders.DataCenter, Environment.Zone); context.Response.Headers.Add(GigyaHttpHeaders.Environment, Environment.DeploymentEnvironment); context.Response.Headers.Add(GigyaHttpHeaders.ServiceVersion, AppInfo.Version.ToString()); context.Response.Headers.Add(GigyaHttpHeaders.ServerHostname, CurrentApplicationInfo.HostName); context.Response.Headers.Add(GigyaHttpHeaders.SchemaHash, ServiceSchema.Hash); try { await WriteResponseAndMeasureTime(context, body, serviceCallEvent); return(true); } catch (HttpListenerException writeEx) { if (serviceCallEvent != null) { serviceCallEvent.Exception = writeEx; } // For some reason, HttpListener.IgnoreWriteExceptions doesn't work here. Log.Warn(_ => _("HttpServiceListener: Failed to write the response of a service call. See exception and tags for details.", exception: writeEx, unencryptedTags: new { remoteEndpoint = context.Request.RemoteEndPoint, rawUrl = context.Request.RawUrl, status = httpStatus }, encryptedTags: new { response = data })); return(false); } }
private async Task HandleRequest(HttpListenerContext context, long ticks, long timeFromLastReq) { try { var deltaDelayTicks = DateTime.UtcNow.Ticks - ticks; var sw = Stopwatch.StartNew(); RequestTimings.ClearCurrentTimings(); using (context.Response) { // Special endpoints should not be logged/measured/traced like regular endpoints // Access is allowed without HTTPS verifications since they don't expose anything sensitive (e.g. config values are encrypted) if (await TryHandleSpecialEndpoints(context)) { return; } // Regular endpoint handling using (_activeRequestsCounter.NewContext("Request")) { RequestTimings.GetOrCreate(); // initialize request timing context string methodName = null; // Initialize with empty object for protocol backwards-compatibility. var requestData = new HttpServiceRequest { TracingData = new TracingData() }; object[] argumentsWithDefaults = null; ServiceMethod serviceMethod = null; ServiceCallEvent callEvent = _serverRequestPublisher.GetNewCallEvent(); try { try { await CheckSecureConnection(context); ValidateRequest(context); requestData = await ParseRequest(context); //----------------------------------------------------------------------------------------- // Don't move TracingContext writes main flow, IT have to be here, to avoid side changes //----------------------------------------------------------------------------------------- TracingContext.SetRequestID(requestData.TracingData.RequestID); TracingContext.SpanStartTime = requestData.TracingData.SpanStartTime; TracingContext.AbandonRequestBy = requestData.TracingData.AbandonRequestBy; TracingContext.SetParentSpan( requestData.TracingData.SpanID ?? Guid.NewGuid().ToString("N")); TracingContext.SetOverrides(requestData.Overrides); if (requestData.TracingData.Tags != null) { TracingContext.Tags = new ContextTags(requestData.TracingData.Tags); } TracingContext.AdditionalProperties = requestData.TracingData.AdditionalProperties; callEvent.ServiceMethodSchema = context.Request.IsSecureConnection ? "HTTPS" : "HTTP"; SetCallEventRequestData(callEvent, requestData); serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target); callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name; methodName = serviceMethod.ServiceInterfaceMethod.Name; var arguments = requestData.Target.IsWeaklyTyped ? GetParametersByName(serviceMethod, requestData.Arguments) : requestData.Arguments.Values.Cast <object>().ToArray(); argumentsWithDefaults = GetConvertedAndDefaultArguments(serviceMethod.ServiceInterfaceMethod, arguments); if (_extendedDelayTimeLogging) { callEvent.RecvDateTicks = ticks; callEvent.ReqStartupDeltaTicks = deltaDelayTicks; callEvent.TimeFromLastReq = timeFromLastReq; var outstandingReqs = Interlocked.Read(ref OutstandingRequests); callEvent.OutstandingRequests = outstandingReqs; if (deltaDelayTicks > 10_000_000) { callEvent.CollectionCountGen0 = GC.CollectionCount(0); callEvent.CollectionCountGen1 = GC.CollectionCount(1); callEvent.CollectionCountGen2 = GC.CollectionCount(2); } } } catch (Exception e) { callEvent.Exception = e; if (e is RequestException) { throw; } throw new RequestException("Invalid request", e); } RejectRequestIfLateOrOverloaded(); var responseJson = await GetResponse(context, serviceMethod, requestData, argumentsWithDefaults); if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent)) { callEvent.ErrCode = 0; _successCounter.Increment(); } else { _failureCounter.Increment(); } } catch (Exception e) { callEvent.Exception = callEvent.Exception ?? e; _failureCounter.Increment(); Exception ex = GetRelevantException(e); string json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex)); await TryWriteResponse(context, json, GetExceptionStatusCode(ex), serviceCallEvent : callEvent); } finally { sw.Stop(); callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds; _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); if (methodName != null) { _endpointContext.Timer(methodName, Unit.Requests) .Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); } _serverRequestPublisher.TryPublish(callEvent, argumentsWithDefaults, serviceMethod); } } } } finally { Interlocked.Decrement(ref OutstandingRequests); } }
private async Task HandleRequest(HttpListenerContext context) { RequestTimings.ClearCurrentTimings(); using (context.Response) { var sw = Stopwatch.StartNew(); // Special endpoints should not be logged/measured/traced like regular endpoints if (await TryHandleSpecialEndpoints(context)) { return; } // Regular endpoint handling using (_activeRequestsCounter.NewContext("Request")) { RequestTimings.GetOrCreate(); // initialize request timing context string methodName = null; // Initialize with empty object for protocol backwards-compatibility. var requestData = new HttpServiceRequest { TracingData = new TracingData() }; object[] argumentsWithDefaults = null; ServiceMethod serviceMethod = null; ServiceCallEvent callEvent = _serverRequestPublisher.GetNewCallEvent(); try { try { ValidateRequest(context); await CheckSecureConnection(context); requestData = await ParseRequest(context); //----------------------------------------------------------------------------------------- // Don't move TracingContext writes main flow, IT have to be here, to avoid side changes //----------------------------------------------------------------------------------------- TracingContext.SetRequestID(requestData.TracingData.RequestID); TracingContext.SpanStartTime = requestData.TracingData.SpanStartTime; TracingContext.AbandonRequestBy = requestData.TracingData.AbandonRequestBy; TracingContext.SetParentSpan(requestData.TracingData.SpanID ?? Guid.NewGuid().ToString("N")); SetCallEventRequestData(callEvent, requestData); TracingContext.SetOverrides(requestData.Overrides); serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target); callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name; methodName = serviceMethod.ServiceInterfaceMethod.Name; var arguments = requestData.Target.IsWeaklyTyped ? GetParametersByName(serviceMethod, requestData.Arguments) : requestData.Arguments.Values.Cast <object>().ToArray(); argumentsWithDefaults = GetConvertedAndDefaultArguments(serviceMethod.ServiceInterfaceMethod, arguments); } catch (Exception e) { callEvent.Exception = e; if (e is RequestException) { throw; } throw new RequestException("Invalid request", e); } RejectRequestIfLateOrOverloaded(); var responseJson = await GetResponse(context, serviceMethod, requestData, argumentsWithDefaults); if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent)) { callEvent.ErrCode = 0; _successCounter.Increment(); } else { _failureCounter.Increment(); } } catch (Exception e) { callEvent.Exception = callEvent.Exception ?? e; _failureCounter.Increment(); Exception ex = GetRelevantException(e); string json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex)); await TryWriteResponse(context, json, GetExceptionStatusCode(ex), serviceCallEvent : callEvent); } finally { sw.Stop(); callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds; _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); if (methodName != null) { _endpointContext.Timer(methodName, Unit.Requests).Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); } _serverRequestPublisher.TryPublish(callEvent, argumentsWithDefaults, serviceMethod); } } } }
private async Task HandleRequest(HttpListenerContext context) { RequestTimings.ClearCurrentTimings(); using (context.Response) { var sw = Stopwatch.StartNew(); // Special endpoints should not be logged/measured/traced like regular endpoints if (await TryHandleSpecialEndpoints(context)) { return; } // Regular endpoint handling using (_activeRequestsCounter.NewContext("Request")) { TracingContext.SetUpStorage(); RequestTimings.GetOrCreate(); // initialize request timing context string methodName = null; // Initialize with empty object for protocol backwards-compatibility. var requestData = new HttpServiceRequest { TracingData = new TracingData() }; ServiceMethod serviceMethod = null; ServiceCallEvent callEvent = _serverRequestPublisher.GetNewCallEvent(); try { try { ValidateRequest(context); await CheckSecureConnection(context); requestData = await ParseRequest(context); SetCallEventRequestData(callEvent, requestData); TracingContext.SetOverrides(requestData.Overrides); serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target); callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name; methodName = serviceMethod.ServiceInterfaceMethod.Name; } catch (Exception e) { callEvent.Exception = e; if (e is RequestException) { throw; } throw new RequestException("Invalid request", e); } RejectRequestIfLateOrOverloaded(); var responseJson = await GetResponse(context, serviceMethod, requestData); if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent)) { callEvent.ErrCode = 0; _successCounter.Increment(); } else { _failureCounter.Increment(); } } catch (Exception e) { callEvent.Exception = callEvent.Exception ?? e; _failureCounter.Increment(); Exception ex = GetRelevantException(e); string json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex)); await TryWriteResponse(context, json, GetExceptionStatusCode(ex), serviceCallEvent : callEvent); } finally { sw.Stop(); callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds; _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); if (methodName != null) { _endpointContext.Timer(methodName, Unit.Requests).Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); } IEnumerable <DictionaryEntry> arguments = (requestData.Arguments ?? new OrderedDictionary()).Cast <DictionaryEntry>(); _serverRequestPublisher.TryPublish(callEvent, arguments, serviceMethod); } } } }
private void PushEvent(ServiceCallEvent e) { lock (_service_call_queue_lock) { serviceCallQueue.Enqueue(e); } }