From 017e400b329d3045b451dfd98484e818b727b1a2 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Wed, 27 Dec 2023 22:34:04 -0600 Subject: [PATCH 1/8] add links --- pkg/tracegen/parameterized.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/tracegen/parameterized.go b/pkg/tracegen/parameterized.go index 7d0d5d6..c5c4803 100644 --- a/pkg/tracegen/parameterized.go +++ b/pkg/tracegen/parameterized.go @@ -114,7 +114,12 @@ func (g *ParameterizedGenerator) generateSpan(t *TraceParams, dest ptrace.Span) event := span.Events().AppendEmpty() event.SetName(random.K6String(12)) event.SetTimestamp(pcommon.NewTimestampFromTime(startTime)) - event.Attributes().PutStr(random.K6String(12), random.K6String(12)) + event.Attributes().PutStr("event attribute"+random.K6String(5), random.K6String(12)) + + link := span.Links().AppendEmpty() + link.SetTraceID(traceID) + link.SetSpanID(random.SpanID()) + link.Attributes().PutStr(random.K6String(12), random.K6String(12)) status := span.Status() status.SetCode(1) From 61a96880ca3b1636020f2d69942a5f07fe1f5a35 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Thu, 28 Dec 2023 14:33:45 -0600 Subject: [PATCH 2/8] remove test artifact --- pkg/tracegen/parameterized.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tracegen/parameterized.go b/pkg/tracegen/parameterized.go index c5c4803..437ca32 100644 --- a/pkg/tracegen/parameterized.go +++ b/pkg/tracegen/parameterized.go @@ -114,7 +114,7 @@ func (g *ParameterizedGenerator) generateSpan(t *TraceParams, dest ptrace.Span) event := span.Events().AppendEmpty() event.SetName(random.K6String(12)) event.SetTimestamp(pcommon.NewTimestampFromTime(startTime)) - event.Attributes().PutStr("event attribute"+random.K6String(5), random.K6String(12)) + event.Attributes().PutStr(random.K6String(5), random.K6String(12)) link := span.Links().AppendEmpty() link.SetTraceID(traceID) From 58a4aa5e2d6aa064f690b0e5425c59b164544b89 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Thu, 11 Jan 2024 21:54:22 -0600 Subject: [PATCH 3/8] add templated events and links --- examples/template/template.js | 14 +- pkg/tracegen/templated.go | 322 ++++++++++++++++++++++++++++++++- pkg/tracegen/templated_test.go | 93 ++++++++++ 3 files changed, 418 insertions(+), 11 deletions(-) diff --git a/examples/template/template.js b/examples/template/template.js index c31818e..056c3e0 100644 --- a/examples/template/template.js +++ b/examples/template/template.js @@ -21,7 +21,9 @@ const client = new tracing.Client({ const traceDefaults = { attributeSemantics: tracing.SEMANTICS_HTTP, attributes: {"one": "three"}, - randomAttributes: {count: 2, cardinality: 5} + randomAttributes: {count: 2, cardinality: 5}, + eventDefaults: {generateExceptionOnError: true, count: 1.0, randomAttributes: {count: 2, cardinality: 3}}, + linkDefaults: {linkToPreviousSpanIndex: true, count: 1.0, randomAttributes: {count: 2, cardinality: 3}}, } const traceTemplates = [ @@ -63,6 +65,16 @@ const traceTemplates = [ {service: "auth-service", name: "authenticate", attributes: {"http.status_code": 403}}, ] }, + { + defaults: traceDefaults, + spans: [ + {service: "shop-backend", attributes: {"http.status_code": 403}}, + {service: "shop-backend", name: "authenticate", attributes: {"http.request.header.accept": ["application/json"]}}, + {service: "auth-service", name: "authenticate", attributes: {"http.status_code": 403}}, + {service: "test-random", name: "events", randomEvents: {exceptionCount: 1, count: 2, randomAttributes: {count: 5, cardinality: 2}}}, + {service: "test-random", name: "links", randomLinks: {linkToPreviousSpanIndex: true, count: 2, randomAttributes: {count: 3, cardinality: 2}}} + ] + }, ] export default function () { diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go index 403c488..90b663e 100644 --- a/pkg/tracegen/templated.go +++ b/pkg/tracegen/templated.go @@ -36,7 +36,7 @@ type Range struct { // AttributeParams describe how random attributes should be created. type AttributeParams struct { - // Count the number of attributes to creat. + // Count the number of attributes to create. Count int // Cardinality how many distinct values are created for each attribute. Cardinality *int @@ -50,6 +50,10 @@ type SpanDefaults struct { Attributes map[string]interface{} `js:"attributes"` // RandomAttributes random attributes generated for each span. RandomAttributes *AttributeParams `js:"randomAttributes"` + // Random events generated for each span + EventDefaults EventDefaults `js:"eventDefaults"` + // Random links generated for each span + LinkDefaults LinkDefaults `js:"linkDefaults"` } // SpanTemplate parameters that define how a span is created. @@ -72,6 +76,14 @@ type SpanTemplate struct { // RandomAttributes parameters to configure the creation of random attributes. If missing, no random attributes // are added to the span. RandomAttributes *AttributeParams `js:"randomAttributes"` + // List of events for the span with specific parameters + Events []Event `js:"events"` + // List of links for the span with specific parameters + Links []Link `js:"links"` + // Generate random events for the span + RandomEvents RandomEvents `js:"randomEvents"` + // Generate random links for the span + RandomLinks RandomLinks `js:"randomLinks"` } // TraceTemplate describes how all a trace and it's spans are generated. @@ -82,6 +94,73 @@ type TraceTemplate struct { Spans []SpanTemplate `js:"spans"` } +type Link struct { + // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span + LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` + // Attributes for this link + Attributes map[string]interface{} `js:"attributes"` + // Generate random attributes for this link + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type Event struct { + // Name of event + Name string `js:"name"` + // Attributes for this event + Attributes map[string]interface{} `js:"attributes"` + // Generate random attributes for this event + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type LinkDefaults struct { + // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span + // Unless it is the first span then a random TraceID and a random SpanID will be used + LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` + // Rate of random links per each span + Rate float32 `js:"rate"` + // Generate random attributes for this link + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type EventDefaults struct { + // Generate exception event if status code of the span is >= 400 + GenerateExceptionOnError bool `js:"generateExceptionOnError"` + // Rate of random events per each span + Rate float32 `js:"rate"` + // Generate random attributes for this event + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type RandomEvents struct { + // Number of random exception events to generate for the span + ExceptionCount int `js:"exceptionCount"` + // Number of non-exception events to generate for the span + Count int `js:"count"` + // Generate random attributes for these events + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type RandomLinks struct { + // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span + LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` + // Number of links to generate for the span + Count int `js:"count"` + // Generate random attributes for these links + RandomAttributes *AttributeParams `js:"randomAttributes"` +} + +type internalLinkDefaults struct { + LinkToPreviousSpanIndex bool + Count int + RandomAttributes *AttributeParams +} + +type internalEventDefaults struct { + GenerateExceptionOnError bool + Count int + RandomAttributes *AttributeParams +} + // NewTemplatedGenerator creates a new trace generator. func NewTemplatedGenerator(template *TraceTemplate) (*TemplatedGenerator, error) { gen := &TemplatedGenerator{} @@ -102,15 +181,18 @@ type TemplatedGenerator struct { } type internalSpanTemplate struct { - idx int - resource *internalResourceTemplate - parent *internalSpanTemplate - name string - kind ptrace.SpanKind - duration *Range - attributeSemantics *OTelSemantics - attributes map[string]interface{} - randomAttributes map[string][]interface{} + idx int + resource *internalResourceTemplate + parent *internalSpanTemplate + name string + kind ptrace.SpanKind + duration *Range + attributeSemantics *OTelSemantics + attributes map[string]interface{} + randomAttributes map[string][]interface{} + events []Event + links []Link + generateExceptionEvents bool } type internalResourceTemplate struct { @@ -226,6 +308,58 @@ func (g *TemplatedGenerator) generateSpan(scopeSpans ptrace.ScopeSpans, tmpl *in } } + // events + + span.Events().EnsureCapacity(len(tmpl.events)) + for _, e := range tmpl.events { + event := span.Events().AppendEmpty() + event.SetName(e.Name) + event.SetTimestamp(pcommon.NewTimestampFromTime(end)) + for k, v := range e.Attributes { + _ = event.Attributes().PutEmpty(k).FromRaw(v) + } + } + + if tmpl.generateExceptionEvents { + var status int64 + parentAttr := pcommon.NewMap() + if parent != nil { + parentAttr = parent.Attributes() + } + if st, found := span.Attributes().Get("http.status_code"); found { + status = st.Int() + } else if st, found = parentAttr.Get("http.status_code"); found { + status = st.Int() + } else { + status = random.HTTPStatusSuccess() + span.Attributes().PutInt("http.status_code", status) + } + if status >= 400 { + exceptionEvent := generateExceptionEvent() + event := span.Events().AppendEmpty() + event.SetName(exceptionEvent.Name) + for k, v := range exceptionEvent.Attributes { + _ = event.Attributes().PutEmpty(k).FromRaw(v) + } + } + } + + // links + span.Links().EnsureCapacity(len(tmpl.links)) + for _, l := range tmpl.links { + link := span.Links().AppendEmpty() + if l.LinkToPreviousSpanIndex && parent != nil { + link.SetTraceID(traceID) + link.SetSpanID(parent.SpanID()) + } else { + link.SetTraceID(random.TraceID()) + link.SetSpanID(random.SpanID()) + } + for k, v := range l.Attributes { + _ = link.Attributes().PutEmpty(k).FromRaw(v) + } + } + return span } @@ -407,6 +541,49 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat } span.attributes = util.MergeMaps(defaults.Attributes, tmpl.Attributes) + eventDefaultsRate := defaults.EventDefaults.Rate + var eventDefaults internalEventDefaults + // if rate is more than 1, use whole integers + if eventDefaultsRate > 1 { + eventDefaults = internalEventDefaults{ + GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, + RandomAttributes: defaults.EventDefaults.RandomAttributes, + Count: int(eventDefaultsRate), + } + } else if idx%int(1/eventDefaultsRate) == 0 { + // if rate is less than one + eventDefaults = internalEventDefaults{ + GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, + RandomAttributes: defaults.EventDefaults.RandomAttributes, + Count: 1, + } + } + + // generate all non-exception events + span.events = g.initializeEvents(tmpl.Events, tmpl.RandomEvents, eventDefaults) + + // need span status to determine if an exception event should occur + span.generateExceptionEvents = defaults.EventDefaults.GenerateExceptionOnError + + linkDefaultsRate := defaults.LinkDefaults.Rate + var linkDefaults internalLinkDefaults + if linkDefaultsRate > 1 { + linkDefaults = internalLinkDefaults{ + LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, + RandomAttributes: defaults.LinkDefaults.RandomAttributes, + Count: int(linkDefaultsRate), + } + } else if idx%int(1/linkDefaultsRate) == 0 { + linkDefaults = internalLinkDefaults{ + LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, + RandomAttributes: defaults.LinkDefaults.RandomAttributes, + Count: 1, + } + } + + // initialize all links but need + span.links = g.initializeLinks(tmpl.Links, tmpl.RandomLinks, linkDefaults) + // set span name if tmpl.Name != nil { span.name = *tmpl.Name @@ -501,3 +678,128 @@ func initializeRandomAttributes(attributeParams *AttributeParams) map[string][]i return attributes } + +func (g *TemplatedGenerator) initializeEvents(tmplEvents []Event, randomEvents RandomEvents, eventDefaults internalEventDefaults) []Event { + count := len(tmplEvents) + randomEvents.Count + eventDefaults.Count + + if count == 0 { + return []Event{} + } + + events := make([]Event, 0, count) + + for _, e := range tmplEvents { + event := generateEvent(e.Name, e.Attributes, e.RandomAttributes) + events = append(events, event) + } + + for i := 0; i < randomEvents.ExceptionCount; i++ { + event := generateExceptionEvent() + events = append(events, event) + } + + for i := 0; i < randomEvents.Count; i++ { + event := generateEvent("", nil, randomEvents.RandomAttributes) + events = append(events, event) + } + + for i := 0; i < eventDefaults.Count; i++ { + event := generateEvent("", nil, eventDefaults.RandomAttributes) + events = append(events, event) + } + + return events +} + +func generateExceptionEvent() Event { + return Event{ + Name: "exception", + Attributes: map[string]interface{}{ + "exception.escape": false, + "exception.message": generateRandomExceptionMsg(), + "exception.stacktrace": generateRandomExceptionStackTrace(), + "exception.type": random.K6String(10) + ".error", + }, + } +} + +func generateEvent(name string, attributes map[string]interface{}, randomAttr *AttributeParams) Event { + event := Event{ + Attributes: make(map[string]interface{}), + } + + if name != "" { + event.Name = name + } else { + event.Name = "event " + random.K6String(10) + } + + for k, v := range attributes { + event.Attributes[k] = v + } + + for k, v := range initializeRandomAttributes(randomAttr) { + event.Attributes[k] = random.SelectElement(v) + } + return event +} + +func generateRandomExceptionMsg() string { + return "error: " + random.K6String(20) +} + +func generateRandomExceptionStackTrace() string { + var ( + panics = []string{"runtime error: index out of range", "runtime error: can't divide by 0"} + functions = []string{"main.main()", "trace.makespan()", "account.login()", "payment.collect()"} + ) + + return "panic: " + random.SelectElement(panics) + "\n" + random.SelectElement(functions) +} + +func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks RandomLinks, linkDefaults internalLinkDefaults) []Link { + count := len(tmplLinks) + randomLinks.Count + linkDefaults.Count + + if count == 0 { + return []Link{} + } + + links := make([]Link, 0, count) + newLink := func(linkToPar bool) *Link { + return &Link{ + LinkToPreviousSpanIndex: linkToPar, + Attributes: make(map[string]interface{}), + } + } + + for _, l := range tmplLinks { + link := newLink(l.LinkToPreviousSpanIndex) + + for k, v := range l.Attributes { + link.Attributes[k] = v + } + + for k, v := range initializeRandomAttributes(l.RandomAttributes) { + link.Attributes[k] = random.SelectElement(v) + } + links = append(links, *link) + } + + for i := 0; i < randomLinks.Count; i++ { + link := newLink(randomLinks.LinkToPreviousSpanIndex) + for k, v := range initializeRandomAttributes(randomLinks.RandomAttributes) { + link.Attributes[k] = random.SelectElement(v) + } + links = append(links, *link) + } + + for i := 0; i < linkDefaults.Count; i++ { + link := newLink(linkDefaults.LinkToPreviousSpanIndex) + for k, v := range initializeRandomAttributes(linkDefaults.RandomAttributes) { + link.Attributes[k] = random.SelectElement(v) + } + links = append(links, *link) + } + + return links +} diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index cc1e95a..617b69f 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -52,6 +52,99 @@ func TestTemplatedGenerator_Traces(t *testing.T) { } } +func TestTemplatedGenerator_EventsLinks(t *testing.T) { + attributeSemantics := []OTelSemantics{SemanticsHTTP} + template := TraceTemplate{ + Defaults: SpanDefaults{ + Attributes: map[string]interface{}{"fixed.attr": "some-value"}, + RandomAttributes: &AttributeParams{Count: 3}, + LinkDefaults: LinkDefaults{LinkToPreviousSpanIndex: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + EventDefaults: EventDefaults{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + }, + Spans: []SpanTemplate{ + // do not change order of the first one + {Service: "test-service", Name: ptr("only_default")}, + {Service: "test-service", Name: ptr("default_and_template"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}}, + {Service: "test-service", Name: ptr("default_and_random"), RandomEvents: RandomEvents{Count: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: RandomLinks{LinkToPreviousSpanIndex: false, Count: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_template_random"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}, RandomEvents: RandomEvents{Count: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: RandomLinks{LinkToPreviousSpanIndex: false, Count: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_generate_on_error"), Attributes: map[string]interface{}{"http.status_code": 400}}, + }, + } + + for _, semantics := range attributeSemantics { + template.Defaults.AttributeSemantics = &semantics + gen, err := NewTemplatedGenerator(&template) + assert.NoError(t, err) + + for i := 0; i < testRounds; i++ { + traces := gen.Traces() + spans := collectSpansFromTrace(traces) + + assert.Len(t, spans, len(template.Spans)) + for i, span := range spans { + events := span.Events() + links := span.Links() + checkEventsLinksLength := func(spanIndex, expectedTemplate, expectedRandom int, spanName string) { + expected := expectedTemplate + expectedRandom + // because default rate is 0.5 + if spanIndex%2 == 0 { + assert.Equal(t, expected+1, events.Len(), "test name: %s events", spanName) + assert.Equal(t, expected+1, links.Len(), "test name: %s links", spanName) + } else { + assert.Equal(t, expected, events.Len(), "test name: %s events", spanName) + assert.Equal(t, expected, links.Len(), "test name: %s links", spanName) + } + } + + switch span.Name() { + case "only_default": + checkEventsLinksLength(i, 0, 0, span.Name()) + if i%2 == 0 { + // check default event with 3 random attributes + event := events.At(0) + assert.Equal(t, 3, len(event.Attributes().AsRaw())) + + // check default link with 3 random attributes + // and not matching trace id and parent span id because this is + // the first span, there is no previous span + link := links.At(0) + assert.Equal(t, 3, len(link.Attributes().AsRaw())) + assert.NotEqual(t, span.TraceID().String(), link.TraceID()) + assert.NotEqual(t, span.ParentSpanID(), link.SpanID()) + } + case "default_and_template": + checkEventsLinksLength(i, 1, 0, span.Name()) + case "default_and_random": + checkEventsLinksLength(i, 0, 2, span.Name()) + case "default_template_random": + checkEventsLinksLength(i, 1, 2, span.Name()) + case "default_generate_on_error": + // # events and links should not match in this scenario + if i%2 == 0 { + assert.Equal(t, 2, events.Len()) + assert.Equal(t, 1, links.Len()) + } else { + assert.Equal(t, 1, events.Len()) + assert.Equal(t, 0, links.Len()) + } + found := false + for i := 0; i < events.Len(); i++ { + event := events.At(i) + if event.Name() == "exception" { + found = true + assert.NotNil(t, event.Attributes().AsRaw()["exception.escape"]) + assert.NotNil(t, event.Attributes().AsRaw()["exception.message"]) + assert.NotNil(t, event.Attributes().AsRaw()["exception.stacktrace"]) + assert.NotNil(t, event.Attributes().AsRaw()["exception.type"]) + } + } + assert.True(t, found, "exception event not found") + } + } + } + } +} + func attributesWithPrefix(span ptrace.Span, prefix string) int { var count int span.Attributes().Range(func(k string, _ pcommon.Value) bool { From 39a488a64729b654484d8c5538cd9ab199964408 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Mon, 15 Jan 2024 16:46:37 -0600 Subject: [PATCH 4/8] use random factor for rates & merge defaults+random --- examples/template/template.js | 4 +- pkg/tracegen/templated.go | 88 +++++++++++++++++++--------------- pkg/tracegen/templated_test.go | 34 +++++-------- 3 files changed, 64 insertions(+), 62 deletions(-) diff --git a/examples/template/template.js b/examples/template/template.js index 056c3e0..9039557 100644 --- a/examples/template/template.js +++ b/examples/template/template.js @@ -71,8 +71,8 @@ const traceTemplates = [ {service: "shop-backend", attributes: {"http.status_code": 403}}, {service: "shop-backend", name: "authenticate", attributes: {"http.request.header.accept": ["application/json"]}}, {service: "auth-service", name: "authenticate", attributes: {"http.status_code": 403}}, - {service: "test-random", name: "events", randomEvents: {exceptionCount: 1, count: 2, randomAttributes: {count: 5, cardinality: 2}}}, - {service: "test-random", name: "links", randomLinks: {linkToPreviousSpanIndex: true, count: 2, randomAttributes: {count: 3, cardinality: 2}}} + {service: "cart-service", name: "checkout", randomEvents: {exceptionCount: 1, count: 2, randomAttributes: {count: 5, cardinality: 2}}}, + {service: "billing-service", name: "payment", randomLinks: {linkToPreviousSpanIndex: true, count: 2, randomAttributes: {count: 3, cardinality: 2}}} ] }, ] diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go index 90b663e..bf6c8f6 100644 --- a/pkg/tracegen/templated.go +++ b/pkg/tracegen/templated.go @@ -2,6 +2,7 @@ package tracegen import ( "fmt" + "math/rand" "net/http" "net/url" "strings" @@ -51,9 +52,9 @@ type SpanDefaults struct { // RandomAttributes random attributes generated for each span. RandomAttributes *AttributeParams `js:"randomAttributes"` // Random events generated for each span - EventDefaults EventDefaults `js:"eventDefaults"` + EventDefaults EventParams `js:"eventDefaults"` // Random links generated for each span - LinkDefaults LinkDefaults `js:"linkDefaults"` + LinkDefaults LinkParams `js:"linkDefaults"` } // SpanTemplate parameters that define how a span is created. @@ -81,9 +82,9 @@ type SpanTemplate struct { // List of links for the span with specific parameters Links []Link `js:"links"` // Generate random events for the span - RandomEvents RandomEvents `js:"randomEvents"` + RandomEvents EventParams `js:"randomEvents"` // Generate random links for the span - RandomLinks RandomLinks `js:"randomLinks"` + RandomLinks LinkParams `js:"randomLinks"` } // TraceTemplate describes how all a trace and it's spans are generated. @@ -112,7 +113,7 @@ type Event struct { RandomAttributes *AttributeParams `js:"randomAttributes"` } -type LinkDefaults struct { +type LinkParams struct { // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span // Unless it is the first span then a random TraceID and a random SpanID will be used LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` @@ -122,41 +123,26 @@ type LinkDefaults struct { RandomAttributes *AttributeParams `js:"randomAttributes"` } -type EventDefaults struct { +type EventParams struct { // Generate exception event if status code of the span is >= 400 GenerateExceptionOnError bool `js:"generateExceptionOnError"` + // Rate of exception events per each span + ExceptionRate float32 `js:"exceptionRate"` // Rate of random events per each span Rate float32 `js:"rate"` // Generate random attributes for this event RandomAttributes *AttributeParams `js:"randomAttributes"` } -type RandomEvents struct { - // Number of random exception events to generate for the span - ExceptionCount int `js:"exceptionCount"` - // Number of non-exception events to generate for the span - Count int `js:"count"` - // Generate random attributes for these events - RandomAttributes *AttributeParams `js:"randomAttributes"` -} - -type RandomLinks struct { - // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span - LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` - // Number of links to generate for the span - Count int `js:"count"` - // Generate random attributes for these links - RandomAttributes *AttributeParams `js:"randomAttributes"` -} - -type internalLinkDefaults struct { +type internalLinkParams struct { LinkToPreviousSpanIndex bool Count int RandomAttributes *AttributeParams } -type internalEventDefaults struct { +type internalEventParams struct { GenerateExceptionOnError bool + ExceptionCount int Count int RandomAttributes *AttributeParams } @@ -542,47 +528,71 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat span.attributes = util.MergeMaps(defaults.Attributes, tmpl.Attributes) eventDefaultsRate := defaults.EventDefaults.Rate - var eventDefaults internalEventDefaults + var eventDefaults internalEventParams // if rate is more than 1, use whole integers if eventDefaultsRate > 1 { - eventDefaults = internalEventDefaults{ + eventDefaults = internalEventParams{ GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, RandomAttributes: defaults.EventDefaults.RandomAttributes, Count: int(eventDefaultsRate), + ExceptionCount: int(defaults.EventDefaults.ExceptionRate), } - } else if idx%int(1/eventDefaultsRate) == 0 { + } else { + var count, exeptionCount int + if rand.Float32() < eventDefaultsRate { + count = 1 + } + + if rand.Float32() < eventDefaultsRate { + exeptionCount = 1 + } + // if rate is less than one - eventDefaults = internalEventDefaults{ + eventDefaults = internalEventParams{ GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, RandomAttributes: defaults.EventDefaults.RandomAttributes, - Count: 1, + Count: count, + ExceptionCount: exeptionCount, } } + randomEvents := internalEventParams{ + GenerateExceptionOnError: tmpl.RandomEvents.GenerateExceptionOnError, + RandomAttributes: tmpl.RandomEvents.RandomAttributes, + Count: int(tmpl.RandomEvents.Rate), + ExceptionCount: int(tmpl.RandomEvents.ExceptionRate), + } + // generate all non-exception events - span.events = g.initializeEvents(tmpl.Events, tmpl.RandomEvents, eventDefaults) + span.events = g.initializeEvents(tmpl.Events, randomEvents, eventDefaults) // need span status to determine if an exception event should occur span.generateExceptionEvents = defaults.EventDefaults.GenerateExceptionOnError linkDefaultsRate := defaults.LinkDefaults.Rate - var linkDefaults internalLinkDefaults + var linkDefaults internalLinkParams if linkDefaultsRate > 1 { - linkDefaults = internalLinkDefaults{ + linkDefaults = internalLinkParams{ LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, RandomAttributes: defaults.LinkDefaults.RandomAttributes, Count: int(linkDefaultsRate), } - } else if idx%int(1/linkDefaultsRate) == 0 { - linkDefaults = internalLinkDefaults{ + } else if rand.Float32() < linkDefaultsRate { + linkDefaults = internalLinkParams{ LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, RandomAttributes: defaults.LinkDefaults.RandomAttributes, Count: 1, } } + randomLinks := internalLinkParams{ + LinkToPreviousSpanIndex: tmpl.RandomLinks.LinkToPreviousSpanIndex, + Count: int(tmpl.RandomLinks.Rate), + RandomAttributes: tmpl.RandomEvents.RandomAttributes, + } + // initialize all links but need - span.links = g.initializeLinks(tmpl.Links, tmpl.RandomLinks, linkDefaults) + span.links = g.initializeLinks(tmpl.Links, randomLinks, linkDefaults) // set span name if tmpl.Name != nil { @@ -679,7 +689,7 @@ func initializeRandomAttributes(attributeParams *AttributeParams) map[string][]i return attributes } -func (g *TemplatedGenerator) initializeEvents(tmplEvents []Event, randomEvents RandomEvents, eventDefaults internalEventDefaults) []Event { +func (g *TemplatedGenerator) initializeEvents(tmplEvents []Event, randomEvents internalEventParams, eventDefaults internalEventParams) []Event { count := len(tmplEvents) + randomEvents.Count + eventDefaults.Count if count == 0 { @@ -757,7 +767,7 @@ func generateRandomExceptionStackTrace() string { return "panic: " + random.SelectElement(panics) + "\n" + random.SelectElement(functions) } -func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks RandomLinks, linkDefaults internalLinkDefaults) []Link { +func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks internalLinkParams, linkDefaults internalLinkParams) []Link { count := len(tmplLinks) + randomLinks.Count + linkDefaults.Count if count == 0 { diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index 617b69f..3f2762d 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -58,15 +58,15 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { Defaults: SpanDefaults{ Attributes: map[string]interface{}{"fixed.attr": "some-value"}, RandomAttributes: &AttributeParams{Count: 3}, - LinkDefaults: LinkDefaults{LinkToPreviousSpanIndex: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, - EventDefaults: EventDefaults{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + LinkDefaults: LinkParams{LinkToPreviousSpanIndex: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + EventDefaults: EventParams{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, }, Spans: []SpanTemplate{ // do not change order of the first one {Service: "test-service", Name: ptr("only_default")}, {Service: "test-service", Name: ptr("default_and_template"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}}, - {Service: "test-service", Name: ptr("default_and_random"), RandomEvents: RandomEvents{Count: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: RandomLinks{LinkToPreviousSpanIndex: false, Count: 2, RandomAttributes: &AttributeParams{Count: 1}}}, - {Service: "test-service", Name: ptr("default_template_random"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}, RandomEvents: RandomEvents{Count: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: RandomLinks{LinkToPreviousSpanIndex: false, Count: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_and_random"), RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{LinkToPreviousSpanIndex: false, Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_template_random"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}, RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{LinkToPreviousSpanIndex: false, Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, {Service: "test-service", Name: ptr("default_generate_on_error"), Attributes: map[string]interface{}{"http.status_code": 400}}, }, } @@ -87,23 +87,21 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { checkEventsLinksLength := func(spanIndex, expectedTemplate, expectedRandom int, spanName string) { expected := expectedTemplate + expectedRandom // because default rate is 0.5 - if spanIndex%2 == 0 { - assert.Equal(t, expected+1, events.Len(), "test name: %s events", spanName) - assert.Equal(t, expected+1, links.Len(), "test name: %s links", spanName) - } else { - assert.Equal(t, expected, events.Len(), "test name: %s events", spanName) - assert.Equal(t, expected, links.Len(), "test name: %s links", spanName) - } + assert.GreaterOrEqual(t, events.Len(), expected, "test name: %s events", spanName) + assert.GreaterOrEqual(t, links.Len(), expected, "test name: %s links", spanName) + assert.LessOrEqual(t, events.Len(), expected+1, "test name: %s events", spanName) + assert.LessOrEqual(t, links.Len(), expected+1, "test name: %s links", spanName) } switch span.Name() { case "only_default": checkEventsLinksLength(i, 0, 0, span.Name()) - if i%2 == 0 { + if events.Len() > 0 { // check default event with 3 random attributes event := events.At(0) assert.Equal(t, 3, len(event.Attributes().AsRaw())) - + } + if links.Len() > 0 { // check default link with 3 random attributes // and not matching trace id and parent span id because this is // the first span, there is no previous span @@ -119,14 +117,8 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { case "default_template_random": checkEventsLinksLength(i, 1, 2, span.Name()) case "default_generate_on_error": - // # events and links should not match in this scenario - if i%2 == 0 { - assert.Equal(t, 2, events.Len()) - assert.Equal(t, 1, links.Len()) - } else { - assert.Equal(t, 1, events.Len()) - assert.Equal(t, 0, links.Len()) - } + // there should be at least one event + assert.GreaterOrEqual(t, events.Len(), 0, "test name: %s events", "default generate on error") found := false for i := 0; i < events.Len(); i++ { event := events.At(i) From cd0d018ad26ce62a5cd2f034d18b65fcaa1c4cdd Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Mon, 15 Jan 2024 17:00:52 -0600 Subject: [PATCH 5/8] making linking to previous span a default until we can support specific linkage --- pkg/tracegen/templated.go | 37 +++++++++++++--------------------- pkg/tracegen/templated_test.go | 21 ++++++++++++++----- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go index bf6c8f6..43031d0 100644 --- a/pkg/tracegen/templated.go +++ b/pkg/tracegen/templated.go @@ -96,8 +96,6 @@ type TraceTemplate struct { } type Link struct { - // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span - LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` // Attributes for this link Attributes map[string]interface{} `js:"attributes"` // Generate random attributes for this link @@ -114,9 +112,6 @@ type Event struct { } type LinkParams struct { - // LinkToPreviousSpanIndex true will set TraceID and SpanID the same as the previous span - // Unless it is the first span then a random TraceID and a random SpanID will be used - LinkToPreviousSpanIndex bool `js:"linkToPreviousSpanIndex"` // Rate of random links per each span Rate float32 `js:"rate"` // Generate random attributes for this link @@ -334,7 +329,9 @@ func (g *TemplatedGenerator) generateSpan(scopeSpans ptrace.ScopeSpans, tmpl *in span.Links().EnsureCapacity(len(tmpl.links)) for _, l := range tmpl.links { link := span.Links().AppendEmpty() - if l.LinkToPreviousSpanIndex && parent != nil { + // default to linking to previous span if exist + // maybe we will be able support linking to specific spans in the future + if parent != nil { link.SetTraceID(traceID) link.SetSpanID(parent.SpanID()) } else { @@ -573,22 +570,19 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat var linkDefaults internalLinkParams if linkDefaultsRate > 1 { linkDefaults = internalLinkParams{ - LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, - RandomAttributes: defaults.LinkDefaults.RandomAttributes, - Count: int(linkDefaultsRate), + RandomAttributes: defaults.LinkDefaults.RandomAttributes, + Count: int(linkDefaultsRate), } } else if rand.Float32() < linkDefaultsRate { linkDefaults = internalLinkParams{ - LinkToPreviousSpanIndex: defaults.LinkDefaults.LinkToPreviousSpanIndex, - RandomAttributes: defaults.LinkDefaults.RandomAttributes, - Count: 1, + RandomAttributes: defaults.LinkDefaults.RandomAttributes, + Count: 1, } } randomLinks := internalLinkParams{ - LinkToPreviousSpanIndex: tmpl.RandomLinks.LinkToPreviousSpanIndex, - Count: int(tmpl.RandomLinks.Rate), - RandomAttributes: tmpl.RandomEvents.RandomAttributes, + Count: int(tmpl.RandomLinks.Rate), + RandomAttributes: tmpl.RandomEvents.RandomAttributes, } // initialize all links but need @@ -775,20 +769,17 @@ func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks inter } links := make([]Link, 0, count) - newLink := func(linkToPar bool) *Link { + newLink := func() *Link { return &Link{ - LinkToPreviousSpanIndex: linkToPar, - Attributes: make(map[string]interface{}), + Attributes: make(map[string]interface{}), } } for _, l := range tmplLinks { - link := newLink(l.LinkToPreviousSpanIndex) - + link := newLink() for k, v := range l.Attributes { link.Attributes[k] = v } - for k, v := range initializeRandomAttributes(l.RandomAttributes) { link.Attributes[k] = random.SelectElement(v) } @@ -796,7 +787,7 @@ func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks inter } for i := 0; i < randomLinks.Count; i++ { - link := newLink(randomLinks.LinkToPreviousSpanIndex) + link := newLink() for k, v := range initializeRandomAttributes(randomLinks.RandomAttributes) { link.Attributes[k] = random.SelectElement(v) } @@ -804,7 +795,7 @@ func (g *TemplatedGenerator) initializeLinks(tmplLinks []Link, randomLinks inter } for i := 0; i < linkDefaults.Count; i++ { - link := newLink(linkDefaults.LinkToPreviousSpanIndex) + link := newLink() for k, v := range initializeRandomAttributes(linkDefaults.RandomAttributes) { link.Attributes[k] = random.SelectElement(v) } diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index 3f2762d..f923b9d 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -58,15 +58,15 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { Defaults: SpanDefaults{ Attributes: map[string]interface{}{"fixed.attr": "some-value"}, RandomAttributes: &AttributeParams{Count: 3}, - LinkDefaults: LinkParams{LinkToPreviousSpanIndex: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + LinkDefaults: LinkParams{Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, EventDefaults: EventParams{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, }, Spans: []SpanTemplate{ // do not change order of the first one {Service: "test-service", Name: ptr("only_default")}, - {Service: "test-service", Name: ptr("default_and_template"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}}, - {Service: "test-service", Name: ptr("default_and_random"), RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{LinkToPreviousSpanIndex: false, Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, - {Service: "test-service", Name: ptr("default_template_random"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{LinkToPreviousSpanIndex: true, Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}, RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{LinkToPreviousSpanIndex: false, Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_and_template"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}}, + {Service: "test-service", Name: ptr("default_and_random"), RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, + {Service: "test-service", Name: ptr("default_template_random"), Events: []Event{{Name: "event-name", RandomAttributes: &AttributeParams{Count: 2}}}, Links: []Link{{Attributes: map[string]interface{}{"link-attr-key": "link-attr-value"}}}, RandomEvents: EventParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}, RandomLinks: LinkParams{Rate: 2, RandomAttributes: &AttributeParams{Count: 1}}}, {Service: "test-service", Name: ptr("default_generate_on_error"), Attributes: map[string]interface{}{"http.status_code": 400}}, }, } @@ -93,6 +93,14 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { assert.LessOrEqual(t, links.Len(), expected+1, "test name: %s links", spanName) } + checkLinks := func() { + for i := 0; i < links.Len(); i++ { + link := links.At(i) + assert.Equal(t, span.TraceID(), link.TraceID()) + assert.Equal(t, span.ParentSpanID(), link.SpanID()) + } + } + switch span.Name() { case "only_default": checkEventsLinksLength(i, 0, 0, span.Name()) @@ -107,15 +115,18 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { // the first span, there is no previous span link := links.At(0) assert.Equal(t, 3, len(link.Attributes().AsRaw())) - assert.NotEqual(t, span.TraceID().String(), link.TraceID()) + assert.NotEqual(t, span.TraceID(), link.TraceID()) assert.NotEqual(t, span.ParentSpanID(), link.SpanID()) } case "default_and_template": checkEventsLinksLength(i, 1, 0, span.Name()) + checkLinks() case "default_and_random": checkEventsLinksLength(i, 0, 2, span.Name()) + checkLinks() case "default_template_random": checkEventsLinksLength(i, 1, 2, span.Name()) + checkLinks() case "default_generate_on_error": // there should be at least one event assert.GreaterOrEqual(t, events.Len(), 0, "test name: %s events", "default generate on error") From 723b5d8b88bf88feb205a38932b58efe7fcb5480 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Mon, 15 Jan 2024 17:04:29 -0600 Subject: [PATCH 6/8] lint --- pkg/tracegen/templated_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index f923b9d..ed1e54c 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -81,10 +81,10 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { spans := collectSpansFromTrace(traces) assert.Len(t, spans, len(template.Spans)) - for i, span := range spans { + for _, span := range spans { events := span.Events() links := span.Links() - checkEventsLinksLength := func(spanIndex, expectedTemplate, expectedRandom int, spanName string) { + checkEventsLinksLength := func(expectedTemplate, expectedRandom int, spanName string) { expected := expectedTemplate + expectedRandom // because default rate is 0.5 assert.GreaterOrEqual(t, events.Len(), expected, "test name: %s events", spanName) @@ -103,7 +103,7 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { switch span.Name() { case "only_default": - checkEventsLinksLength(i, 0, 0, span.Name()) + checkEventsLinksLength(0, 0, span.Name()) if events.Len() > 0 { // check default event with 3 random attributes event := events.At(0) @@ -119,13 +119,13 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { assert.NotEqual(t, span.ParentSpanID(), link.SpanID()) } case "default_and_template": - checkEventsLinksLength(i, 1, 0, span.Name()) + checkEventsLinksLength(1, 0, span.Name()) checkLinks() case "default_and_random": - checkEventsLinksLength(i, 0, 2, span.Name()) + checkEventsLinksLength(0, 2, span.Name()) checkLinks() case "default_template_random": - checkEventsLinksLength(i, 1, 2, span.Name()) + checkEventsLinksLength(1, 2, span.Name()) checkLinks() case "default_generate_on_error": // there should be at least one event From dcc463ed93d0755d125464c0d0a02544e1a213fc Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Tue, 16 Jan 2024 13:13:59 -0600 Subject: [PATCH 7/8] fix template example, rename defaults --- examples/template/template.js | 8 ++++---- pkg/tracegen/templated.go | 30 +++++++++++++++--------------- pkg/tracegen/templated_test.go | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/template/template.js b/examples/template/template.js index 9039557..c36855f 100644 --- a/examples/template/template.js +++ b/examples/template/template.js @@ -22,8 +22,8 @@ const traceDefaults = { attributeSemantics: tracing.SEMANTICS_HTTP, attributes: {"one": "three"}, randomAttributes: {count: 2, cardinality: 5}, - eventDefaults: {generateExceptionOnError: true, count: 1.0, randomAttributes: {count: 2, cardinality: 3}}, - linkDefaults: {linkToPreviousSpanIndex: true, count: 1.0, randomAttributes: {count: 2, cardinality: 3}}, + randomEvents: {generateExceptionOnError: true, rate: 1.0, randomAttributes: {count: 2, cardinality: 3}}, + randomLinks: {rate: 1.0, randomAttributes: {count: 2, cardinality: 3}}, } const traceTemplates = [ @@ -71,8 +71,8 @@ const traceTemplates = [ {service: "shop-backend", attributes: {"http.status_code": 403}}, {service: "shop-backend", name: "authenticate", attributes: {"http.request.header.accept": ["application/json"]}}, {service: "auth-service", name: "authenticate", attributes: {"http.status_code": 403}}, - {service: "cart-service", name: "checkout", randomEvents: {exceptionCount: 1, count: 2, randomAttributes: {count: 5, cardinality: 2}}}, - {service: "billing-service", name: "payment", randomLinks: {linkToPreviousSpanIndex: true, count: 2, randomAttributes: {count: 3, cardinality: 2}}} + {service: "cart-service", name: "checkout", randomEvents: {exceptionRate: 1, rate: 2, randomAttributes: {count: 5, cardinality: 2}}}, + {service: "billing-service", name: "payment", randomLinks: {rate: 2, randomAttributes: {count: 3, cardinality: 2}}} ] }, ] diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go index 43031d0..4e75dac 100644 --- a/pkg/tracegen/templated.go +++ b/pkg/tracegen/templated.go @@ -52,9 +52,9 @@ type SpanDefaults struct { // RandomAttributes random attributes generated for each span. RandomAttributes *AttributeParams `js:"randomAttributes"` // Random events generated for each span - EventDefaults EventParams `js:"eventDefaults"` + RandomEvents EventParams `js:"randomEvents"` // Random links generated for each span - LinkDefaults LinkParams `js:"linkDefaults"` + RandomLinks LinkParams `js:"randomLinks"` } // SpanTemplate parameters that define how a span is created. @@ -130,9 +130,8 @@ type EventParams struct { } type internalLinkParams struct { - LinkToPreviousSpanIndex bool - Count int - RandomAttributes *AttributeParams + Count int + RandomAttributes *AttributeParams } type internalEventParams struct { @@ -319,6 +318,7 @@ func (g *TemplatedGenerator) generateSpan(scopeSpans ptrace.ScopeSpans, tmpl *in exceptionEvent := generateExceptionEvent() event := span.Events().AppendEmpty() event.SetName(exceptionEvent.Name) + event.SetTimestamp(pcommon.NewTimestampFromTime(end)) for k, v := range exceptionEvent.Attributes { _ = event.Attributes().PutEmpty(k).FromRaw(v) } @@ -524,15 +524,15 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat } span.attributes = util.MergeMaps(defaults.Attributes, tmpl.Attributes) - eventDefaultsRate := defaults.EventDefaults.Rate + eventDefaultsRate := defaults.RandomEvents.Rate var eventDefaults internalEventParams // if rate is more than 1, use whole integers if eventDefaultsRate > 1 { eventDefaults = internalEventParams{ - GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, - RandomAttributes: defaults.EventDefaults.RandomAttributes, + GenerateExceptionOnError: defaults.RandomEvents.GenerateExceptionOnError, + RandomAttributes: defaults.RandomEvents.RandomAttributes, Count: int(eventDefaultsRate), - ExceptionCount: int(defaults.EventDefaults.ExceptionRate), + ExceptionCount: int(defaults.RandomEvents.ExceptionRate), } } else { var count, exeptionCount int @@ -546,8 +546,8 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat // if rate is less than one eventDefaults = internalEventParams{ - GenerateExceptionOnError: defaults.EventDefaults.GenerateExceptionOnError, - RandomAttributes: defaults.EventDefaults.RandomAttributes, + GenerateExceptionOnError: defaults.RandomEvents.GenerateExceptionOnError, + RandomAttributes: defaults.RandomEvents.RandomAttributes, Count: count, ExceptionCount: exeptionCount, } @@ -564,18 +564,18 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat span.events = g.initializeEvents(tmpl.Events, randomEvents, eventDefaults) // need span status to determine if an exception event should occur - span.generateExceptionEvents = defaults.EventDefaults.GenerateExceptionOnError + span.generateExceptionEvents = defaults.RandomEvents.GenerateExceptionOnError - linkDefaultsRate := defaults.LinkDefaults.Rate + linkDefaultsRate := defaults.RandomLinks.Rate var linkDefaults internalLinkParams if linkDefaultsRate > 1 { linkDefaults = internalLinkParams{ - RandomAttributes: defaults.LinkDefaults.RandomAttributes, + RandomAttributes: defaults.RandomLinks.RandomAttributes, Count: int(linkDefaultsRate), } } else if rand.Float32() < linkDefaultsRate { linkDefaults = internalLinkParams{ - RandomAttributes: defaults.LinkDefaults.RandomAttributes, + RandomAttributes: defaults.RandomLinks.RandomAttributes, Count: 1, } } diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index ed1e54c..66b7425 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -58,8 +58,8 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { Defaults: SpanDefaults{ Attributes: map[string]interface{}{"fixed.attr": "some-value"}, RandomAttributes: &AttributeParams{Count: 3}, - LinkDefaults: LinkParams{Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, - EventDefaults: EventParams{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + RandomLinks: LinkParams{Rate: 1, RandomAttributes: &AttributeParams{Count: 3}}, + RandomEvents: EventParams{GenerateExceptionOnError: true, Rate: 1, RandomAttributes: &AttributeParams{Count: 3}}, }, Spans: []SpanTemplate{ // do not change order of the first one From c24f7d9d848be67fb19fdcecf28d39bd77446c36 Mon Sep 17 00:00:00 2001 From: Jennie Pham Date: Tue, 16 Jan 2024 20:02:26 -0600 Subject: [PATCH 8/8] oops forgot to undo testing --- pkg/tracegen/templated_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/tracegen/templated_test.go b/pkg/tracegen/templated_test.go index 66b7425..a4c0033 100644 --- a/pkg/tracegen/templated_test.go +++ b/pkg/tracegen/templated_test.go @@ -58,8 +58,8 @@ func TestTemplatedGenerator_EventsLinks(t *testing.T) { Defaults: SpanDefaults{ Attributes: map[string]interface{}{"fixed.attr": "some-value"}, RandomAttributes: &AttributeParams{Count: 3}, - RandomLinks: LinkParams{Rate: 1, RandomAttributes: &AttributeParams{Count: 3}}, - RandomEvents: EventParams{GenerateExceptionOnError: true, Rate: 1, RandomAttributes: &AttributeParams{Count: 3}}, + RandomLinks: LinkParams{Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, + RandomEvents: EventParams{GenerateExceptionOnError: true, Rate: 0.5, RandomAttributes: &AttributeParams{Count: 3}}, }, Spans: []SpanTemplate{ // do not change order of the first one