/// <summary> /// Convert a Segment to an instance of <see cref="TraceHeader"/>. /// </summary> /// <param name="entity">A instance of <see cref="Entity"/> that will be used to convert to <see cref="TraceHeader"/>.</param> /// <param name="header">When the method returns, contains the <see cref="TraceHeader"/> object converted from <paramref name="entity"/>, /// if the conversion succeeded, or null if the conversion failed. The conversion fails if the <paramref name="entity"/> is null, or /// is not of the correct format. This parameter is passed uninitialized; any value originally supplied will be overwritten.</param> /// <returns>true if <paramref name="entity"/> converted successfully; otherwise, false.</returns> public static bool TryParse(Entity entity, out TraceHeader header) { header = null; if (entity == null) { _logger.DebugFormat("Failed to parse TraceHeader because segment is null."); return(false); } if (string.IsNullOrEmpty(entity.Id)) { _logger.DebugFormat("Failed to parse TraceHeader because segment id is null or empty."); return(false); } if (string.IsNullOrEmpty(entity.RootSegment.TraceId)) { _logger.DebugFormat("Failed to parse TraceHeader because trace id is null or empty."); return(false); } var newHeader = new TraceHeader(); // Trace id doesn't exist in subsegment, so get it from rootsegment newHeader.RootTraceId = entity.RootSegment.TraceId; newHeader.ParentId = entity.Id; newHeader.Sampled = entity.Sampled; header = newHeader; return(true); }
/// <summary> /// Convert the string representation of a trace header to an instance of <see cref="TraceHeader"/>. /// </summary> /// <param name="rawHeader">A string from HTTP request containing a trace header</param> /// <param name="traceHeader">When the method returns, contains the <see cref="TraceHeader"/> object converted from <paramref name="rawHeader"/>, /// if the conversion succeeded, or null if the conversion failed. The conversion fails if the <paramref name="rawHeader"/> is null or empty, /// is not of the correct format. This parameter is passed uninitialized; any value originally supplied will be overwritten. RootId, ParentId /// and Sampling decision are all required in valid form</param> /// <returns>true if <paramref name="rawHeader"/> converted successfully; otherwise, false.</returns> public static bool TryParseAll(string rawHeader, out TraceHeader traceHeader) { traceHeader = FromString(rawHeader); if (string.IsNullOrEmpty(rawHeader) || string.IsNullOrEmpty(traceHeader.RootTraceId) || string.IsNullOrEmpty(traceHeader.ParentId) || traceHeader.Sampled == SampleDecision.Unknown) { return(false); } return(true); }
/// <summary> /// Converts the string representation of a trace header to an instance of <see cref="TraceHeader"/>. /// </summary> /// <param name="rawHeader">A string from HTTP request containing a trace header.</param> /// <param name="header">When the method returns, contains the <see cref="TraceHeader"/> object converted from <paramref name="rawHeader"/>, /// It only extracts non-null and valid values.</param> /// <returns>true if <paramref name="rawHeader"/> converted successfully; otherwise, false.</returns> public static TraceHeader FromString(string rawHeader) { TraceHeader result = new TraceHeader(); try { if (string.IsNullOrEmpty(rawHeader)) { return(result); } Dictionary <string, string> keyValuePairs = rawHeader.Split(_validSeparators, StringSplitOptions.RemoveEmptyEntries) .Select(value => value.Trim().Split('=')) .ToDictionary(pair => pair[0], pair => pair[1]); string tmpValue; if (keyValuePairs.TryGetValue(RootKey, out tmpValue) && TraceId.IsIdValid(tmpValue)) { result.RootTraceId = tmpValue; } if (keyValuePairs.TryGetValue(ParentKey, out tmpValue) && Entity.IsIdValid(tmpValue)) { result.ParentId = tmpValue; } char tmpChar; if (keyValuePairs.TryGetValue(SampledKey, out tmpValue) && char.TryParse(tmpValue, out tmpChar)) { if (Enum.IsDefined(typeof(SampleDecision), (int)tmpChar)) { result.Sampled = (SampleDecision)tmpChar; } } return(result); } catch (IndexOutOfRangeException e) { _logger.Error(e, "Invalid trace header from string: {0}", rawHeader); return(result); } }
/// <summary> /// Convert the string representation of a trace header to an instance of <see cref="TraceHeader"/>. /// </summary> /// <param name="rawHeader">A string from HTTP request containing a trace header</param> /// <param name="header">When the method returns, contains the <see cref="TraceHeader"/> object converted from <paramref name="rawHeader"/>, /// if the conversion succeeded, or null if the conversion failed. The conversion fails if the <paramref name="rawHeader"/> is null or empty, /// is not of the correct format. This parameter is passed uninitialized; any value originally supplied will be overwritten.</param> /// <returns>true if <paramref name="rawHeader"/> converted successfully; otherwise, false. Root trace id /// required while parent id and sample decision is optional.</returns> public static bool TryParse(string rawHeader, out TraceHeader header) { header = null; try { if (string.IsNullOrEmpty(rawHeader)) { return(false); } var result = new TraceHeader(); Dictionary <string, string> keyValuePairs = rawHeader.Split(_validSeparators, StringSplitOptions.RemoveEmptyEntries) .Select(value => value.Trim().Split('=')) .ToDictionary(pair => pair[0], pair => pair[1]); string tmpValue; // Root trace id is required if (!keyValuePairs.TryGetValue(RootKey, out tmpValue)) { return(false); } if (!TraceId.IsIdValid(tmpValue)) { return(false); } result.RootTraceId = tmpValue; // Parent id is optional if (keyValuePairs.TryGetValue(ParentKey, out tmpValue)) { if (!Entity.IsIdValid(tmpValue)) { return(false); } result.ParentId = tmpValue; } // Sample decision is optional char tmpChar; if (keyValuePairs.TryGetValue(SampledKey, out tmpValue) && char.TryParse(tmpValue, out tmpChar)) { if (Enum.IsDefined(typeof(SampleDecision), (int)tmpChar)) { result.Sampled = (SampleDecision)tmpChar; } } header = result; return(true); } catch (IndexOutOfRangeException e) { _logger.Error(e, "Invalid trace header from string: {0}", rawHeader); return(false); } }