in src/Library/TelemetryGenerator.cs [48:175]
public IEnumerable<ITelemetry> Generate(InstanceMsg instance)
{
#if DEBUG_INFO
var debugInfo = instance.ToString();
Diagnostics.LogInfo($"Received instance: {debugInfo}");
#endif
var sourceUid = instance.SpanTags["source.uid"].StringValue;
var sourceName = instance.SpanTags["source.name"].StringValue;
var sourceWorkloadName = instance.SpanTags["source.workload.name"].StringValue;
var sourceWorkloadNamespace = instance.SpanTags["source.workload.namespace"].StringValue;
var destinationUid = instance.SpanTags["destination.uid"].StringValue;
var destinationName = instance.SpanTags["destination.name"].StringValue;
var destinationWorkloadName = instance.SpanTags["destination.workload.name"].StringValue;
var destinationWorkloadNamespace = instance.SpanTags["destination.workload.namespace"].StringValue;
var contextReporterUid = instance.SpanTags["context.reporter.uid"].StringValue;
var contextReporterKind = instance.SpanTags["context.reporter.kind"].StringValue.ToLowerInvariant();
var contextProtocol = instance.SpanTags["context.protocol"].StringValue.ToLowerInvariant();
//var connectionEvent = instance.SpanTags["connection.event"].StringValue.ToLowerInvariant();
//!!! configure the adapter to receive less trace spans through configuration (rules, etc), not filter them here. That would save bandwidth and mixer CPU
var sourceAppInsightsMonitoringEnabled = instance.SpanTags["source.labels.appinsights.monitoring.enabled"].StringValue;
var destinationAppInsightsMonitoringEnabled = instance.SpanTags["destination.labels.appinsights.monitoring.enabled"].StringValue;
var isSourceIstioIngressGateway = instance.SpanTags["source.labels.istio.isingressgateway"].BoolValue;
var requestHeadersRequestId = instance.SpanTags["request.headers.request.id"].StringValue;
var requestHeadersSyntheticTestRunId = instance.SpanTags["request.headers.synthetictest.runid"].StringValue;
var requestHeadersSyntheticTestLocation = instance.SpanTags["request.headers.synthetictest.location"].StringValue;
var requestHeadersRequestContext = instance.SpanTags["request.headers.request.context"].StringValue;
var responseHeadersRequestContext = instance.SpanTags["response.headers.request.context"].StringValue;
string requestHeadersRequestContextAppId = string.Empty;
if (!string.IsNullOrWhiteSpace(requestHeadersRequestContext))
{
// Regex.Match is thread-safe
Match requestHeadersRequestContextAppIdMatch = requestContextAppIdRegex.Match(requestHeadersRequestContext);
Group group = requestHeadersRequestContextAppIdMatch.Groups["appId"];
if (requestHeadersRequestContextAppIdMatch.Success && group.Success && group.Captures.Count == 1)
{
requestHeadersRequestContextAppId = requestHeadersRequestContextAppIdMatch.Groups["appId"].Value;
}
}
string responseHeadersRequestContextAppId = string.Empty;
if (!string.IsNullOrWhiteSpace(responseHeadersRequestContext))
{
// Regex.Match is thread-safe
Match responseHeadersRequestContextAppIdMatch = requestContextAppIdRegex.Match(responseHeadersRequestContext);
Group group = responseHeadersRequestContextAppIdMatch.Groups["appId"];
if (responseHeadersRequestContextAppIdMatch.Success && group.Success && group.Captures.Count == 1)
{
responseHeadersRequestContextAppId = responseHeadersRequestContextAppIdMatch.Groups["appId"].Value;
}
}
var sourceRoleName = instance.SpanTags["source.role.name"].StringValue.ToLowerInvariant().Replace("kubernetes://", string.Empty);
var sourceRoleInstance = instance.SpanTags["source.role.instance"].StringValue.ToLowerInvariant().Replace("kubernetes://", string.Empty);
var destinationRoleName = instance.SpanTags["destination.role.name"].StringValue.ToLowerInvariant().Replace("kubernetes://", string.Empty);
var destinationRoleInstance= instance.SpanTags["destination.role.instance"].StringValue.ToLowerInvariant().Replace("kubernetes://", string.Empty);
var httpUserAgent = instance.SpanTags["http.useragent"].StringValue;
var host = instance.SpanTags["host"].StringValue;
var httpStatusCode = instance.SpanTags["http.status_code"].Int64Value;
var httpPath = instance.SpanTags["http.path"].StringValue;
var httpMethod = instance.SpanTags["http.method"].StringValue;
var requestScheme = instance.SpanTags["request.scheme"].StringValue;
var destinationPort = instance.SpanTags["destination.port"].Int64Value;
var destinatonServiceUid = instance.SpanTags["destination.service.uid"].StringValue;
var destinatonServiceHost = instance.SpanTags["destination.service.host"].StringValue;
var destinatonServiceName = instance.SpanTags["destination.service.name"].StringValue;
var destinatonServiceNamespace = instance.SpanTags["destination.service.namespace"].StringValue;
// if source/desination information is insufficient, let's assume it's an external caller/dependency and use whatever little we know about them
if (string.IsNullOrWhiteSpace(sourceRoleName) || string.Equals(sourceRoleName, UnknownValue, StringComparison.InvariantCultureIgnoreCase))
{
sourceRoleName = httpUserAgent;
}
if (string.IsNullOrWhiteSpace(sourceRoleInstance) || string.Equals(sourceRoleInstance, UnknownValue, StringComparison.InvariantCultureIgnoreCase))
{
sourceRoleInstance = httpUserAgent;
}
if (string.IsNullOrWhiteSpace(destinationRoleName) || string.Equals(destinationRoleName, UnknownValue, StringComparison.InvariantCultureIgnoreCase))
{
destinationRoleName = host;
}
if (string.IsNullOrWhiteSpace(destinationRoleInstance) || string.Equals(destinationRoleInstance, UnknownValue, StringComparison.InvariantCultureIgnoreCase))
{
destinationRoleInstance = host;
}
// if none of the workloads have anything to do with us, skip the instance completely
this.DetermineInterest(contextReporterUid, sourceWorkloadNamespace, destinationWorkloadNamespace, sourceAppInsightsMonitoringEnabled, destinationAppInsightsMonitoringEnabled,
out bool isInstanceInteresting, out bool isInstanceFullyWithinTargetArea, out bool isSourceWithinTargetArea, out bool isDestinationWithinTargetArea);
Diagnostics.LogTrace($"source: {sourceName}.{sourceWorkloadNamespace}, destination: {destinationName}.{destinationWorkloadNamespace}, reporter: {contextReporterUid}, kind: {contextReporterKind}");
//if (contextProtocol == "tcp")
//{
// Diagnostics.LogTrace(Invariant($"TCP. {debugInfo}"));
//}
if (!isInstanceInteresting || !contextProtocol.StartsWith("http") /*|| (contextProtocol == "tcp" && connectionEvent != "open")*/)
{
Diagnostics.LogTrace($"SKIPPED: isInstanceInteresting: {isInstanceInteresting}, contextProtocol: {contextProtocol}");
yield break;
}
// Request-Id header format https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/HierarchicalRequestId.md
bool incomingRequestIdPresent = !string.IsNullOrWhiteSpace(requestHeadersRequestId);
string incomingRequestId = incomingRequestIdPresent ? requestHeadersRequestId : Invariant($"|{RandomStringLong()}.");
string url = Invariant(
$@"{contextProtocol}{(string.IsNullOrWhiteSpace(contextProtocol) ? string.Empty : "://")}{destinationRoleInstance}{httpPath}{
(destinationPort > 0 ? $":{destinationPort}" : string.Empty)
}");