public void TestSubsegment() { _recorder.BeginSubsegment("subsegment1"); Subsegment subsegment1 = (Subsegment)AWSXRayRecorder.Instance.TraceContext.GetEntity(); FacadeSegment facadeSegment = (FacadeSegment)subsegment1.RootSegment; _recorder.EndSubsegment(); Assert.AreEqual(typeof(LambdaContextContainer), AWSXRayRecorder.Instance.TraceContext.GetType()); Assert.AreEqual(facadeSegment.GetType(), typeof(FacadeSegment)); Assert.IsFalse(facadeSegment.Subsegments.Contains(subsegment1)); // only subsegment is streamed Assert.IsFalse(AWSXRayRecorder.Instance.TraceContext.IsEntityPresent()); // facade segment is cleared from AWSXRayRecorder.Instance.TraceContext }
/// <summary> /// Processes Begin request by starting subsegment. /// </summary> private void ProcessBeginRequest(IExecutionContext executionContext) { var request = executionContext.RequestContext.Request; Entity entity = null; try { entity = _recorder.GetEntity(); } catch (EntityNotAvailableException e) { _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing AWS SDK request"); } var serviceName = RemoveAmazonPrefixFromServiceName(request.ServiceName); _recorder.BeginSubsegment(AWSXRaySDKUtils.FormatServiceName(serviceName)); _recorder.SetNamespace("aws"); entity = entity == null ? null : _recorder.GetEntity(); if (TraceHeader.TryParse(entity, out TraceHeader traceHeader)) { request.Headers[TraceHeader.HeaderKey] = traceHeader.ToString(); } else { _logger.DebugFormat("Failed to inject trace header to AWS SDK request as the segment can't be converted to TraceHeader."); } }
/// <summary> /// Processes HTTP request. /// </summary> private void ProcessHTTPRequest(HttpContext context) { HttpRequest request = context.Request; string headerString = null; if (request.Headers.TryGetValue(TraceHeader.HeaderKey, out StringValues headerValue)) { if (headerValue.ToArray().Length >= 1) { headerString = headerValue.ToArray()[0]; } } // Trace header doesn't exist, which means this is the root node. Create a new traceId and inject the trace header. if (!TraceHeader.TryParse(headerString, out TraceHeader traceHeader)) { _logger.DebugFormat("Trace header doesn't exist or not valid : ({0}). Injecting a new one.", headerString); traceHeader = new TraceHeader { RootTraceId = TraceId.NewId(), ParentId = null, Sampled = SampleDecision.Unknown }; } bool isSampleDecisionRequested = traceHeader.Sampled == SampleDecision.Requested; // Make sample decision if (traceHeader.Sampled == SampleDecision.Unknown || traceHeader.Sampled == SampleDecision.Requested) { string serviceName = request.Host.Host; string url = request.Path; string method = request.Method; traceHeader.Sampled = _recorder.SamplingStrategy.Sample(serviceName, url, method); } if (AWSXRayRecorder.Instance.IsLambda()) { _recorder.BeginSubsegment(SegmentNamingStrategy.GetSegmentName(request)); } else { _recorder.BeginSegment(SegmentNamingStrategy.GetSegmentName(request), traceHeader.RootTraceId, traceHeader.ParentId, traceHeader.Sampled); } if (!AWSXRayRecorder.Instance.IsTracingDisabled()) { var requestAttributes = new Dictionary <string, object>(); PopulateRequestAttributes(request, requestAttributes); _recorder.AddHttpInformation("request", requestAttributes); } if (isSampleDecisionRequested) { context.Response.Headers.Add(TraceHeader.HeaderKey, traceHeader.ToString()); // Its recommended not to modify response header after _next.Invoke() call } }
public async Task <NumberPlateTrigger> FunctionHandler(S3Event evnt, ILambdaContext context) { var s3Event = evnt.Records?[0].S3; context.Logger.LogLine("EVENT Received: " + JsonConvert.SerializeObject(s3Event)); if (regExNumberPlate == null) { context.Logger.LogLine("regExNumberPlate is not yet populated. Calling getNumberPlateFromSecretsManager()..."); regExNumberPlate = await getNumberPlateFromSecretsManager(context); context.Logger.LogLine("regExNumberPlate is " + regExNumberPlate); } NumberPlateTrigger result = new NumberPlateTrigger { bucket = s3Event.Bucket.Name, key = s3Event.Object.Key, contentType = "", contentLength = s3Event.Object.Size, charge = int.Parse(Environment.GetEnvironmentVariable("TollgateCharge")), numberPlate = new NumberPlate() { numberPlateRegEx = this.regExNumberPlate, detected = false } }; AWSXRayRecorder recorder = AWSXRayRecorder.Instance; recorder.BeginSubsegment("TollGantry::Detect Number Plate in Captured Image"); recorder.AddMetadata("bucket", s3Event.Bucket.Name); recorder.AddMetadata("key", s3Event.Object.Key); recorder.AddMetadata("regex", this.regExNumberPlate); // // TODO: Call Rekognition to detect text in the captured image // recorder.EndSubsegment(); // // Kick off the step function // context.Logger.LogLine("Starting the state machine"); IAmazonStepFunctions stepFunctionsClient = new AmazonStepFunctionsClient(); await stepFunctionsClient.StartExecutionAsync(new StartExecutionRequest() { StateMachineArn = Environment.GetEnvironmentVariable("NumberPlateProcessStateMachine"), Input = JsonConvert.SerializeObject(result) }); context.Logger.LogLine("State machine started"); return(result); }
/// <inheritdoc /> public async Task <TResult> InterceptAsync <TResult>(Func <Task <TResult> > method, DbCommand command) { _recorder.BeginSubsegment(BuildSubsegmentName(command)); try { _recorder.SetNamespace("remote"); var ret = await method(); CollectSqlInformation(command); return(ret); } catch (Exception e) { _recorder.AddException(e); throw; } finally { _recorder.EndSubsegment(); } }
/// <summary> /// Processes Begin request by starting subsegment. /// </summary> private void ProcessBeginRequest(IExecutionContext executionContext) { var request = executionContext.RequestContext.Request; if (TraceHeader.TryParse(_recorder.GetEntity(), out TraceHeader traceHeader)) { request.Headers[TraceHeader.HeaderKey] = traceHeader.ToString(); } else { _logger.DebugFormat("Failed to inject trace header to AWS SDK request as the segment can't be converted to TraceHeader."); } _recorder.BeginSubsegment(RemoveAmazonPrefixFromServiceName(request.ServiceName)); _recorder.SetNamespace("aws"); }
private void ProcessBeginCommand(CommandEventData eventData) { Entity entity = null; try { entity = _recorder.GetEntity(); } catch (EntityNotAvailableException e) { _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing start of Entity Framework command."); } _recorder.BeginSubsegment(BuildSubsegmentName(eventData.Command)); _recorder.SetNamespace("remote"); CollectSqlInformation(eventData); }
public void TestTryParseSubsegment() { using (var recorder = new AWSXRayRecorder()) { recorder.BeginSegment("TraceHeaderTest", TraceId); recorder.BeginSubsegment("subjob"); var subsegment = TraceContext.GetEntity(); TraceHeader header; Assert.IsTrue(TraceHeader.TryParse(subsegment, out header)); Assert.AreEqual(TraceId, header.RootTraceId); Assert.AreEqual(subsegment.Id, header.ParentId); Assert.AreEqual(SampleDecision.Sampled, header.Sampled); recorder.EndSubsegment(); recorder.EndSegment(); } }
private void ProcessBeginRequest(IExecutionContext executionContext) { var request = executionContext.RequestContext.Request; Entity entity = null; try { entity = _recorder.GetEntity(); } catch (EntityNotAvailableException e) { _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing AWS SDK request"); } _recorder.BeginSubsegment(RemoveAmazonPrefixFromServiceName(request.ServiceName)); _recorder.SetNamespace("aws"); entity = entity == null ? null : _recorder.GetEntity(); if (TraceHeader.TryParse(entity, out var traceHeader)) { request.Headers[TraceHeader.HeaderKey] = traceHeader.ToString(); if (request.Parameters.Any(p => p.Value == "AWSTraceHeader")) { return; } var index = request .Parameters .Where(x => x.Key.StartsWith("MessageSystemAttribute")) .Select(x => int.TryParse(x.Value.Split('.')[1], out var idx) ? idx : 0) .Union(new[] { 0 }) .Max() + 1; request.Parameters.Add("MessageSystemAttribute" + "." + index + "." + "Name", StringUtils.FromString("AWSTraceHeader")); request.Parameters.Add("MessageSystemAttribute" + "." + index + "." + "Value.DataType", StringUtils.FromString("String")); request.Parameters.Add("MessageSystemAttribute" + "." + index + "." + "Value" + "." + "StringValue", StringUtils.FromString(traceHeader.ToString())); } }
private void BeforeRequestEventHandler(object sender, RequestEventArgs e) { var args = e as WebServiceRequestEventArgs; if (args == null) { _logger.DebugFormat("Failed to handle BeforeRequestEvent, because e can't be converted to WebServiceRequestEventArgs."); return; } if (TraceHeader.TryParse(_recorder.GetEntity(), out TraceHeader traceHeader)) { args.Headers[TraceHeader.HeaderKey] = traceHeader.ToString(); } else { _logger.DebugFormat("Failed to inject trace header to AWS SDK request as the segment can't be converted to TraceHeader."); } _recorder.BeginSubsegment(RemoveAmazonPrefixFromServiceName(args.ServiceName)); _recorder.SetNamespace("aws"); }
public void TestLogErrorModeForContextMissingStrategy() { using (var recorder = new AWSXRayRecorder()) { recorder.ContextMissingStrategy = ContextMissingStrategy.LOG_ERROR; recorder.EndSegment(); recorder.BeginSubsegment("no segment"); recorder.EndSubsegment(); recorder.SetNamespace("dummy namespace"); recorder.AddAnnotation("key", "value"); recorder.AddHttpInformation("key", "value"); recorder.MarkError(); recorder.MarkFault(); recorder.MarkThrottle(); recorder.AddException(new ArgumentNullException()); recorder.AddPrecursorId(Entity.GenerateId()); recorder.AddSqlInformation("sqlKey", "value"); recorder.AddMetadata("key", "value"); } }
/// <summary> /// Processes Begin request by starting subsegment. /// </summary> private void ProcessBeginRequest(IExecutionContext executionContext) { if (AWSXRayRecorder.Instance.IsTracingDisabled()) { _logger.DebugFormat("X-Ray tracing is disabled, do not handle AWSSDK request."); return; } var request = executionContext.RequestContext.Request; if (TraceHeader.TryParse(TraceContext.GetEntity(), out TraceHeader traceHeader)) { request.Headers[TraceHeader.HeaderKey] = traceHeader.ToString(); } else { _logger.DebugFormat("Failed to inject trace header to AWS SDK request as the segment can't be converted to TraceHeader."); } _recorder.BeginSubsegment(RemoveAmazonPrefixFromServiceName(request.ServiceName)); _recorder.SetNamespace("aws"); }
private TResult Intercept <TResult>(Func <TResult> method) { AWSXRayRecorder recorder = AWSXRayRecorder.Instance; recorder.BeginSubsegment(Connection.Database + "@" + SqlUtil.RemovePortNumberFromDataSource(Connection.DataSource)); try { recorder.SetNamespace("remote"); var ret = method(); CollectSqlInformation(); return(ret); } catch (Exception e) { recorder.AddException(e); throw; } finally { recorder.EndSubsegment(); } }
public void TestSyncCreateSegmentAndSubsegments() { _recorder.BeginSegment("parent", TraceId); Segment parent = (Segment)AWSXRayRecorder.Instance.TraceContext.GetEntity(); _recorder.BeginSubsegment("child"); Subsegment child = (Subsegment)AWSXRayRecorder.Instance.TraceContext.GetEntity(); _recorder.EndSubsegment(); Assert.ReferenceEquals(AWSXRayRecorder.Instance.TraceContext.GetEntity(), parent); _recorder.EndSegment(); Assert.ReferenceEquals(parent, child.Parent); Assert.IsTrue(parent.Subsegments.Contains(child)); }
/// <summary> /// Process command to begin subsegment. /// </summary> /// <param name="command">Instance of <see cref="DbCommand"/>.</param> /// <param name="collectSqlQueriesOverride">Nullable to indicate whether to collect sql query text or not.</param> internal static void ProcessBeginCommand(DbCommand command, bool?collectSqlQueriesOverride) { _recorder.BeginSubsegment(BuildSubsegmentName(command)); _recorder.SetNamespace("remote"); CollectSqlInformation(command, collectSqlQueriesOverride); }
/// <summary> /// Process http request. /// </summary> internal static void ProcessRequest(HttpContext httpContext) { HttpRequest request = httpContext.Request; string headerString = null; if (request.Headers.TryGetValue(TraceHeader.HeaderKey, out StringValues headerValue)) { if (headerValue.Count >= 1) { headerString = headerValue[0]; } } if (!TraceHeader.TryParse(headerString, out TraceHeader traceHeader)) { _logger.DebugFormat("Trace header doesn't exist or not valid : ({0}). Injecting a new one.", headerString); traceHeader = new TraceHeader { RootTraceId = TraceId.NewId(), ParentId = null, Sampled = SampleDecision.Unknown }; } var segmentName = SegmentNamingStrategy.GetSegmentName(request); bool isSampleDecisionRequested = traceHeader.Sampled == SampleDecision.Requested; string ruleName = null; // Make sample decision if (traceHeader.Sampled == SampleDecision.Unknown || traceHeader.Sampled == SampleDecision.Requested) { string host = request.Host.Host; string url = request.Path; string method = request.Method; SamplingInput samplingInput = new SamplingInput(host, url, method, segmentName, _recorder.Origin); SamplingResponse sampleResponse = _recorder.SamplingStrategy.ShouldTrace(samplingInput); traceHeader.Sampled = sampleResponse.SampleDecision; ruleName = sampleResponse.RuleName; } if (AWSXRayRecorder.IsLambda()) { _recorder.BeginSubsegment(segmentName); } else { SamplingResponse samplingResponse = new SamplingResponse(ruleName, traceHeader.Sampled); // get final ruleName and SampleDecision _recorder.BeginSegment(SegmentNamingStrategy.GetSegmentName(request), traceHeader.RootTraceId, traceHeader.ParentId, samplingResponse); } if (!AWSXRayRecorder.Instance.IsTracingDisabled()) { var requestAttributes = PopulateRequestAttributes(request); _recorder.AddHttpInformation("request", requestAttributes); } // Mark the segment as auto-instrumented AgentUtil.AddAutoInstrumentationMark(); if (isSampleDecisionRequested) { httpContext.Response.Headers.Add(TraceHeader.HeaderKey, traceHeader.ToString()); // Its recommended not to modify response header after _next.Invoke() call } }
public async Task <NumberPlateTrigger> FunctionHandler(S3Event evnt, ILambdaContext context) { var s3Event = evnt.Records?[0].S3; context.Logger.LogLine("EVENT Received: " + JsonConvert.SerializeObject(s3Event)); if (regExNumberPlate == null) { context.Logger.LogLine("regExNumberPlate is not yet populated. Calling getNumberPlateFromSecretsManager()..."); regExNumberPlate = await getNumberPlateFromSecretsManager(context); context.Logger.LogLine("regExNumberPlate is " + regExNumberPlate); } //var response = await this.S3Client.GetObjectMetadataAsync(s3Event.Bucket.Name, s3Event.Object.Key); //return response.Headers.ContentType; NumberPlateTrigger result = new NumberPlateTrigger { bucket = s3Event.Bucket.Name, key = s3Event.Object.Key, contentType = "", contentLength = s3Event.Object.Size, charge = int.Parse(Environment.GetEnvironmentVariable("TollgateCharge")), numberPlate = new NumberPlate() { numberPlateRegEx = this.regExNumberPlate, detected = false } }; recorder.BeginSubsegment("TollGantry::Detect Number Plate in Captured Image"); recorder.AddMetadata("bucket", s3Event.Bucket.Name); recorder.AddMetadata("key", s3Event.Object.Key); recorder.AddMetadata("regex", this.regExNumberPlate); S3Object s3Object = new S3Object(); s3Object.Bucket = s3Event.Bucket.Name; s3Object.Name = s3Event.Object.Key; DetectTextRequest detectTextReq = new DetectTextRequest { Image = new Image { S3Object = s3Object } }; context.Logger.LogLine("Calling Rekognition ... "); DetectTextResponse detectTextResponse = await rekognitionClient.DetectTextAsync(detectTextReq); context.Logger.LogLine($"Response from Rekognition: {JsonConvert.SerializeObject(detectTextResponse)}"); // Check if the a valid number was detected... foreach (var textItem in detectTextResponse.TextDetections) { if (!result.numberPlate.detected && textItem.Type.Value == "LINE" && textItem.Confidence > float.Parse(Environment.GetEnvironmentVariable("RekognitionTextMinConfidence"))) { Regex regex = new Regex(regExNumberPlate); MatchCollection matches = regex.Matches(textItem.DetectedText); context.Logger.LogLine($"Matches collection: {matches.Count}"); string plateNumber = ""; foreach (Match match in matches) { plateNumber += (match.Groups[1].Value + match.Groups[2].Value); } if (!string.IsNullOrEmpty(plateNumber)) { result.numberPlate.detected = true; result.numberPlate.confidence = textItem.Confidence; result.numberPlate.numberPlateString = plateNumber; context.Logger.LogLine($"A valid plate number was detected ({result.numberPlate.numberPlateString})"); } } } recorder.EndSubsegment(); // // At this point, we either know it is a valid number plate // or it couldn't be determined with adequate confidence // so we need manual intervention // // // Kick off the step function // context.Logger.LogLine("Starting the state machine"); //TODO: add code to start the state machine context.Logger.LogLine("State machine started"); return(result); }