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

[SVLS-4142] Create a cold start span only when a cold start has not already occurred #22202

Merged
merged 26 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
381f812
create a Lambda span on timeouts
DylanLovesCoffee Dec 11, 2023
831dab7
don't create a cold start span when the runtime restarts during timeouts
DylanLovesCoffee Dec 11, 2023
45c8d83
Merge branch 'main' into dylan/timeout-trace
DylanLovesCoffee Dec 11, 2023
2200b76
fix linting
DylanLovesCoffee Dec 11, 2023
a9ec6a7
fix test
DylanLovesCoffee Dec 11, 2023
71ee55f
lint: rename name variables
DylanLovesCoffee Dec 11, 2023
eb04b12
lint again
DylanLovesCoffee Dec 11, 2023
68632e3
small fixes
DylanLovesCoffee Dec 13, 2023
6c6ce1c
refactor timeout span logic
DylanLovesCoffee Dec 21, 2023
7299681
Merge branch 'main' into dylan/timeout-trace
DylanLovesCoffee Dec 21, 2023
bf23790
add mutexes
DylanLovesCoffee Jan 2, 2024
3cc6e87
Merge branch 'main' into dylan/timeout-trace
DylanLovesCoffee Jan 5, 2024
3f9bf0d
Merge branch 'main' into dylan/timeout-trace
DylanLovesCoffee Jan 8, 2024
65e7c20
fix span completed check
DylanLovesCoffee Jan 8, 2024
f1e2857
revert refactor
DylanLovesCoffee Jan 8, 2024
12eb913
remove cold start span changes
DylanLovesCoffee Jan 9, 2024
4f0543f
use mutex over rwmutex
DylanLovesCoffee Jan 9, 2024
24712f0
test routes
DylanLovesCoffee Jan 9, 2024
05a6392
add comment + update tests
DylanLovesCoffee Jan 10, 2024
2b48fe1
test endExecutionSpan
DylanLovesCoffee Jan 10, 2024
5d27996
add serverless.go test
DylanLovesCoffee Jan 10, 2024
70cbf83
add test /hello for route
DylanLovesCoffee Jan 10, 2024
73b9a88
prevent additional cold start spans from being created after runtime …
DylanLovesCoffee Jan 19, 2024
1642e90
fix merge conflict
DylanLovesCoffee Apr 22, 2024
d31dd3b
fix bad conflict merge
DylanLovesCoffee Apr 22, 2024
2f9e6fb
fix test
DylanLovesCoffee Apr 22, 2024
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
1 change: 1 addition & 0 deletions cmd/serverless/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ func runAgent() {
TraceAgent: serverlessDaemon.TraceAgent,
StopChan: make(chan struct{}),
ColdStartSpanId: coldStartSpanId,
ColdStartRequestID: serverlessDaemon.ExecutionContext.GetCurrentState().ColdstartRequestID,
}

log.Debug("Starting ColdStartSpanCreator")
Expand Down
10 changes: 9 additions & 1 deletion pkg/serverless/trace/cold_start_span_creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ColdStartSpanCreator struct {
initDuration float64
StopChan chan struct{}
initStartTime time.Time
ColdStartRequestID string
}

//nolint:revive // TODO(SERV) Fix revive linter
Expand Down Expand Up @@ -143,7 +144,14 @@ func (c *ColdStartSpanCreator) create() {
Type: "serverless",
}

c.createSpan.Do(func() { c.processSpan(coldStartSpan) })
c.createSpan.Do(func() {
// An unexpected shutdown will reset this sync.Once counter, so we check whether a cold start has already occurred
if len(c.ColdStartRequestID) > 0 {
log.Debugf("[ColdStartCreator] Cold start span already created for request ID %s", c.ColdStartRequestID)
return
}
c.processSpan(coldStartSpan)
})
}

func (c *ColdStartSpanCreator) processSpan(coldStartSpan *pb.Span) {
Expand Down
59 changes: 59 additions & 0 deletions pkg/serverless/trace/cold_start_span_creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,65 @@ func TestColdStartSpanCreatorNotColdStart(t *testing.T) {
assert.Equal(t, true, timedOut)
}

func TestColdStartSpanCreatorColdStartExists(t *testing.T) {
setupTraceAgentTest(t)

cfg := config.New()
cfg.GlobalTags = map[string]string{}
cfg.Endpoints[0].APIKey = "test"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
agnt := agent.NewAgent(ctx, cfg, telemetry.NewNoopCollector(), &statsd.NoOpClient{})
traceAgent := &ServerlessTraceAgent{
ta: agnt,
}
coldStartDuration := 50.0 // Given in millis
lambdaSpanChan := make(chan *pb.Span)
lambdaInitMetricChan := make(chan *serverlessLog.LambdaInitMetric)
initReportStartTime := time.Now().Add(-1 * time.Second)
lambdaInitMetricDuration := &serverlessLog.LambdaInitMetric{
InitDurationTelemetry: coldStartDuration,
}
lambdaInitMetricStartTime := &serverlessLog.LambdaInitMetric{
InitStartTime: initReportStartTime,
}
stopChan := make(chan struct{})
coldStartSpanID := random.Random.Uint64()
coldStartSpanCreator := &ColdStartSpanCreator{
TraceAgent: traceAgent,
LambdaSpanChan: lambdaSpanChan,
LambdaInitMetricChan: lambdaInitMetricChan,
ColdStartSpanId: coldStartSpanID,
StopChan: stopChan,
ColdStartRequestID: "test",
}

coldStartSpanCreator.Run()
defer coldStartSpanCreator.Stop()

lambdaSpan := &pb.Span{
Service: "aws.lambda",
Name: "aws.lambda",
Start: time.Now().Unix(),
TraceID: random.Random.Uint64(),
SpanID: random.Random.Uint64(),
ParentID: random.Random.Uint64(),
Duration: 500,
}
lambdaSpanChan <- lambdaSpan
lambdaInitMetricChan <- lambdaInitMetricDuration
lambdaInitMetricChan <- lambdaInitMetricStartTime
timeout := time.After(time.Millisecond)
timedOut := false
select {
case ss := <-traceAgent.ta.TraceWriter.In:
t.Fatalf("created a coldstart span when we should have passed, %v", ss)
case <-timeout:
timedOut = true
}
assert.Equal(t, true, timedOut)
}

func TestColdStartSpanCreatorCreateValidProvisionedConcurrency(t *testing.T) {
setupTraceAgentTest(t)

Expand Down
Loading