public void RewriteTraceContext(SQSEvent.SQSMessage sqsMessage, ILambdaContext lambdaContext) { var traceHeader = TraceHeader.FromString(sqsMessage.Attributes["AWSTraceHeader"]); var lambdaSegmentParentId = traceHeader.ParentId; var lambdaSegmentId = Entity.GenerateId(); traceHeader.ParentId = lambdaSegmentId; Environment.SetEnvironmentVariable(AWSXRayRecorder.LambdaTraceHeaderKey, traceHeader.ToString()); _lambdaSegment = new Segment(lambdaContext.FunctionName, traceHeader.RootTraceId) { Id = lambdaSegmentId, ParentId = lambdaSegmentParentId, Sampled = traceHeader.Sampled, Origin = "AWS::Lambda::Function", Aws = { { "account_id", lambdaContext.InvokedFunctionArn.Split(":")[4] }, { "function_arn", lambdaContext.InvokedFunctionArn }, { "resource_names", new List <string> { lambdaContext.FunctionName } } } }; _lambdaSegment.SetStartTime(_startTime); }
public void TestTryParseNullString() { TraceHeader header; string nullString = null; Assert.IsFalse(TraceHeader.TryParse(nullString, out header)); }
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> /// Processes HTTP response. /// </summary> private static void ProcessHTTPResponse(Object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; var response = context.Response; if (!AWSXRayRecorder.Instance.IsTracingDisabled() && response != null) { Dictionary <string, object> responseAttributes = new Dictionary <string, object>(); ProcessResponseAttributes(response, responseAttributes); _recorder.AddHttpInformation("response", responseAttributes); } Exception exc = context.Error; // Record exception, if any if (exc != null) { _recorder.AddException(exc); } TraceHeader traceHeader = GetTraceHeader(context); bool isSampleDecisionRequested = traceHeader.Sampled == SampleDecision.Requested; if (traceHeader.Sampled == SampleDecision.Unknown || traceHeader.Sampled == SampleDecision.Requested) { SetSamplingDecision(traceHeader); // extracts sampling decision from the available segment } _recorder.EndSegment(); // if the sample decision is requested, add the trace header to response if (isSampleDecisionRequested) { response.Headers.Add(TraceHeader.HeaderKey, traceHeader.ToString()); } }
public static TraceHeader GetTraceHeader(this Message message) { return (message.Attributes.TryGetValue(Constants.TraceHeader, out var value) ? TraceHeader.FromString(value) : null); }
/// <summary> /// Processes HTTP request. /// </summary> private static void ProcessHTTPRequest(Object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; if (context.Items.Contains(XRayEntity)) { return; // Do not override segment for the current request } var request = context.Request; TraceHeader traceHeader = GetTraceHeader(context); // Make sample decision if (traceHeader.Sampled == SampleDecision.Unknown || traceHeader.Sampled == SampleDecision.Requested) { SetSamplingDecision(request, traceHeader); } var timestamp = context.Timestamp.ToUniversalTime().ToUnixTimeSeconds(); // Gets initial timestamp of current HTTP Request _recorder.BeginSegment(GetSegmentNamingStrategy().GetSegmentName(request), traceHeader.RootTraceId, timestamp, traceHeader.ParentId, traceHeader.Sampled); if (!AWSXRayRecorder.Instance.IsTracingDisabled()) { Dictionary <string, object> requestAttributes = new Dictionary <string, object>(); ProcessRequestAttributes(request, requestAttributes); _recorder.AddHttpInformation("request", requestAttributes); } context.Items.Add(XRayEntity, Core.Internal.Utils.TraceContext.GetEntity()); }
private static void ProcessRequest(Uri uri, string method, Action <string> addHeaderAction) { if (AWSXRayRecorder.Instance.IsTracingDisabled()) { _logger.DebugFormat("Tracing is disabled. Not starting a subsegment on HTTP request."); return; } var recorder = AWSXRayRecorder.Instance; recorder.BeginSubsegment(uri.Host); recorder.SetNamespace("remote"); var requestInformation = new Dictionary <string, object> { ["url"] = uri.AbsoluteUri, ["method"] = method }; recorder.AddHttpInformation("request", requestInformation); try { if (TraceHeader.TryParse(recorder.GetEntity(), out var header)) { addHeaderAction(header.ToString()); } } catch (EntityNotAvailableException e) { recorder.TraceContext.HandleEntityMissing(recorder, e, "Failed to get entity since it is not available in trace context while processing http request."); } }
private static void LogTimes(TraceHeader th) { Console.Write("{0}", th.OccurredAt); if (th.Duration == TimeSpan.Zero) { Console.Write(" | "); } else { if (th.Duration > threshold) { if (th.NextHeader != null && th.NextHeader.TraceEntry.IsUITriggered) { Console.Write("@>"); } else { Console.Write("=>"); } } else { Console.Write(" "); } Console.Write("{0:dd\\.hh\\:mm\\:ss\\.fff} ", th.Duration); } }
/// <summary> /// Processes HTTP request. /// </summary> private static void ProcessHTTPRequest(Object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; string ruleName = null; var request = context.Request; TraceHeader traceHeader = GetTraceHeader(context); var segmentName = GetSegmentNamingStrategy().GetSegmentName(request); // Make sample decision if (traceHeader.Sampled == SampleDecision.Unknown || traceHeader.Sampled == SampleDecision.Requested) { SamplingResponse response = MakeSamplingDecision(request, traceHeader, segmentName); ruleName = response.RuleName; } var timestamp = context.Timestamp.ToUniversalTime(); // Gets initial timestamp of current HTTP Request SamplingResponse samplingResponse = new SamplingResponse(ruleName, traceHeader.Sampled); // get final ruleName and SampleDecision _recorder.BeginSegment(segmentName, traceHeader.RootTraceId, traceHeader.ParentId, samplingResponse, timestamp); if (!AWSXRayRecorder.Instance.IsTracingDisabled()) { Dictionary <string, object> requestAttributes = new Dictionary <string, object>(); ProcessRequestAttributes(request, requestAttributes); _recorder.AddHttpInformation("request", requestAttributes); } }
/// <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."); } }
private static void SetSamplingDecision(HttpRequest request, TraceHeader traceHeader) { string serviceName = request.Headers.Get("Host"); string url = request.Url.AbsolutePath; string method = request.HttpMethod; traceHeader.Sampled = _recorder.SamplingStrategy.Sample(serviceName, url, method); }
public void TestTryParseSampleRequested() { string input = "Root=1-5759e988-bd862e3fe1be46a994272793; Sampled=?"; TraceHeader header; Assert.IsTrue(TraceHeader.TryParse(input, out header)); Assert.AreEqual(SampleDecision.Requested, header.Sampled); }
public void TestTrParseWithInvalidTraceId() { string input = "Root=1-5759e988"; TraceHeader header; Assert.IsFalse(TraceHeader.TryParse(input, out header)); Assert.IsNull(header); }
public void TestTryParseWithInvalidParentId() { string input = "Root=1-5759e988-bd862e3fe1be46a994272793; Parent=215748"; TraceHeader header; Assert.IsFalse(TraceHeader.TryParse(input, out header)); Assert.IsNull(header); }
/// <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 void TestTryParseInvalidString() { string[] invalidStrings = new string[] { "asdfhdk=fidksldfj", "asdfhdkfidksldfj", ";", ";=", string.Empty }; foreach (string s in invalidStrings) { TraceHeader header; Assert.IsFalse(TraceHeader.TryParse(s, out header)); } }
public void TestTryParseWithOnlyRootTraceId() { string input = "Root=1-5759e988-bd862e3fe1be46a994272793;"; TraceHeader header; Assert.IsTrue(TraceHeader.TryParse(input, out header)); Assert.AreEqual("1-5759e988-bd862e3fe1be46a994272793", header.RootTraceId); Assert.IsNull(header.ParentId); Assert.AreEqual(SampleDecision.Unknown, header.Sampled); }
private static void ProcessTraceHeader(TraceHeader traceHeader, MutableObject traceMutable) { MutableObject header = new MutableObject(); header.Add("Binary ID", (int)traceHeader.BinaryId); header.Add("Magic", (int)traceHeader.Magic); header.Add("Version", (int)traceHeader.Version); header.Add("Flags", (int)traceHeader.Flags); traceMutable.Add("Header", header); }
private static SamplingResponse MakeSamplingDecision(HttpRequest request, TraceHeader traceHeader, string name) { string host = request.Headers.Get("Host"); string url = request.Url.AbsolutePath; string method = request.HttpMethod; SamplingInput samplingInput = new SamplingInput(host, url, method, name, _recorder.Origin); SamplingResponse sampleResponse = _recorder.SamplingStrategy.ShouldTrace(samplingInput); traceHeader.Sampled = sampleResponse.SampleDecision; return(sampleResponse); }
public void TestTryParseWithRootParentSampled() { string input = "Root=1-5759e988-bd862e3fe1be46a994272793; Parent=defdfd9912dc5a56; Sampled=1"; TraceHeader header; Assert.IsTrue(TraceHeader.TryParse(input, out header)); Assert.AreEqual("1-5759e988-bd862e3fe1be46a994272793", header.RootTraceId); Assert.AreEqual("defdfd9912dc5a56", header.ParentId); Assert.AreEqual(SampleDecision.Sampled, header.Sampled); }
public void TestToStringUnknown() { var header = new TraceHeader(); header.RootTraceId = "1-5759e988-bd862e3fe1be46a994272793"; header.ParentId = "defdfd9912dc5a56"; header.Sampled = SampleDecision.Unknown; var expected = "Root=1-5759e988-bd862e3fe1be46a994272793; Parent=defdfd9912dc5a56"; Assert.AreEqual(expected, header.ToString()); }
public async Task <TraceHeader> SaveTraceHeaderAsync(TraceHeader header) { using (IDbConnection connection = new NpgsqlConnection(GetConnectionString())) { var sql = @"INSERT INTO traceheader(filedataid, tracename, blocksize, tracedate, vunit, hresolution, hoffset, hunit) VALUES(@FileDataId, @TraceName, @BlockSize, @TraceDate, @VUnit, @HResolution, @HOffSet, @HUnit) RETURNING traceheaderid;"; header.TraceHeaderId = await connection.ExecuteScalarAsync <int>(sql, header); return(header); } }
private static void SetSamplingDecision(TraceHeader traceHeader) { try { Segment segment = (Segment)AWSXRayRecorder.Instance.GetEntity(); traceHeader.Sampled = segment.Sampled; } catch (InvalidCastException e) { _logger.Error(new EntityNotAvailableException("Failed to cast the entity to Segment.", e), "Failed to get the segment from trace context for setting sampling decision in the response."); } }
/// <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 static void SetSamplingDecision(TraceHeader traceHeader) { try { Segment segment = (Segment)AWSXRayRecorder.Instance.GetEntity(); traceHeader.Sampled = segment.Sampled; } catch (InvalidCastException e) { _logger.Error(new EntityNotAvailableException("Failed to cast the entity to Segment.", e), "Failed to get the segment from trace context for setting sampling decision in the response."); } catch (EntityNotAvailableException e) { AWSXRayRecorder.Instance.TraceContext.HandleEntityMissing(AWSXRayRecorder.Instance, e, "Failed to get entity since it is not available in trace context while processing ASPNET request."); } }
private static void ProcessRequest(WebRequest request) { if (!AWSXRayRecorder.Instance.IsTracingDisabled()) { 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(TraceHeader.HeaderKey, header.ToString()); } }
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())); } }
static void Main(string[] args) { var random = new Random(); // make sure Zipkin with Scribe client is working //var collector = new HttpCollector(new Uri("http://localhost:9411/")); var collector = new KafkaCollector(KafkaSettings.Default); var traceId = new TraceHeader(traceId: (ulong)random.Next(), spanId: (ulong)random.Next()); var span = new Span(traceId, new IPEndPoint(IPAddress.Loopback, 9000), "test-service"); span.Record(Annotations.ClientSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerReceive(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ClientReceive(DateTime.UtcNow)); collector.CollectAsync(span).Wait(); }
/// <summary> /// Returns instance of <see cref="TraceHeader"/> class from given <see cref="HttpContext"/> object. /// </summary> private static TraceHeader GetTraceHeader(HttpContext context) { var request = context.Request; string headerString = request.Headers.Get(TraceHeader.HeaderKey); // 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 }; } return(traceHeader); }
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(); } }