mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 04:29:04 +08:00
fix(trace-detail): trace details improvements (#6998)
* fix(trace-detail): query service and ux improvements * fix(trace-detail): added query service events * fix(trace-detail): address review comments
This commit is contained in:
parent
5783f1555f
commit
bbf64a7b52
@ -45,7 +45,7 @@ function EventsTable(props: IEventsTableProps): JSX.Element {
|
||||
)}
|
||||
{events
|
||||
.filter((eve) =>
|
||||
eve.name.toLowerCase().includes(fieldSearchInput.toLowerCase()),
|
||||
eve.name?.toLowerCase().includes(fieldSearchInput.toLowerCase()),
|
||||
)
|
||||
.map((event) => (
|
||||
<div
|
||||
@ -76,7 +76,7 @@ function EventsTable(props: IEventsTableProps): JSX.Element {
|
||||
<div className="timestamp-container">
|
||||
<Typography.Text className="attribute-value">
|
||||
{getYAxisFormattedValue(
|
||||
`${event.timeUnixNano / 1e6 - startTime}`,
|
||||
`${(event.timeUnixNano || 0) / 1e6 - startTime}`,
|
||||
'ms',
|
||||
)}
|
||||
</Typography.Text>
|
||||
|
@ -241,18 +241,19 @@
|
||||
height: 54px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-left: 15px;
|
||||
cursor: pointer;
|
||||
|
||||
.span-line {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
height: 12px;
|
||||
top: 35%;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.span-line-text {
|
||||
position: absolute;
|
||||
top: 65%;
|
||||
position: relative;
|
||||
top: 40%;
|
||||
font-variant-numeric: lining-nums tabular-nums stacked-fractions
|
||||
slashed-zero;
|
||||
font-feature-settings: 'case' on, 'cpsp' on, 'dlig' on, 'salt' on;
|
||||
|
@ -188,14 +188,13 @@ function SpanDuration({
|
||||
left: `${leftOffset}%`,
|
||||
width: `${width}%`,
|
||||
backgroundColor: color,
|
||||
marginLeft: '15px',
|
||||
}}
|
||||
/>
|
||||
<Tooltip title={`${toFixed(time, 2)} ${timeUnitName}`}>
|
||||
<Typography.Text
|
||||
className="span-line-text"
|
||||
ellipsis
|
||||
style={{ left: `${leftOffset}%`, color, marginLeft: '15px' }}
|
||||
style={{ left: `${leftOffset}%`, color }}
|
||||
>{`${toFixed(time, 2)} ${timeUnitName}`}</Typography.Text>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -1452,7 +1452,9 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
var traceRoots []*model.Span
|
||||
var serviceNameToTotalDurationMap = map[string]uint64{}
|
||||
var serviceNameIntervalMap = map[string][]tracedetail.Interval{}
|
||||
var hasMissingSpans bool
|
||||
|
||||
userEmail , emailErr := auth.GetEmailFromJwt(ctx)
|
||||
cachedTraceData, err := r.GetWaterfallSpansForTraceWithMetadataCache(ctx, traceID)
|
||||
if err == nil {
|
||||
startTime = cachedTraceData.StartTime
|
||||
@ -1463,6 +1465,11 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
traceRoots = cachedTraceData.TraceRoots
|
||||
totalSpans = cachedTraceData.TotalSpans
|
||||
totalErrorSpans = cachedTraceData.TotalErrorSpans
|
||||
hasMissingSpans = cachedTraceData.HasMissingSpans
|
||||
|
||||
if emailErr == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_TRACE_DETAIL_API, map[string]interface{}{"traceSize": totalSpans}, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -1477,6 +1484,10 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
}
|
||||
totalSpans = uint64(len(searchScanResponses))
|
||||
|
||||
if emailErr == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_TRACE_DETAIL_API, map[string]interface{}{"traceSize": totalSpans}, userEmail, true, false)
|
||||
}
|
||||
|
||||
processingBeforeCache := time.Now()
|
||||
for _, item := range searchScanResponses {
|
||||
ref := []model.OtelSpanRef{}
|
||||
@ -1514,7 +1525,23 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
Children: make([]*model.Span, 0),
|
||||
}
|
||||
|
||||
// convert start timestamp to millis
|
||||
// metadata calculation
|
||||
startTimeUnixNano := uint64(item.TimeUnixNano.UnixNano())
|
||||
if startTime == 0 || startTimeUnixNano < startTime {
|
||||
startTime = startTimeUnixNano
|
||||
}
|
||||
if endTime == 0 || (startTimeUnixNano + jsonItem.DurationNano ) > endTime {
|
||||
endTime = (startTimeUnixNano + jsonItem.DurationNano )
|
||||
}
|
||||
if durationNano == 0 || jsonItem.DurationNano > durationNano {
|
||||
durationNano = jsonItem.DurationNano
|
||||
}
|
||||
|
||||
if jsonItem.HasError {
|
||||
totalErrorSpans = totalErrorSpans + 1
|
||||
}
|
||||
|
||||
// convert start timestamp to millis because right now frontend is expecting it in millis
|
||||
jsonItem.TimeUnixNano = uint64(item.TimeUnixNano.UnixNano() / 1000000)
|
||||
|
||||
// collect the intervals for service for execution time calculation
|
||||
@ -1523,20 +1550,6 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
|
||||
// append to the span node map
|
||||
spanIdToSpanNodeMap[jsonItem.SpanID] = &jsonItem
|
||||
|
||||
// metadata calculation
|
||||
if startTime == 0 || jsonItem.TimeUnixNano < startTime {
|
||||
startTime = jsonItem.TimeUnixNano
|
||||
}
|
||||
if endTime == 0 || (jsonItem.TimeUnixNano+(jsonItem.DurationNano/1000000)) > endTime {
|
||||
endTime = jsonItem.TimeUnixNano + (jsonItem.DurationNano / 1000000)
|
||||
}
|
||||
if durationNano == 0 || jsonItem.DurationNano > durationNano {
|
||||
durationNano = jsonItem.DurationNano
|
||||
}
|
||||
if jsonItem.HasError {
|
||||
totalErrorSpans = totalErrorSpans + 1
|
||||
}
|
||||
}
|
||||
|
||||
// traverse through the map and append each node to the children array of the parent node
|
||||
@ -1568,6 +1581,7 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
missingSpan.Children = append(missingSpan.Children, spanNode)
|
||||
spanIdToSpanNodeMap[missingSpan.SpanID] = &missingSpan
|
||||
traceRoots = append(traceRoots, &missingSpan)
|
||||
hasMissingSpans = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1595,6 +1609,7 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
SpanIdToSpanNodeMap: spanIdToSpanNodeMap,
|
||||
ServiceNameToTotalDurationMap: serviceNameToTotalDurationMap,
|
||||
TraceRoots: traceRoots,
|
||||
HasMissingSpans: hasMissingSpans,
|
||||
}
|
||||
|
||||
zap.L().Info("getWaterfallSpansForTraceWithMetadata: processing pre cache", zap.Duration("duration", time.Since(processingBeforeCache)), zap.String("traceID", traceID))
|
||||
@ -1610,14 +1625,14 @@ func (r *ClickHouseReader) GetWaterfallSpansForTraceWithMetadata(ctx context.Con
|
||||
|
||||
response.Spans = selectedSpans
|
||||
response.UncollapsedSpans = uncollapsedSpans
|
||||
response.StartTimestampMillis = startTime
|
||||
response.EndTimestampMillis = endTime
|
||||
response.StartTimestampMillis = startTime / 1000000
|
||||
response.EndTimestampMillis = endTime / 1000000
|
||||
response.TotalSpansCount = totalSpans
|
||||
response.TotalErrorSpansCount = totalErrorSpans
|
||||
response.RootServiceName = rootServiceName
|
||||
response.RootServiceEntryPoint = rootServiceEntryPoint
|
||||
response.ServiceNameToTotalDurationMap = serviceNameToTotalDurationMap
|
||||
response.HasMissingSpans = len(traceRoots) > 1
|
||||
response.HasMissingSpans = hasMissingSpans
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@ -1692,19 +1707,20 @@ func (r *ClickHouseReader) GetFlamegraphSpansForTrace(ctx context.Context, trace
|
||||
Children: make([]*model.FlamegraphSpan, 0),
|
||||
}
|
||||
|
||||
jsonItem.TimeUnixNano = uint64(item.TimeUnixNano.UnixNano() / 1000000)
|
||||
spanIdToSpanNodeMap[jsonItem.SpanID] = &jsonItem
|
||||
|
||||
// metadata calculation
|
||||
if startTime == 0 || jsonItem.TimeUnixNano < startTime {
|
||||
startTime = jsonItem.TimeUnixNano
|
||||
startTimeUnixNano := uint64(item.TimeUnixNano.UnixNano())
|
||||
if startTime == 0 || startTimeUnixNano < startTime {
|
||||
startTime = startTimeUnixNano
|
||||
}
|
||||
if endTime == 0 || (jsonItem.TimeUnixNano+(jsonItem.DurationNano/1000000)) > endTime {
|
||||
endTime = jsonItem.TimeUnixNano + (jsonItem.DurationNano / 1000000)
|
||||
if endTime == 0 || ( startTimeUnixNano + jsonItem.DurationNano ) > endTime {
|
||||
endTime = (startTimeUnixNano + jsonItem.DurationNano )
|
||||
}
|
||||
if durationNano == 0 || jsonItem.DurationNano > durationNano {
|
||||
durationNano = jsonItem.DurationNano
|
||||
}
|
||||
|
||||
jsonItem.TimeUnixNano = uint64(item.TimeUnixNano.UnixNano() / 1000000)
|
||||
spanIdToSpanNodeMap[jsonItem.SpanID] = &jsonItem
|
||||
}
|
||||
|
||||
// traverse through the map and append each node to the children array of the parent node
|
||||
@ -1760,8 +1776,8 @@ func (r *ClickHouseReader) GetFlamegraphSpansForTrace(ctx context.Context, trace
|
||||
zap.L().Info("getFlamegraphSpansForTrace: processing post cache", zap.Duration("duration", time.Since(processingPostCache)), zap.String("traceID", traceID))
|
||||
|
||||
trace.Spans = selectedSpansForRequest
|
||||
trace.StartTimestampMillis = startTime
|
||||
trace.EndTimestampMillis = endTime
|
||||
trace.StartTimestampMillis = startTime / 1000000
|
||||
trace.EndTimestampMillis = endTime / 1000000
|
||||
return trace, nil
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ func getLatencyAndTimestampBucketedSpans(spans []*model.FlamegraphSpan, selected
|
||||
}
|
||||
|
||||
func GetSelectedSpansForFlamegraphForRequest(selectedSpanID string, selectedSpans [][]*model.FlamegraphSpan, startTime uint64, endTime uint64) [][]*model.FlamegraphSpan {
|
||||
var selectedSpansForRequest [][]*model.FlamegraphSpan
|
||||
var selectedSpansForRequest = make([][]*model.FlamegraphSpan, 0)
|
||||
var selectedIndex = 0
|
||||
|
||||
if selectedSpanID != "" {
|
||||
|
@ -158,7 +158,7 @@ func CalculateServiceTime(serviceIntervals map[string][]Interval) map[string]uin
|
||||
|
||||
func GetSelectedSpans(uncollapsedSpans []string, selectedSpanID string, traceRoots []*model.Span, spanIdToSpanNodeMap map[string]*model.Span, isSelectedSpanIDUnCollapsed bool) ([]*model.Span, []string, string, string) {
|
||||
|
||||
var preOrderTraversal = []*model.Span{}
|
||||
var preOrderTraversal = make([]*model.Span, 0)
|
||||
var rootServiceName, rootServiceEntryPoint string
|
||||
updatedUncollapsedSpans := uncollapsedSpans
|
||||
|
||||
|
@ -11,6 +11,7 @@ type GetWaterfallSpansForTraceWithMetadataCache struct {
|
||||
ServiceNameToTotalDurationMap map[string]uint64 `json:"serviceNameToTotalDurationMap"`
|
||||
SpanIdToSpanNodeMap map[string]*Span `json:"spanIdToSpanNodeMap"`
|
||||
TraceRoots []*Span `json:"traceRoots"`
|
||||
HasMissingSpans bool `json:"hasMissingSpans"`
|
||||
}
|
||||
|
||||
func (c *GetWaterfallSpansForTraceWithMetadataCache) MarshalBinary() (data []byte, err error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user