Skip to content

Commit

Permalink
feat: trace detail add trace filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Qinyouzeng committed Oct 21, 2024
1 parent 7460b70 commit 3e9c97c
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 100 deletions.
2 changes: 0 additions & 2 deletions src/Services/Masa.Tsc.Service.Admin/Services/ApmService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the Apache License. See LICENSE.txt in the project root for license information.

using Masa.BuildingBlocks.StackSdks.Pm.Enum;

namespace Masa.Tsc.Service.Admin.Services;

public class ApmService : ServiceBase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ private void SetQueryList()
private void TeamChanged(Guid teamId)
{
GlobalConfig.CurrentTeamId = teamId;
if (Isloaded && CheckUrl())
{
NavigationManager.NavigateTo(NavigationManager.Uri, true);
return;
}
_ = InvokeAsync(async () =>
{
await LoadEnvironmentAsync();
Expand All @@ -191,6 +196,18 @@ private void TeamChanged(Guid teamId)
});
}

private bool CheckUrl()
{
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
var values = HttpUtility.ParseQueryString(uri.Query);
if (values.Count > 0)
{
return true;
}
else
return false;
}

private async Task ServiceTypeChanged(string value)
{
Search.ServiceType = value;
Expand Down
10 changes: 10 additions & 0 deletions src/Web/Masa.Tsc.Web.Admin.Rcl/Data/Apm/TreeLineDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ public string Label

public bool Faild { get; set; } = false;

public string? ServiceName
{
get
{
if (Trace == null || Trace.Resource == null || !Trace.Resource.ContainsKey("service.name"))
return default;
return Trace.Resource["service.name"].ToString();
}
}

public bool IsError
{
get
Expand Down
53 changes: 7 additions & 46 deletions src/Web/Masa.Tsc.Web.Admin.Rcl/Pages/Apm/Endpoints/TimeLine.razor
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
<div class="d-flex justify-start flex-wrap">
@foreach (var service in services)
{
<div class="pl-2"> <SIcon Small Color="@colors[services.IndexOf(service)]">mdi-circle</SIcon> @service</div>
<div class="pl-2">
<div class="pa-1 rounded-xl" style="cursor: pointer;@(GetServiceStyle(service))" @onclick="@(()=>OnServiceSelected(service))"><SIcon Small Color="@colors[services.IndexOf(service)]">mdi-circle</SIcon> @service</div>
</div>
}
</div>
</div>
Expand Down Expand Up @@ -83,6 +85,8 @@
style = $"padding-right:{timeLine.Right}%";
}

if (selectedServices.Contains(timeLine.ServiceName!))
{
<div class="time_line d-flex justify-space-between">
<div class="left_col d-flex justify-space-start" style="margin-left:@(level*8)px;border-left:solid 1px #ccc">
@if (timeLine.Children != null && timeLine.Children.Any())
Expand All @@ -93,7 +97,7 @@
<div style="width:calc(100% - 100px)">
<div class="d-flex mt-2">
<div class="left" style="width:@timeLine.Left%"></div>
<div @onclick="(()=>ShowTraceDetail(timeLine))" class="process" title="@timeLine.Label" style="width:@timeLine.Process%;background-color:@colors[services.IndexOf(timeLine.Trace.Resource["service.name"].ToString())]"></div>
<div @onclick="(()=>ShowTraceDetail(timeLine))" class="process" title="@timeLine.Label" style="width:@timeLine.Process%;background-color:@colors[services.IndexOf(timeLine.ServiceName)]"></div>
<div class="right" style="width:@timeLine.Right%"></div>
</div>
<div class="@className" style="@style">
Expand All @@ -114,7 +118,7 @@
</div>
<div class="right_col"></div>
</div>

}
@if (level == 0 && !showTimeLine)
{
if (!hasShow)
Expand All @@ -128,47 +132,4 @@
}
}
}

