From 495050bbe5ec8f801d691d3d9acc59228b6051d7 Mon Sep 17 00:00:00 2001
From: Joe Elliott <number101010@gmail.com>
Date: Wed, 28 Aug 2024 14:09:36 -0400
Subject: [PATCH 1/2] add span status support

Signed-off-by: Joe Elliott <number101010@gmail.com>
---
 pkg/tracegen/templated.go | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go
index b772c01..522fd07 100644
--- a/pkg/tracegen/templated.go
+++ b/pkg/tracegen/templated.go
@@ -63,6 +63,8 @@ type SpanTemplate struct {
 	Service string `js:"service"`
 	// Name represents the name of the span. If empty, the name will be randomly generated.
 	Name *string `js:"name"`
+	// Status string sets the span status. "error", "ok" or "unset" are supported
+	Status *string `js:"status"`
 	// ParentIDX defines the index of the parent span in TraceTemplate.Spans. ParentIDX must be smaller than the
 	// own index. If empty, the parent is the span with the position directly before this span in TraceTemplate.Spans.
 	ParentIDX *int `js:"parentIdx"`
@@ -154,6 +156,7 @@ type internalSpanTemplate struct {
 	parent             *internalSpanTemplate
 	name               string
 	kind               ptrace.SpanKind
+	status             *ptrace.StatusCode
 	duration           *Range
 	attributeSemantics *OTelSemantics
 	attributes         map[string]interface{}
@@ -322,6 +325,10 @@ func (g *TemplatedGenerator) generateSpan(scopeSpans ptrace.ScopeSpans, tmpl *in
 		}
 	}
 
+	if tmpl.status != nil {
+		span.Status().SetCode(*tmpl.status)
+	}
+
 	// generate links
 	span.Links().EnsureCapacity(len(tmpl.links))
 	for _, l := range tmpl.links {
@@ -530,6 +537,20 @@ func (g *TemplatedGenerator) initializeSpan(idx int, parent *internalSpanTemplat
 	}
 	span.attributes = util.MergeMaps(defaults.Attributes, tmpl.Attributes)
 
+	// set status
+	if tmpl.Status != nil {
+		var status ptrace.StatusCode
+		switch *tmpl.Status {
+		case "error":
+			status = ptrace.StatusCodeError
+		case "ok":
+			status = ptrace.StatusCodeOk
+		case "unset":
+			status = ptrace.StatusCodeUnset
+		}
+		span.status = &status
+	}
+
 	// set span name
 	if tmpl.Name != nil {
 		span.name = *tmpl.Name

From ac44497905e41b0951b7f8afeb7b724d173bcd61 Mon Sep 17 00:00:00 2001
From: Joe Elliott <number101010@gmail.com>
Date: Wed, 28 Aug 2024 15:57:37 -0400
Subject: [PATCH 2/2] percentage of span

Signed-off-by: Joe Elliott <number101010@gmail.com>
---
 pkg/tracegen/templated.go | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/pkg/tracegen/templated.go b/pkg/tracegen/templated.go
index 522fd07..44e6810 100644
--- a/pkg/tracegen/templated.go
+++ b/pkg/tracegen/templated.go
@@ -107,6 +107,8 @@ type Link struct {
 type Event struct {
 	// Name of event
 	Name string `js:"name"`
+	// PercentageOfSpan if set controls where in the span the event is generated. If missing, the event is generated randomly
+	PercentageOfSpan float32 `js:"percentageOfSpan"`
 	// Attributes for this event
 	Attributes map[string]interface{} `js:"attributes"`
 	// Generate random attributes for this event
@@ -181,6 +183,7 @@ type internalLinkTemplate struct {
 
 type internalEventTemplate struct {
 	rate             float32
+	percentageOfSpan float32
 	exceptionOnError bool
 	name             string
 	attributes       map[string]interface{}
@@ -314,7 +317,13 @@ func (g *TemplatedGenerator) generateSpan(scopeSpans ptrace.ScopeSpans, tmpl *in
 		event.Attributes().EnsureCapacity(len(e.attributes) + len(e.randomAttributes))
 
 		event.SetName(e.name)
-		eventTime := start.Add(random.Duration(0, duration))
+
+		var eventTime time.Time
+		if e.percentageOfSpan > 0 {
+			eventTime = start.Add(time.Duration(float64(duration) * float64(e.percentageOfSpan)))
+		} else {
+			eventTime = start.Add(random.Duration(0, duration))
+		}
 		event.SetTimestamp(pcommon.NewTimestampFromTime(eventTime))
 
 		for k, v := range e.attributes {
@@ -658,6 +667,7 @@ func (g *TemplatedGenerator) initializeEvents(tmplEvents []Event, randomEvents,
 		event := internalEventTemplate{
 			name:             e.Name,
 			attributes:       e.Attributes,
+			percentageOfSpan: e.PercentageOfSpan,
 			randomAttributes: initializeRandomAttributes(e.RandomAttributes),
 		}
 		internalEvents = append(internalEvents, event)