예제 #1
0
        /// <summary>
        /// Converts Activity Links to custom property with key as _MS.links.
        /// Value will be a JSON string formatted as [{"operation_Id":"{TraceId}","id":"{SpanId}"}].
        /// </summary>
        private static void AddActivityLinksToPartCTags(IEnumerable <ActivityLink> links, ref AzMonList PartCTags)
        {
            string msLinks = "_MS.links";
            // max number of links that can fit in this json formatted string is 107. it is based on assumption that traceid and spanid will be of fixed length.
            // Keeping max at 100 for now.
            int maxLinks = MaxlinksAllowed;

            if (links != null && links.Any())
            {
                var linksJson = new StringBuilder();
                linksJson.Append('[');
                foreach (var link in links)
                {
                    linksJson
                    .Append('{')
                    .Append("\"operation_Id\":")
                    .Append('\"')
                    .Append(link.Context.TraceId.ToHexString())
                    .Append('\"')
                    .Append(',');
                    linksJson
                    .Append("\"id\":")
                    .Append('\"')
                    .Append(link.Context.SpanId.ToHexString())
                    .Append('\"');
                    linksJson.Append("},");

                    maxLinks--;
                    if (maxLinks == 0)
                    {
                        if (MaxlinksAllowed < links.Count())
                        {
                            AzureMonitorExporterEventSource.Log.Write($"ActivityLinksIgnored{EventLevelSuffix.Informational}", $"Max count of {MaxlinksAllowed} has reached.");
                        }
                        break;
                    }
                }

                if (linksJson.Length > 0)
                {
                    // trim trailing comma - json does not support it
                    linksJson.Remove(linksJson.Length - 1, 1);
                }

                linksJson.Append(']');

                AzMonList.Add(ref PartCTags, new KeyValuePair <string, object>(msLinks, linksJson.ToString()));
            }
        }
예제 #2
0
        internal static RemoteDependencyData GetRemoteDependencyData(Activity activity, ref TagEnumerationState monitorTags)
        {
            AddActivityLinksToPartCTags(activity.Links, ref monitorTags.PartCTags);

            string httpUrl = null;
            string dependencyName;

            if (monitorTags.activityType == PartBType.Http)
            {
                httpUrl        = monitorTags.PartBTags.GetDependencyUrl();
                dependencyName = monitorTags.PartBTags.GetHttpDependencyName(httpUrl) ?? activity.DisplayName;
            }
            else
            {
                dependencyName = activity.DisplayName;
            }

            var dependency = new RemoteDependencyData(2, dependencyName, activity.Duration.ToString("c", CultureInfo.InvariantCulture))
            {
                Id      = activity.Context.SpanId.ToHexString(),
                Success = activity.GetStatus().StatusCode != StatusCode.Error
            };

            switch (monitorTags.activityType)
            {
            case PartBType.Http:
                dependency.Data       = httpUrl;
                dependency.Target     = monitorTags.PartBTags.GetDependencyTarget(PartBType.Http);
                dependency.Type       = "Http";
                dependency.ResultCode = AzMonList.GetTagValue(ref monitorTags.PartBTags, SemanticConventions.AttributeHttpStatusCode)?.ToString() ?? "0";
                break;

            case PartBType.Db:
                var depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeDbStatement, SemanticConventions.AttributeDbSystem);
                dependency.Data   = depDataAndType[0]?.ToString();
                dependency.Target = monitorTags.PartBTags.GetDbDependencyTarget();
                dependency.Type   = SqlDbs.Contains(depDataAndType[1]?.ToString()) ? "SQL" : depDataAndType[1]?.ToString();
                break;

            case PartBType.Rpc:
                var depInfo = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeRpcService, SemanticConventions.AttributeRpcSystem, SemanticConventions.AttributeRpcStatus);
                dependency.Data       = depInfo[0]?.ToString();
                dependency.Type       = depInfo[1]?.ToString();
                dependency.ResultCode = depInfo[2]?.ToString();
                break;

            case PartBType.Messaging:
                depDataAndType  = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeMessagingUrl, SemanticConventions.AttributeMessagingSystem);
                dependency.Data = depDataAndType[0]?.ToString();
                dependency.Type = depDataAndType[1]?.ToString();
                break;
            }

            if (activity.Kind == ActivityKind.Internal && activity.Parent != null)
            {
                dependency.Type = "InProc";
            }

            AddPropertiesToTelemetry(dependency.Properties, ref monitorTags.PartCTags);

            return(dependency);
        }
예제 #3
0
 private static void AddPropertiesToTelemetry(IDictionary <string, string> destination, ref AzMonList PartCTags)
 {
     // TODO: Iterate only interested fields. Ref: https://github.com/Azure/azure-sdk-for-net/pull/14254#discussion_r470907560
     for (int i = 0; i < PartCTags.Length; i++)
     {
         destination.Add(PartCTags[i].Key, PartCTags[i].Value?.ToString());
     }
 }