public void RenderChildTimeLines(RenderTreeBuilder __builder, List<TreeLineDto>? timeLines)
{
if (timeLines == null || !timeLines.Any())
return;

<div class="time_line d-flex justify-space-between">
@{
foreach (var timeLine in timeLines)
{
<div class="left" style="width:@timeLine.Left.ToString("#.00")%">
</div>
<div class="content" style="width:@timeLine.Process.ToString("#.00")%">
<div class="process" title="@timeLine.Name"></div>
<div class="name text-truncate" title="@timeLine.Name">@timeLine.Name</div>
@((RenderFragment)(dictRender => RenderChildTimeLine(dictRender, timeLine.Children)))
</div>
}
}
<div class="right" style="width:@timeLines[timeLines.Count-1].Right.ToString("#.00")%"></div>
</div>
}

public void RenderChildTimeLine(RenderTreeBuilder __builder, List<TreeLineDto>? timeLines)
{
if (timeLines == null || !timeLines.Any())
return;

<div class="time_line d-flex justify-space-between">
@{
foreach (var timeLine in timeLines)
{
<div class="left" style="width:@timeLine.Left.ToString("#.00")%"></div>
<div class="content" style="width:@timeLine.Process.ToString("#.00")%">
<div class="process" title="@timeLine.Name"></div>
<div class="name text-truncate" title="@timeLine.Name">@timeLine.Name</div>
@((RenderFragment)(dictRender => RenderChildTimeLine(dictRender, timeLine.Children)))
</div>
}
}
<div class="right" style="width:@timeLines[timeLines.Count-1].Right.ToString("#.00")%"></div>
</div>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public partial class TimeLine
TreeLineDto? currentTimeLine = null;
TreeLineDto defaultTimeLine = null;
List<string> services = new();
List<string> selectedServices = new();
string? traceLinkUrl = default, spanLinkUrl = default;
private string urlService, UrlEndpoint, urlMethod;

Expand Down Expand Up @@ -103,6 +104,7 @@ private async Task CaculateTimelines(List<TraceResponseDto>? traces)
spanLinkUrl = default;
timeLines.Clear();
services.Clear();
selectedServices.Clear();
if (traces == null || !traces.Any())
return;

Expand Down Expand Up @@ -140,6 +142,7 @@ private async Task CaculateTimelines(List<TraceResponseDto>? traces)
await OnSpanIdChanged.InvokeAsync(defaultTimeLine?.Trace?.SpanId);
timeLines = timeLines.OrderBy(item => item.Trace.Timestamp).ToList();
services = services.Distinct().ToList();
selectedServices.Add(urlService);
traceLinkUrl = GetUrl(defaultTimeLine);
}

Expand All @@ -156,30 +159,42 @@ private async Task CaculateTimelines(List<TraceResponseDto>? traces)
return default;
foreach (var item in data)
{
if (item.Trace.Resource["service.name"].ToString() == urlService
&& item.Trace.Kind == "SPAN_KIND_SERVER"
&& item.Trace.Resource.TryGetValue("telemetry.sdk.version", out var sdkVersion))
{
if (string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_5_1_Lonsid) || string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_5_1))
{
if ((string.IsNullOrEmpty(urlMethod) || item.Trace.Attributes.TryGetValue("http.target", out var target) && string.Equals(UrlEndpoint, target.ToString()!, StringComparison.CurrentCultureIgnoreCase))
&& item.Trace.Attributes.TryGetValue("http.method", out var method) && string.Equals(urlMethod, method.ToString()!, StringComparison.CurrentCultureIgnoreCase))
return item;
}
else if (string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_9_0))
{
if ((string.IsNullOrEmpty(urlMethod) || item.Trace.Attributes.TryGetValue("http.request.method", out var method) && string.Equals(urlMethod, method.ToString()!, StringComparison.CurrentCultureIgnoreCase))
&& (item.Trace.Attributes.TryGetValue("http.route", out var target) && string.Equals(UrlEndpoint, target.ToString()!, StringComparison.CurrentCultureIgnoreCase)
|| item.Trace.Attributes.TryGetValue("url.path", out target) && string.Equals(UrlEndpoint, target.ToString()!, StringComparison.CurrentCultureIgnoreCase)))
return item;
}
}
if (IsTarget(item))
return item;
var find = GetDefaultLine(item.Children);
if (find != null) return find;
}
return default;
}

