// GET: Home public ActionResult Index( string serviceName = null, string spanName = null, long?endTs = null, string annotationQuery = null, int?limit = null, int?minDuration = null) { ViewBag.serviceName = serviceName; ViewBag.endTs = (endTs ?? Util.CurrentTimeMilliseconds()).ToString(); ViewBag.annotationQuery = annotationQuery ?? string.Empty; ViewBag.limit = (limit ?? 10).ToString(); ViewBag.minDuration = minDuration.HasValue ? minDuration.Value.ToString() : string.Empty; ViewBag.Services = new List <object>(); ViewBag.Spans = new List <string>(); var spans = new List <string>(); var traces = new List <TraceSummary>(); if (!string.IsNullOrEmpty(serviceName)) { var client = new RestClient(Zipkin.UI.Web.Helpers.WebAppSettings.QueryHost); spans = client.Execute <List <string> >(new RestRequest(string.Format("/api/v1/spans?serviceName={0}", serviceName))).Data; var tracesReq = new RestRequest("/api/v1/traces"); foreach (var key in Request.QueryString.AllKeys) { tracesReq.AddParameter(key, Request.QueryString[key]); } var response = client.Execute <List <List <JsonSpan> > >(tracesReq); traces = response.Data .Select(t => TraceSummary.Create(t.Select(js => js.Invert()))) .Where(ts => ts != null).ToList(); } if (spans.Count != 0 && traces.Count != 0) { ViewBag.Spans = spans.Select(s => new Dictionary <string, string> { { "name", s }, { "selected", s == spanName ? "selected" : string.Empty } }).ToList(); ViewBag.queryResults = TraceSummaryToMustache(serviceName, traces); } return(View()); }
public ActionResult Index(string id) { var traceId = Util.HexToLong(id); var client = new RestClient(Zipkin.UI.Web.Helpers.WebAppSettings.QueryHost); var response = client.Execute <List <JsonSpan> >(new RestRequest(string.Format("/api/v1/trace/{0}", traceId))); if (response.StatusCode != System.Net.HttpStatusCode.OK || response.Data == null || response.Data.Count == 0) { return(HttpNotFound()); } var trace = response.Data.Select(js => js.Invert()).ToList(); var traceTimestamp = trace.First().timestamp ?? 0L; var traceDuration = Trace.Duration(trace) ?? 0L; var spanDepths = TraceSummary.ToSpanDepths(trace); var spanMap = WebUtil.GetIdToSpanMap(trace); var rootSpans = WebUtil.GetRootSpans(trace); var spans = new List <Dictionary <string, object> >(); foreach (var rootSpan in rootSpans) { foreach (var span in SpanNode.Create(rootSpan, trace).ToSpans()) { var spanStartTs = span.timestamp ?? traceTimestamp; int depth; if (!spanDepths.TryGetValue(span.id, out depth)) { depth = 1; } var width = span.duration.HasValue ? 100 * (double)span.duration.Value / (double)traceDuration : 0.0; var binaryAnnotations = new List <JsonBinaryAnnotation>(); span.binaryAnnotations.ToList().ForEach(ba => { if (Constants.CoreAddress.Contains(ba.key)) { if (ba.endpoint != null) { binaryAnnotations.Add(ToHostAndPort(Constants.CoreAnnotationNames[ba.key], ba.endpoint)); } } else { var jsonAnno = new JsonBinaryAnnotation(ba); if (Constants.CoreAnnotationNames.ContainsKey(ba.key)) { jsonAnno.key = Constants.CoreAnnotationNames[ba.key]; } binaryAnnotations.Add(jsonAnno); } }); span.binaryAnnotations.Where(ba => ba.key == Constants.LocalComponent).ToList().ForEach(ba => { if (ba.endpoint != null) { binaryAnnotations.Add(ToHostAndPort("Local Address", ba.endpoint)); } }); spans.Add(new Dictionary <string, object>() { { "spanId", Util.LongToHex(span.id) }, { "parentId", span.parentId.HasValue && spanMap.ContainsKey(span.parentId.Value) ? Util.LongToHex(span.parentId.Value) : string.Empty }, { "spanName", span.name }, { "serviceNames", string.Join(",", span.ServiceNames) }, { "serviceName", span.ServiceName }, { "duration", span.duration }, { "durationStr", WebUtil.FormatDurtion(span.duration ?? 0) }, { "left", ((float)(spanStartTs - traceTimestamp) / (float)traceDuration) * 100 }, { "width", width < 0.1 ? 0.1 : width }, { "depth", (depth + 1) * 5 }, { "depthClass", (depth - 1) % 6 }, { "children", string.Join(",", trace.Where(s => s.parentId == span.id).Select(s => Util.LongToHex(s.id)).ToArray()) }, { "annotations", span.annotations.Select(a => new Dictionary <string, object>() { { "isCore", Constants.CoreAnnotations.Contains(a.value) }, { "left", span.duration.HasValue ? 100 * (float)(a.timestamp - spanStartTs) / (float)span.duration.Value : 0 }, { "endpoint", a.endpoint == null ? string.Empty : string.Format("{0}:{1}", a.endpoint.GetHostAddress(), a.endpoint.GetUnsignedPort()) }, { "value", WebUtil.GetAnnotationName(a.value) }, { "timestamp", a.timestamp }, { "relativeTime", WebUtil.FormatDurtion(a.timestamp - traceTimestamp) }, { "serviceName", a.endpoint == null ? string.Empty : a.endpoint.serviceName }, { "width", 8 } }).ToList() }, { "binaryAnnotations", binaryAnnotations } }); } } var serviceDurations = new List <MustacheServiceDuration>(); var summary = TraceSummary.Create(trace); if (summary != null) { serviceDurations = summary.SpanTimestamps.GroupBy(sts => sts.Name).Select(g => new MustacheServiceDuration() { name = g.Key, count = g.Count(), max = g.Max(st => st.Duration / 1000) }).ToList(); } var i = 0; var timeMarkers = new double[] { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 } .Select(p => new Dictionary <string, string>() { { "index", (i++).ToString() }, { "time", WebUtil.FormatDurtion((long)(traceDuration * p)) } }).ToList(); var timeMarkersBackup = timeMarkers.Select(m => m).ToList(); var spansBackup = spans.Select(s => s).ToList(); ViewBag.duration = WebUtil.FormatDurtion(traceDuration); ViewBag.services = serviceDurations.Count; ViewBag.depth = spanDepths.Values.Max(); ViewBag.totalSpans = spans.Count; ViewBag.serviceCounts = serviceDurations.OrderBy(sd => sd.name); ViewBag.timeMarkers = timeMarkers; ViewBag.timeMarkersBackup = timeMarkersBackup; ViewBag.spans = spans; ViewBag.spansBackup = spansBackup; return(View()); }