public void TestSubsegmentStreamingParentSubsegmentDoNotGetRemoved() { _recorder.BeginSegment(GetType().Name, TraceId); var segment = (Segment)TraceContext.GetEntity(); _recorder.BeginSubsegment("parent"); for (int i = 0; i < 98; i++) { _recorder.BeginSubsegment("job" + i); _recorder.EndSubsegment(); } _recorder.BeginSubsegment("last job"); var lastJob = (Subsegment)TraceContext.GetEntity(); // End parent subsegment, and trigger subsegment stream TraceContext.SetEntity(lastJob.Parent); _recorder.EndSubsegment(); Assert.AreEqual(2, segment.Size); Assert.AreEqual(1, segment.Subsegments.Count); Assert.AreEqual(1, segment.Subsegments[0].Subsegments.Count); TraceContext.ClearEntity(); }
public void TaskAsyncCreateThousandSubsegments() { _recorder.BeginSegment("parent", TraceId); Segment parent = (Segment)TraceContext.GetEntity(); Action action = () => { _recorder.BeginSubsegment("child"); _recorder.EndSubsegment(); }; var tasks = new Task[1000]; for (int i = 0; i < 1000; i++) { tasks[i] = Task.Run(action); } Task.WaitAll(tasks); _recorder.EndSegment(); Assert.IsTrue(parent.Subsegments.Count < 100); Assert.AreEqual(0, parent.Reference); Assert.AreEqual(parent.Size, parent.Subsegments.Count); }
public async Task TestSubsegmentOutLiveParent() { var mockEmitter = new Mock <ISegmentEmitter>(); using (var client = AWSXRayRecorderFactory.CreateAWSXRayRecorder(mockEmitter.Object)) { client.BeginSegment("parent", TraceId); var parent = TraceContext.GetEntity(); Subsegment child = null; Task task = Task.Run(async() => { client.BeginSubsegment("child"); child = (Subsegment)TraceContext.GetEntity(); await Task.Delay(1000); // Wait for parent to end first client.EndSubsegment(); }); await Task.Delay(50); // Wait to ensure subsegment has started client.EndSegment(); // Subsegment is not ended mockEmitter.Verify(x => x.Send(It.IsAny <Segment>()), Times.Never); Task.WaitAll(task); Assert.IsNotNull(child); // subsegment ends mockEmitter.Verify(x => x.Send(It.IsAny <Segment>()), Times.Once); } }
public void TestAsyncCreateTwoSubsegment() { _recorder.BeginSegment("parent", TraceId); Segment parent = (Segment)TraceContext.GetEntity(); Subsegment child1 = null; Subsegment child2 = null; Task task1 = Task.Run(async() => { _recorder.BeginSubsegment("child1"); await Task.Delay(1000); // Ensure task1 will not complete when task1 is running child1 = (Subsegment)TraceContext.GetEntity(); _recorder.EndSubsegment(); }); Task task2 = Task.Run(() => { _recorder.BeginSubsegment("child2"); child2 = (Subsegment)TraceContext.GetEntity(); _recorder.EndSubsegment(); }); Task.WaitAll(task1, task2); _recorder.EndSegment(); Assert.IsNotNull(child1); Assert.IsNotNull(child2); Assert.ReferenceEquals(parent, child1.Parent); Assert.ReferenceEquals(parent, child2.Parent); Assert.IsTrue(parent.Subsegments.Contains(child1)); Assert.IsTrue(parent.Subsegments.Contains(child2)); }
public async Task TestAsyncCreateSubsegmentInAChain() { _recorder.BeginSegment("parent", TraceId); var parent = TraceContext.GetEntity(); Subsegment subsegment1 = null; Subsegment subsegment2 = null; await Task.Run(async() => { _recorder.BeginSubsegment("subsegment1"); subsegment1 = (Subsegment)TraceContext.GetEntity(); await Task.Run(() => { _recorder.BeginSubsegment("subsegment2"); subsegment2 = (Subsegment)TraceContext.GetEntity(); _recorder.EndSubsegment(); }); _recorder.EndSubsegment(); }); _recorder.EndSegment(); Assert.ReferenceEquals(parent, subsegment1.Parent); Assert.IsTrue(parent.Subsegments.Contains(subsegment1)); Assert.ReferenceEquals(subsegment1, subsegment2.Parent); Assert.IsTrue(subsegment1.Subsegments.Contains(subsegment2)); }
/// <summary> /// Begin a tracing subsegment. A new segment will be created and added as a subsegment to previous segment. /// </summary> /// <param name="name">Name of the operation.</param> /// <exception cref="ArgumentNullException">The argument has a null value.</exception> /// <exception cref="EntityNotAvailableException">Entity is not available in trace context.</exception> public override void BeginSubsegment(string name) { try { if (IsTracingDisabled()) { _logger.DebugFormat("X-Ray tracing is disabled, do not start subsegment"); return; } // If the request is not sampled, a segment will still be available in TraceContext to // stores the information of the trace. The trace information will still propagated to // downstream service, in case downstream may overwrite the sample decision. Entity parentEntity = TraceContext.GetEntity(); // If the segment is not sampled, do nothing and exit. if (parentEntity.Sampled != SampleDecision.Sampled) { _logger.DebugFormat("Do not start subsegment because the segment doesn't get sampled. ({0})", name); return; } Subsegment subsegment = new Subsegment(name); parentEntity.AddSubsegment(subsegment); subsegment.Sampled = parentEntity.Sampled; subsegment.SetStartTimeToNow(); TraceContext.SetEntity(subsegment); } catch (EntityNotAvailableException e) { HandleEntityNotAvailableException(e, "Failed to start subsegment because the parent segment is not available."); } }
/// <summary> /// End a tracing segment. If all operations of the segments are finished, the segment will be emitted. /// </summary> /// <exception cref="EntityNotAvailableException">Entity is not available in trace context.</exception> public override void EndSegment() { try { // If the request is not sampled, a segment will still be available in TraceContext. // Need to clean up the segment, but do not emit it. Segment segment = (Segment)TraceContext.GetEntity(); if (!IsTracingDisabled()) { segment.SetEndTimeToNow(); //sets end time to current time ProcessEndSegment(segment); } TraceContext.ClearEntity(); } catch (EntityNotAvailableException e) { HandleEntityNotAvailableException(e, "Failed to end segment because cannot get the segment from trace context."); } catch (InvalidCastException e) { HandleEntityNotAvailableException(new EntityNotAvailableException("Failed to cast the entity to Segment.", e), "Failed to cast the entity to Segment."); } }
public void TestDynamoDbClient() { AWSSDKHandler.RegisterXRayForAllServices(_path); // IAmazonDynamoDb will be registered. All new instances of AmazonServiceClient will be automatically registered. using (var client = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1)) { string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; CustomResponses.SetResponse(client, null, requestId, true); _recorder.BeginSegment("test", TraceId); #if NET45 client.ListTables(); #else client.ListTablesAsync().Wait(); #endif var segment = TraceContext.GetEntity(); var subsegment = segment.Subsegments[0]; _recorder.EndSegment(); Assert.AreEqual(segment.Subsegments.Count, 1); Assert.AreEqual(subsegment.Name, "DynamoDBv2"); Assert.AreEqual(subsegment.Aws["region"], RegionEndpoint.USEast1.SystemName); Assert.AreEqual(subsegment.Aws["operation"], "ListTables"); Assert.AreEqual(requestId, subsegment.Aws["request_id"]); Assert.AreEqual("aws", subsegment.Namespace); } }
public void TestLambdaInvokeSubsegmentContainsFunctionNameForAWSSDKHandler() { String temp_path = @"JSONs\AWSRequestInfoWithLambda.json"; //registering manifest file with Lambda AWSSDKHandler.RegisterXRayManifest(temp_path); var lambda = new AmazonLambdaClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); CustomResponses.SetResponse(lambda, null, null, true); AWSXRayRecorder.Instance.BeginSegment("lambda", TraceId); #if NET45 lambda.Invoke(new InvokeRequest { FunctionName = "testFunction" }); #else lambda.InvokeAsync(new InvokeRequest { FunctionName = "testFunction" }).Wait(); #endif var segment = TraceContext.GetEntity(); AWSXRayRecorder.Instance.EndSegment(); Assert.AreEqual("Invoke", segment.Subsegments[0].Aws["operation"]); Assert.AreEqual("testFunction", segment.Subsegments[0].Aws["function_name"]); }
/// <summary> /// Process Synchronous <see cref="AmazonServiceClient"/> operations. A subsegment is started at the beginning of /// the request and ended at the end of the request. /// </summary> public override void InvokeSync(IExecutionContext executionContext) { ProcessBeginRequest(executionContext); try { base.InvokeSync(executionContext); } catch (Exception e) { var subsegment = TraceContext.GetEntity(); subsegment.AddException(e); // record exception if (e is AmazonServiceException amazonServiceException) { ProcessException(amazonServiceException, subsegment); } throw; } finally { ProcessEndRequest(executionContext); } }
public void TestExceptionHandler() { using (var client = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1)) { _handler.AddEventHandler(client); CustomResponses.SetResponse(client, (request) => { throw new InvalidOperationException(); }); _recorder.BeginSegment("test", TraceId); var segment = TraceContext.GetEntity(); try { client.GetItem( "test", new Dictionary <string, AttributeValue>() { { "invalid_key", new AttributeValue("1") } }); Assert.Fail(); } catch (InvalidOperationException e) { Assert.ReferenceEquals(e, segment.Subsegments[0].Cause.ExceptionDescriptors[0].Exception); Assert.IsTrue(segment.Subsegments[0].Aws.ContainsKey("table_name")); Assert.IsTrue(segment.Subsegments[0].Aws.ContainsKey("consistent_read")); Assert.IsTrue(segment.Subsegments[0].Aws.ContainsKey("projection_expression")); Assert.IsTrue(segment.Subsegments[0].Aws.ContainsKey("attribute_names_substituted")); } finally { _recorder.EndSegment(); } } }
public void TestReferenceExceptionFromOtherSubsegment() { using (var recorder = AWSXRayRecorder.Instance) { recorder.BeginSegment("parent", TraceId); var segment = TraceContext.GetEntity(); try { recorder.BeginSubsegment("child"); try { throw new ArgumentNullException("value"); } catch (ArgumentNullException e) { recorder.AddException(e); recorder.EndSubsegment(); throw e; } } catch (ArgumentNullException e) { recorder.AddException(e); recorder.EndSegment(); } Assert.AreEqual(segment.Cause.ReferenceExceptionId, segment.Subsegments[0].Cause.ExceptionDescriptors[0].Id); Assert.IsNull(segment.Cause.ExceptionDescriptors); } }
protected override WebRequest GetWebRequest(Uri address) { var request = base.GetWebRequest(address); if (request != null) { request.Timeout = this.Timeout; } if (AwsUtilityMethods.IsRunningOnAWS) { AWSXRayRecorder.Instance.BeginSubsegment(request.RequestUri.Host); AWSXRayRecorder.Instance.SetNamespace("remote"); Dictionary <string, object> requestInformation = new Dictionary <string, object>(); requestInformation["url"] = request.RequestUri.AbsoluteUri; requestInformation["method"] = request.Method; AWSXRayRecorder.Instance.AddHttpInformation("request", requestInformation); if (TraceHeader.TryParse(TraceContext.GetEntity(), out TraceHeader header)) { request.Headers.Add("X-Amzn-Trace-Id", header.ToString()); } } return(request); }
/// <summary> /// Process Asynchronous <see cref="AmazonServiceClient"/> operations. A subsegment is started at the beginning of /// the request and ended at the end of the request. /// </summary> public override async Task <T> InvokeAsync <T>(IExecutionContext executionContext) { ProcessBeginRequest(executionContext); T ret = null; try { ret = await base.InvokeAsync <T>(executionContext).ConfigureAwait(false); } catch (Exception e) { var subsegment = TraceContext.GetEntity(); subsegment.AddException(e); // record exception if (e is AmazonServiceException amazonServiceException) { ProcessException(amazonServiceException, subsegment); } throw; } finally { ProcessEndRequest(executionContext); } return(ret); }
public void TestSubsegmentStreaming() { _recorder.BeginSegment(GetType().Name, TraceId); var segment = (Segment)TraceContext.GetEntity(); _recorder.BeginSubsegment("first 50"); for (int i = 0; i < 50; i++) { _recorder.BeginSubsegment("job" + i); _recorder.EndSubsegment(); } _recorder.EndSubsegment(); _recorder.BeginSubsegment("second 50"); for (int i = 0; i < 50; i++) { _recorder.BeginSubsegment("job" + i); _recorder.EndSubsegment(); } _recorder.EndSubsegment(); _recorder.EndSegment(); Assert.AreEqual(3, segment.Size); }
public void TestExceptionGetResponseTraced() { var request = (HttpWebRequest)WebRequest.Create(URL404); AWSXRayRecorder.Instance.BeginSegment("parent", TraceId); try { request.GetResponseTraced(); Assert.Fail(); } catch (WebException) //expected { var segment = TraceContext.GetEntity(); AWSXRayRecorder.Instance.EndSegment(); Assert.IsNotNull(request.Headers[TraceHeader.HeaderKey]); var requestInfo = segment.Subsegments[0].Http["request"] as Dictionary <string, object>; Assert.AreEqual(URL404, requestInfo["url"]); Assert.AreEqual("GET", requestInfo["method"]); var responseInfo = segment.Subsegments[0].Http["response"] as Dictionary <string, object>; Assert.AreEqual(404, responseInfo["status"]); Assert.IsNotNull(responseInfo["content_length"]); var subsegment = segment.Subsegments[0]; Assert.IsTrue(subsegment.HasError); Assert.IsFalse(subsegment.HasFault); } }
public void TestMarkError() { _recorder.BeginSegment("test", TraceId); _recorder.MarkError(); var segment = TraceContext.GetEntity(); Assert.IsTrue(segment.HasError); _recorder.EndSegment(); }
public void TestSyncGet() { var segment = new Segment("test", TraceId); TraceContext.SetEntity(segment); var later = TraceContext.GetEntity(); Assert.ReferenceEquals(segment, later); }
public void TestSubsegment() { _recorder.BeginSubsegment("subsegment1"); Subsegment subsegment1 = (Subsegment)TraceContext.GetEntity(); FacadeSegment facadeSegment = (FacadeSegment)subsegment1.RootSegment; _recorder.EndSubsegment(); Assert.AreEqual(facadeSegment.GetType(), typeof(FacadeSegment)); Assert.IsFalse(facadeSegment.Subsegments.Contains(subsegment1)); //only subsegment is streamed Assert.IsFalse(TraceContext.IsEntityPresent()); // facade segment is cleared from TraceContext }
public void TestAddHttp() { _recorder.BeginSegment("test", TraceId); var segment = TraceContext.GetEntity(); _recorder.AddHttpInformation("key", "value"); Assert.AreEqual("value", segment.Http["key"]); _recorder.EndSegment(); }
public void TestLambdaVariablesNotSetCorrectly() { String invalidTraceHeader = "Root=" + TraceId + ";Parent=53995c3f42cd8ad8"; //sample decision is missing Environment.SetEnvironmentVariable(AWSXRayRecorder.LambdaTraceHeaderKey, invalidTraceHeader); _recorder.BeginSubsegment("subsegment1"); Subsegment subsegment = (Subsegment)TraceContext.GetEntity(); //subsegment added with sample decision set to not sampled Assert.AreEqual(SampleDecision.NotSampled, subsegment.Sampled); _recorder.EndSubsegment(); //subsegment not sampled since invalid TraceHeader value set in the lambda environment Assert.IsFalse(TraceContext.IsEntityPresent()); // Facade segment not present in the callcontext }
public void TestAddMetadata() { _recorder.BeginSegment("metadata", TraceId); _recorder.AddMetadata("key1", "value1"); _recorder.AddMetadata("aws", "key2", "value2"); var segment = TraceContext.GetEntity(); _recorder.EndSegment(); Assert.AreEqual("value1", segment.Metadata["default"]["key1"]); Assert.AreEqual("value2", segment.Metadata["aws"]["key2"]); }
public void TestServiceContext() { _recorder.BeginSegment("test", TraceId); var segment = (Segment)TraceContext.GetEntity(); _recorder.EndSegment(); #if NET45 Assert.AreEqual(".NET Framework", segment.Service["runtime"]); #else Assert.AreEqual(".NET Core Framework", segment.Service["runtime"]); #endif Assert.AreEqual(Environment.Version.ToString(), segment.Service["runtime_version"]); }
public async Task TestTraceMethodAsyncReturnVoid() { _recorder.BeginSegment("test", TraceId); int count = 0; await _recorder.TraceMethodAsync("PlusOneNoReturnAsync", () => PlusOneNoReturnAsync <int>(count)); var subsegment = TraceContext.GetEntity().Subsegments[0]; Assert.AreEqual("PlusOneNoReturnAsync", subsegment.Name); _recorder.EndSegment(); }
public void TestAdd() { _recorder.BeginSegment(GetType().Name, TraceId); _recorder.AddSqlInformation("key1", "value1"); _recorder.AddSqlInformation("key2", "value2"); var segment = TraceContext.GetEntity(); Assert.AreEqual(2, segment.Sql.Count); Assert.AreEqual("value1", segment.Sql["key1"]); Assert.AreEqual("value2", segment.Sql["key2"]); _recorder.EndSegment(); }
public void TestTraceMethodWithReturnValue() { _recorder.BeginSegment("test", TraceId); int count = _recorder.TraceMethod("PlusOneReturn", () => PlusOneReturn(0)); Assert.AreEqual(1, count); var subsegment = TraceContext.GetEntity().Subsegments[0]; Assert.AreEqual("PlusOneReturn", subsegment.Name); _recorder.EndSegment(); }
public async Task TestAsyncGet() { var origin = new Subsegment("test"); TraceContext.SetEntity(origin); Entity later = null; await Task.Run(() => { later = TraceContext.GetEntity(); }); Assert.ReferenceEquals(origin, later); }
public void TestXrayContext() { _recorder.BeginSegment("test", TraceId); var segment = TraceContext.GetEntity(); _recorder.EndSegment(); IDictionary <string, string> xray = (Dictionary <string, string>)segment.Aws["xray"]; var versionText = FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(AWSXRayRecorderBuilder)).Location) .ProductVersion; Assert.AreEqual(versionText, xray["sdk_version"]); Assert.AreEqual("X-Ray for .NET", xray["sdk"]); }
public void TestAddPrecursorIdOnSubsegment() { _recorder.BeginSegment(GetType().Name, TraceId); var segment = TraceContext.GetEntity(); _recorder.BeginSubsegment("child"); var newSegmentId = ThreadSafeRandom.GenerateHexNumber(16); _recorder.AddPrecursorId(newSegmentId); _recorder.EndSubsegment(); Assert.AreEqual(newSegmentId, segment.Subsegments[0].PrecursorIds.First()); _recorder.EndSegment(); }
public void TestNestedSubsegments() { _recorder.BeginSubsegment("subsegment1"); Subsegment child = (Subsegment)TraceContext.GetEntity(); FacadeSegment facadeSegment = (FacadeSegment)child.RootSegment; _recorder.BeginSubsegment("subsegment2"); Assert.AreEqual("subsegment2", TraceContext.GetEntity().Name); Assert.AreEqual(facadeSegment.TraceId, TraceContext.GetEntity().RootSegment.TraceId); //root segment of subsegment2 is facade segment _recorder.EndSubsegment(); _recorder.EndSubsegment(); Assert.AreEqual(facadeSegment.GetType(), typeof(FacadeSegment)); Assert.IsFalse(facadeSegment.Subsegments.Contains(child)); //only subsegments are streamed Assert.IsFalse(TraceContext.IsEntityPresent()); }