Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weights now uses trace_id to pick a choice #44

Merged
merged 2 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased](https://github.com/lightstep/telemetry-generator/compare/v0.11.11...HEAD)
## [Unreleased](https://github.com/lightstep/telemetry-generator/compare/v0.11.12...HEAD)


## [0.11.12](https://github.com/lightstep/telemetry-generator/compare/v0.11.11...v0.11.12) - 2023-3-03
### Changed
* Weights the last two digits of a trace_id to generate their randomness.
* Errors are now propagated up to the parent span.

## [0.11.11](https://github.com/lightstep/telemetry-generator/compare/v0.11.10...v0.11.11) - 2023-3-02
### Fixed
* Fixed a bug where multiple traces were being created with the same trace_id and span_id.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ version for the 10 most recent telemetry-generator versions.

| Telemetry Generator | OpenTelemetry Collector |
|---------------------|-------------------------|
| v0.11.12 | v0.69.1 |
| v0.11.11 | v0.69.1 |
| v0.11.10 | v0.69.1 |
| v0.11.9 | v0.68.0 |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.11.11
0.11.12
13 changes: 9 additions & 4 deletions generatorreceiver/internal/generator/trace_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (g *TraceGenerator) createSpanForServiceRouteCall(traces *ptrace.Traces, se

resource.Attributes().PutStr(string(semconv.ServiceNameKey), serviceTier.ServiceName)

resourceAttributeSet := serviceTier.GetResourceAttributeSet()
resourceAttributeSet := serviceTier.GetResourceAttributeSet(traceId)
attrs := resource.Attributes()
resourceAttributeSet.GetAttributes().InsertTags(&attrs)

Expand All @@ -92,7 +92,7 @@ func (g *TraceGenerator) createSpanForServiceRouteCall(traces *ptrace.Traces, se
span.SetKind(ptrace.SpanKindServer)
span.Attributes().PutStr("load_generator.seq_num", fmt.Sprintf("%v", g.sequenceNumber))

ts := serviceTier.GetTagSet(routeName) // ts is single TagSet consisting of tags from the service AND route
ts := serviceTier.GetTagSet(routeName, traceId) // ts is single TagSet consisting of tags from the service AND route
attr := span.Attributes()
ts.Tags.InsertTags(&attr) // add service and route tags to span attributes

Expand All @@ -106,11 +106,16 @@ func (g *TraceGenerator) createSpanForServiceRouteCall(traces *ptrace.Traces, se
// TODO: this is still a bit weird - we're calling each downstream route
// after a sample of the current route's latency, which doesn't really
// make sense - but maybe it's realistic enough?
endTime := startTimeNanos + route.SampleLatency()
endTime := startTimeNanos + route.SampleLatency(traceId)
for _, c := range route.DownstreamCalls {
var childStartTimeNanos = startTimeNanos + route.SampleLatency()
var childStartTimeNanos = startTimeNanos + route.SampleLatency(traceId)

childSpan := g.createSpanForServiceRouteCall(traces, c.Service, c.Route, childStartTimeNanos, traceId, newSpanId)
val, ok := childSpan.Attributes().Get("error")
if ok {
errorAttr := span.Attributes().PutEmpty("error")
val.CopyTo(errorAttr)
}
endTime = Max(endTime, int64(childSpan.EndTimestamp()))
}

Expand Down
10 changes: 7 additions & 3 deletions generatorreceiver/internal/topology/latency_percentiles.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package topology

import (
"github.com/lightstep/telemetry-generator/generatorreceiver/internal/flags"
"math/rand"
"time"

"go.opentelemetry.io/collector/pdata/pcommon"

"github.com/lightstep/telemetry-generator/generatorreceiver/internal/flags"
)

type LatencyPercentiles struct {
Expand All @@ -21,6 +24,7 @@ type LatencyPercentiles struct {
p999 time.Duration
p100 time.Duration
}
EmbeddedWeight `json:",inline" yaml:",inline"`
flags.EmbeddedFlags `json:",inline" yaml:",inline"`
}

Expand Down Expand Up @@ -80,7 +84,7 @@ func (l *LatencyPercentiles) loadDurations() error {

type LatencyConfigs []*LatencyPercentiles

func (lcfg *LatencyConfigs) Sample() int64 {
func (lcfg *LatencyConfigs) Sample(traceID pcommon.TraceID) int64 {
var defaultCfg *LatencyPercentiles
var enabled []*LatencyPercentiles
for _, cfg := range *lcfg {
Expand All @@ -91,7 +95,7 @@ func (lcfg *LatencyConfigs) Sample() int64 {
}
}
if len(enabled) > 0 {
return enabled[rand.Intn(len(enabled))].Sample()
return pickBasedOnWeight(enabled, traceID).Sample()
}
return defaultCfg.Sample()
}
17 changes: 14 additions & 3 deletions generatorreceiver/internal/topology/pickable.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package topology

import "math/rand"
import (
"encoding/binary"

"go.opentelemetry.io/collector/pdata/pcommon"
)

type Pickable interface { // currently TagSet and ResourceAttributeSet satisfy this interface
GetWeight() float64
Expand All @@ -15,7 +19,7 @@ func (w EmbeddedWeight) GetWeight() float64 {
return w.Weight
}

func pickBasedOnWeight[P Pickable](ps []P) P {
func pickBasedOnWeight[P Pickable](ps []P, traceID pcommon.TraceID) P {
var activeSets []P
totalWeight := 0.0
for _, set := range ps {
Expand All @@ -25,7 +29,14 @@ func pickBasedOnWeight[P Pickable](ps []P) P {
}
}

choice := rand.Float64() * totalWeight
// Take out last 8 bytes from trace id
secondHalf := traceID[8:16]
// Transform them into a uint64
traceUint := binary.BigEndian.Uint64(secondHalf)
// Use the last two digits as percentage.
choice := float64(traceUint%100) / 100.0

choice = choice * totalWeight
current := 0.0
for _, set := range activeSets {
current += set.GetWeight()
Expand Down
6 changes: 4 additions & 2 deletions generatorreceiver/internal/topology/service_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"math/rand"

"go.opentelemetry.io/collector/pdata/pcommon"

"github.com/lightstep/telemetry-generator/generatorreceiver/internal/flags"
)

Expand Down Expand Up @@ -77,10 +79,10 @@ func (r *ServiceRoute) load(route string) error {
return nil
}

func (r *ServiceRoute) SampleLatency() int64 {
func (r *ServiceRoute) SampleLatency(traceID pcommon.TraceID) int64 {
if r.LatencyConfigs == nil {
return rand.Int63n(r.MaxLatencyMillis * 1000000)
} else {
return r.LatencyConfigs.Sample()
return r.LatencyConfigs.Sample(traceID)
}
}
12 changes: 7 additions & 5 deletions generatorreceiver/internal/topology/service_tier.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package topology

import (
"fmt"

"go.opentelemetry.io/collector/pdata/pcommon"
)

type ServiceTier struct {
Expand All @@ -12,9 +14,9 @@ type ServiceTier struct {
Metrics []Metric `json:"metrics" yaml:"metrics"`
}

func (st *ServiceTier) GetTagSet(routeName string) TagSet {
serviceTagSet := pickBasedOnWeight(st.TagSets)
routeTagSet := pickBasedOnWeight(st.GetRoute(routeName).TagSets)
func (st *ServiceTier) GetTagSet(routeName string, traceID pcommon.TraceID) TagSet {
serviceTagSet := pickBasedOnWeight(st.TagSets, traceID)
routeTagSet := pickBasedOnWeight(st.GetRoute(routeName).TagSets, traceID)

combinedTags := TagMap{}
for k, v := range serviceTagSet.Tags {
Expand All @@ -30,9 +32,9 @@ func (st *ServiceTier) GetTagSet(routeName string) TagSet {
}
}

func (st *ServiceTier) GetResourceAttributeSet() ResourceAttributeSet {
func (st *ServiceTier) GetResourceAttributeSet(traceID pcommon.TraceID) ResourceAttributeSet {
// TODO: also support resource attributes on routes
return pickBasedOnWeight(st.ResourceAttributeSets)
return pickBasedOnWeight(st.ResourceAttributeSets, traceID)
}

func (st *ServiceTier) GetRoute(routeName string) *ServiceRoute {
Expand Down