private bool IsTarget(TreeLineDto item)
{
if (item.ServiceName == urlService
&& item.Trace.Kind == "SPAN_KIND_SERVER"
&& item.Trace.Resource.TryGetValue("telemetry.sdk.version", out var sdkVersion))
{
if (string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_5_1_Lonsid) || string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_5_1))
{
return IsNullOrEquals(item.Trace.Attributes, "http.method", urlMethod)
&& IsNullOrEquals(item.Trace.Attributes, "http.target", UrlEndpoint);

}

if (string.Equals(sdkVersion.ToString(), OpenTelemetrySdks.OpenTelemetrySdk1_9_0))
{
return IsNullOrEquals(item.Trace.Attributes, "http.request.method", urlMethod)
&& (IsNullOrEquals(item.Trace.Attributes, "http.route", UrlEndpoint) || IsNullOrEquals(item.Trace.Attributes, "url.path", UrlEndpoint));
}
}
return false;
}

private static bool IsNullOrEquals(Dictionary<string, object> values, string key, string? urlValue = default)
{
if (string.IsNullOrEmpty(urlValue)) return true;
return values.TryGetValue(key, out var value) && string.Equals(urlValue, value.ToString(), StringComparison.CurrentCultureIgnoreCase);
}

private TreeLineDto GetMauiDefaultLines(List<TreeLineDto>? data)
{
if (!IsMaui || data == null || !data.Any() || string.IsNullOrEmpty(RoutePath))
Expand Down Expand Up @@ -314,7 +329,7 @@ private string GetUrl(TreeLineDto current, bool isSpan = false, string baseUrl =
if (current == null)
return string.Empty;
string spanId = current.Trace.SpanId;
return $"{baseUrl}{GetUrlParam(service: current.Trace.Resource["service.name"].ToString(), env: current.Trace.Resource["service.namespace"].ToString(), start: start.AddSeconds(-1), end: end.AddSeconds(1), traceId: current.Trace.TraceId, spanId: isSpan ? spanId : default)}";
return $"{baseUrl}{GetUrlParam(service: current.ServiceName, env: current.Trace.Resource["service.namespace"].ToString(), start: start.AddSeconds(-1), end: end.AddSeconds(1), traceId: current.Trace.TraceId, spanId: isSpan ? spanId : default)}";
}

private async Task OpenLogAsync(TreeLineDto item)
Expand All @@ -327,4 +342,22 @@ private async Task OpenTraceLogAsync()
{
await JSRuntime.InvokeVoidAsync("open", traceLinkUrl, "_blank");
}

private string GetServiceStyle(string service)
{
return selectedServices.Contains(service) ? "background-color: rgb(211, 218, 230)" : "";
}

private void OnServiceSelected(string service)
{
if (service == urlService)
return;

if (selectedServices.Contains(service))
selectedServices.Remove(service);
else
selectedServices.Add(service);

StateHasChanged();
}
}
8 changes: 3 additions & 5 deletions src/Web/Masa.Tsc.Web.Admin.Rcl/Pages/Apm/Service.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public partial class Service
public async Task OnTableOptionsChanged(DataOptions sort)
{
if (sort.SortBy.Any())
sortFiled = sort.SortBy.First();
sortFiled = sort.SortBy[0];
else
sortFiled = default;
if (sort.SortDesc.Any())
sortBy = sort.SortDesc.First();
sortBy = sort.SortDesc[0];
else
sortBy = default;
await LoadASync();
Expand Down Expand Up @@ -81,7 +81,6 @@ private async Task LoadPageDataAsync()
TextValue = Search.TextValue,
IsDesc = sortBy,
ComparisonType = Search.ComparisonType.ToComparisonType(),
//Queries = Search.Text
};
var result = await ApiCaller.ApmService.GetServicePageAsync(GlobalConfig.CurrentTeamId, query, Search.Project, Search.ServiceType);
data.Clear();
Expand All @@ -98,7 +97,6 @@ private async Task LoadPageDataAsync()
}));
total = (int)result.Total;
}

}

private async Task LoadChartDataAsync()
Expand All @@ -124,7 +122,7 @@ private async Task LoadChartDataAsync()

