mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
* add text/markdown marshalling fmt Signed-off-by: Joe Elliott <[email protected]> * add LLM marshaler Signed-off-by: Joe Elliott <[email protected]> * less allocs Signed-off-by: Joe Elliott <[email protected]> * add header Signed-off-by: Joe Elliott <[email protected]> * remove unused func Signed-off-by: Joe Elliott <[email protected]> * comment Signed-off-by: Joe Elliott <[email protected]> * test Signed-off-by: Joe Elliott <[email protected]> * tests Signed-off-by: Joe Elliott <[email protected]> * remove unused func Signed-off-by: Joe Elliott <[email protected]> * changelog Signed-off-by: Joe Elliott <[email protected]> * lint and i bet i push again Signed-off-by: Joe Elliott <[email protected]> * errors.Is Signed-off-by: Joe Elliott <[email protected]> * simplify mcp e2e test Signed-off-by: Joe Elliott <[email protected]> * added structs and improved tests Signed-off-by: Joe Elliott <[email protected]> * fmt Signed-off-by: Joe Elliott <[email protected]> * review Signed-off-by: Joe Elliott <[email protected]> * fixed tests Signed-off-by: Joe Elliott <[email protected]> --------- Signed-off-by: Joe Elliott <[email protected]>
200 lines
5.8 KiB
Go
200 lines
5.8 KiB
Go
package combiner
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/grafana/tempo/pkg/tempopb"
|
|
commonv1 "github.com/grafana/tempo/pkg/tempopb/common/v1"
|
|
resourcev1 "github.com/grafana/tempo/pkg/tempopb/resource/v1"
|
|
tracev1 "github.com/grafana/tempo/pkg/tempopb/trace/v1"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestTraceByIDResponseToSimplifiedJSON(t *testing.T) {
|
|
// Create a comprehensive trace with various patterns
|
|
trace := &tempopb.Trace{
|
|
ResourceSpans: []*tracev1.ResourceSpans{
|
|
{
|
|
Resource: &resourcev1.Resource{
|
|
Attributes: []*commonv1.KeyValue{
|
|
{Key: "service.name", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_StringValue{StringValue: "test-service"}}},
|
|
{Key: "host.name", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_StringValue{StringValue: "localhost"}}},
|
|
},
|
|
},
|
|
ScopeSpans: []*tracev1.ScopeSpans{
|
|
{
|
|
Scope: &commonv1.InstrumentationScope{
|
|
Name: "test-scope",
|
|
Version: "1.0.0",
|
|
},
|
|
Spans: []*tracev1.Span{
|
|
{
|
|
TraceId: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10},
|
|
SpanId: []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18},
|
|
ParentSpanId: []byte{0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28},
|
|
Name: "test-span",
|
|
Kind: tracev1.Span_SPAN_KIND_SERVER,
|
|
StartTimeUnixNano: 1000000000,
|
|
EndTimeUnixNano: 2000000000,
|
|
Attributes: []*commonv1.KeyValue{
|
|
{Key: "http.method", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_StringValue{StringValue: "GET"}}},
|
|
{Key: "http.status_code", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_IntValue{IntValue: 200}}},
|
|
{Key: "error", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_BoolValue{BoolValue: false}}},
|
|
},
|
|
Events: []*tracev1.Span_Event{
|
|
{
|
|
Name: "test-event",
|
|
TimeUnixNano: 1500000000,
|
|
Attributes: []*commonv1.KeyValue{
|
|
{Key: "event.type", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_StringValue{StringValue: "log"}}},
|
|
},
|
|
},
|
|
},
|
|
Links: []*tracev1.Span_Link{
|
|
{
|
|
TraceId: []byte{0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0},
|
|
SpanId: []byte{0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8},
|
|
Attributes: []*commonv1.KeyValue{
|
|
{Key: "link.type", Value: &commonv1.AnyValue{Value: &commonv1.AnyValue_StringValue{StringValue: "parent"}}},
|
|
},
|
|
},
|
|
},
|
|
Status: &tracev1.Status{
|
|
Code: tracev1.Status_STATUS_CODE_OK,
|
|
Message: "success",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
traceResponse := &tempopb.TraceByIDResponse{
|
|
Trace: trace,
|
|
Metrics: &tempopb.TraceByIDMetrics{
|
|
InspectedBytes: 12345,
|
|
},
|
|
}
|
|
|
|
result, err := traceByIDResponseToSimplifiedJSON(traceResponse)
|
|
require.NoError(t, err)
|
|
|
|
// Parse the JSON
|
|
var actual LLMTraceByIDResponse
|
|
err = json.Unmarshal([]byte(result), &actual)
|
|
require.NoError(t, err)
|
|
|
|
// Build expected structure
|
|
expected := &LLMTraceByIDResponse{
|
|
Trace: LLMTrace{
|
|
TraceID: "0102030405060708090a0b0c0d0e0f10",
|
|
Services: []LLMService{
|
|
{
|
|
ServiceName: "test-service",
|
|
Resource: map[string]interface{}{
|
|
"host.name": "localhost",
|
|
},
|
|
Scopes: []LLMScope{
|
|
{
|
|
Name: "test-scope",
|
|
Version: "1.0.0",
|
|
Spans: []LLMSpan{
|
|
{
|
|
SpanID: "1112131415161718",
|
|
ParentSpanID: "2122232425262728",
|
|
Name: "test-span",
|
|
Kind: "SPAN_KIND_SERVER",
|
|
StartTimeUnixNano: "1000000000",
|
|
EndTimeUnixNano: "2000000000",
|
|
DurationMs: 1000.0,
|
|
Attributes: map[string]interface{}{
|
|
"http.method": "GET",
|
|
"http.status_code": float64(200),
|
|
"error": false,
|
|
},
|
|
Events: []LLMEvent{
|
|
{
|
|
Name: "test-event",
|
|
TimeUnixNano: "1500000000",
|
|
Attributes: map[string]interface{}{
|
|
"event.type": "log",
|
|
},
|
|
},
|
|
},
|
|
Links: []LLMLink{
|
|
{
|
|
TraceID: "a1a2a3a4a5a6a7a8a9aaabacadaeafb0",
|
|
SpanID: "b1b2b3b4b5b6b7b8",
|
|
Attributes: map[string]interface{}{
|
|
"link.type": "parent",
|
|
},
|
|
},
|
|
},
|
|
Status: LLMStatus{
|
|
Code: "STATUS_CODE_OK",
|
|
Message: "success",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Metrics: &LLMMetrics{
|
|
InspectedBytes: 12345,
|
|
},
|
|
}
|
|
|
|
assert.Equal(t, expected, &actual)
|
|
}
|
|
|
|
func TestSearchTagValuesV2ResponseToSimplifiedJSON(t *testing.T) {
|
|
response := &tempopb.SearchTagValuesV2Response{
|
|
TagValues: []*tempopb.TagValue{
|
|
{Type: "string", Value: "value1"},
|
|
{Type: "string", Value: "value2"},
|
|
{Type: "int", Value: "42"},
|
|
{Type: "int", Value: "100"},
|
|
{Type: "bool", Value: "true"},
|
|
},
|
|
Metrics: &tempopb.MetadataMetrics{
|
|
InspectedBytes: 5000,
|
|
TotalJobs: 10,
|
|
CompletedJobs: 10,
|
|
TotalBlocks: 5,
|
|
TotalBlockBytes: 10000,
|
|
},
|
|
}
|
|
|
|
result, err := searchTagValuesV2ResponseToSimplifiedJSON(response)
|
|
require.NoError(t, err)
|
|
|
|
// Parse the JSON
|
|
var actual LLMSearchTagValuesV2Response
|
|
err = json.Unmarshal([]byte(result), &actual)
|
|
require.NoError(t, err)
|
|
|
|
// Build expected structure
|
|
expected := &LLMSearchTagValuesV2Response{
|
|
TagValues: map[string][]string{
|
|
"string": {"value1", "value2"},
|
|
"int": {"42", "100"},
|
|
"bool": {"true"},
|
|
},
|
|
Metrics: &LLMMetrics{
|
|
InspectedBytes: 5000,
|
|
TotalJobs: 10,
|
|
CompletedJobs: 10,
|
|
TotalBlocks: 5,
|
|
TotalBlockBytes: 10000,
|
|
},
|
|
}
|
|
|
|
assert.Equal(t, expected, &actual)
|
|
}
|