| 593 | } |
| 594 | |
| 595 | func queryTrace(client httpclient.TempoHTTPClient, info *util.TraceInfo, l *zap.Logger) (traceMetrics, error) { |
| 596 | tm := traceMetrics{ |
| 597 | requested: 1, |
| 598 | } |
| 599 | |
| 600 | hexID := info.HexID() |
| 601 | start := info.Timestamp().Add(-30 * time.Minute).Unix() |
| 602 | end := info.Timestamp().Add(30 * time.Minute).Unix() |
| 603 | |
| 604 | logger := l.With( |
| 605 | zap.Int64("seed", info.Timestamp().Unix()), |
| 606 | zap.String("hexID", hexID), |
| 607 | zap.Duration("ago", time.Since(info.Timestamp())), |
| 608 | ) |
| 609 | logger.Info("querying Tempo trace") |
| 610 | |
| 611 | // We want to define a time range to reduce the number of lookups |
| 612 | trace, err := client.QueryTraceWithRange(context.Background(), hexID, start, end) |
| 613 | if err != nil { |
| 614 | if errors.Is(err, util.ErrTraceNotFound) { |
| 615 | tm.notFoundByID++ |
| 616 | } else { |
| 617 | tm.requestFailed++ |
| 618 | } |
| 619 | logger.Error("error querying Tempo", zap.Error(err)) |
| 620 | return tm, err |
| 621 | } |
| 622 | |
| 623 | if len(trace.ResourceSpans) == 0 { |
| 624 | logger.Error("trace contains 0 batches") |
| 625 | tm.notFoundByID++ |
| 626 | return tm, nil |
| 627 | } |
| 628 | |
| 629 | if hasMissingSpans(trace) { |
| 630 | logger.Error("trace has missing spans") |
| 631 | tm.missingSpans++ |
| 632 | return tm, nil |
| 633 | } |
| 634 | |
| 635 | // Get the expected |
| 636 | expected, err := info.ConstructTraceFromEpoch() |
| 637 | if err != nil { |
| 638 | logger.Error("unable to construct trace from epoch", zap.Error(err)) |
| 639 | return tm, err |
| 640 | } |
| 641 | |
| 642 | match := equalTraces(expected, trace) |
| 643 | if !match { |
| 644 | tm.incorrectResult++ |
| 645 | if diff := deep.Equal(expected, trace); diff != nil { |
| 646 | for _, d := range diff { |
| 647 | logger.Error("incorrect result", |
| 648 | zap.String("expected -> response", d), |
| 649 | ) |
| 650 | } |
| 651 | } |
| 652 | return tm, nil |