foreach (var service in data)
{
var chartData = result.FirstOrDefault(s => s.Name == service.Name);
var chartData = result.Find(s => s.Name == service.Name);
service.LatencyChartData = new();
service.ThroughputChartData = new();
service.FailedChartData = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@

<div class="mx-4">
@* <div class="d-flex py-4">
<div class="col-6 rounded-lg pa-0" style="border:solid #ccc 1px">
<MCard>
<MCardSubtitle Class="font-weight-black h6 py-2">
Span Count
</MCardSubtitle>
<MCardText Class="py-0">
<MECharts Option="@(new())" Height="200" Style="@("width:100%")" />
</MCardText>
</MCard>
</div>
<div class="col-6 pa-0">
<div style="border:solid #ccc 1px;height:284px" class="rounded-lg ma-0 ml-4">
<MCard>
<MCardSubtitle Class="font-weight-black h6 py-2">
Time spent spans
</MCardSubtitle>
<MCardText Class="py-0">
<MECharts Option="@(new())" Height="200" Style="@("width:100%")" />
</MCardText>
</MCard>
</div>
</div>
<div class="col-6 rounded-lg pa-0" style="border:solid #ccc 1px">
<MCard>
<MCardSubtitle Class="font-weight-black h6 py-2">
Span Count
</MCardSubtitle>
<MCardText Class="py-0">
<MECharts Option="@(new())" Height="200" Style="@("width:100%")" />
</MCardText>
</MCard>
</div>
<div class="col-6 pa-0">
<div style="border:solid #ccc 1px;height:284px" class="rounded-lg ma-0 ml-4">
<MCard>
<MCardSubtitle Class="font-weight-black h6 py-2">
Time spent spans
</MCardSubtitle>
<MCardText Class="py-0">
<MECharts Option="@(new())" Height="200" Style="@("width:100%")" />
</MCardText>
</MCard>
</div>
</div>
</div> *@

<div class="col-12 rounded-lg" style="border:solid #ccc 1px">
Expand All @@ -35,24 +35,24 @@
FixedHeader
ServerItemsLength="total"
ItemsPerPage="defaultSize"
Items="data"
Items="data"
TItem="ListChartData"
Loading="@isTableLoading"
Loading="@isTableLoading"
OnOptionsUpdate="OnTableOptionsChanged">
<ItemColContent>
@if (context.Header.Value == nameof(ListChartData.Name))
{
<MTooltip Top Context="tooltipContent">
<ActivatorContent>
<div @attributes="@tooltipContent.Attrs" style="width:400px;overflow:hidden" class="text-truncate">
<a href="/apm/endpoints/@(HttpUtility.UrlEncode(context.Item.Name)+GetUrlParam(service: context.Item.Service, env: GetSearchEnv(Search.Environment, context.Item.Envs?.Split(',')),endpoint:context.Item.Endpoint, comparisonType: Search.ComparisonType, start: Search.Start, end: Search.End))"
<a href="/apm/endpoints/@(HttpUtility.UrlEncode(context.Item.Name)+GetUrlParam(service: context.Item.Service, env: GetSearchEnv(Search.Environment, context.Item.Envs?.Split(',')),endpoint:context.Item.Endpoint,method:context.Item.Method, comparisonType: Search.ComparisonType, start: Search.Start, end: Search.End))"
title="@context.Item.Name">@context.Item.Name</a>
</div>
</ActivatorContent>
<ChildContent>
<span>@context.Item.Name</span>
</ChildContent>
</MTooltip>
</MTooltip>
}
else if (context.Header.Value == nameof(ListChartData.Latency))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private async Task OnTableOptionsChanged(DataOptions sort)
sortBy = sort.SortDesc[0];
else
sortBy = default;
await LoadASync(Search);
await LoadASync(Search);
}

private ChartData GetLatencyChartData(ListChartData item)
Expand Down Expand Up @@ -117,7 +117,8 @@ private async Task LoadPageDataAsync()
Endpoint = item.Endpoint,
Failed = item.Failed,
Throughput = item.Throughput,
Latency = item.Latency
Latency = item.Latency,
Method = item.Method
}));
total = (int)result.Total;
}
Expand Down

0 comments on commit 3e9c97c

Please sign in to comment.