-
Notifications
You must be signed in to change notification settings - Fork 979
feat: add provisioning timings to understand slow build times #14274
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
7e36010
Initial implementation
dannykopping 45b7fb4
More hacking, now including a job-wide view of timings
dannykopping 38c4197
API
dannykopping 803a9d4
Smol refactor
dannykopping 973ec6d
Capture dependency graph timings
dannykopping a070e07
Expand hash to include span category so multiple operations on the sa…
dannykopping 4a29b96
Tests
dannykopping 275bfca
lint/fmt
dannykopping 73bac3f
Moar tests
dannykopping 3d77c63
Improve coverage
dannykopping c0ae1ba
Remove stats API call, will follow up in another PR
dannykopping 28fa2f7
Fixing tests
dannykopping 68b16ff
Use max(end)-min(start) as stage timings, not local maximum
dannykopping 6f0b8f8
make fmt
dannykopping 724f139
Minor fix-ups
dannykopping c30a900
Pls god let this work
dannykopping 0d68e69
Move terraform test helpers into internal package
dannykopping 15282bb
Review comments
dannykopping 82ca13e
Merge branch 'main' of github.com:coder/coder into dk/provision-detai…
dannykopping 597ec85
More CI happiness
dannykopping 805c0f2
Restrict timings tests to non-Windows
dannykopping 46f3318
Give CI exactly what it wants FFS (see https://github.com/coder/coder…
dannykopping ebbaf31
@mtojek you legend :)
dannykopping eb5ec5c
Merge branch 'main' of https://github.com/coder/coder into dk/provisi…
dannykopping File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Smol refactor
Signed-off-by: Danny Kopping <danny@coder.com>
- Loading branch information
commit 803a9d47458f62f1b5398d80d43c9fdf968c4b6e
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,6 @@ import ( | |
"go.opentelemetry.io/otel/attribute" | ||
"golang.org/x/xerrors" | ||
|
||
"github.com/coder/coder/v2/coderd/database" | ||
"github.com/coder/coder/v2/coderd/tracing" | ||
"github.com/coder/coder/v2/provisionersdk/proto" | ||
) | ||
|
@@ -36,6 +35,8 @@ type executor struct { | |
// cachePath and workdir must not be used by multiple processes at once. | ||
cachePath string | ||
workdir string | ||
// used to capture execution times at various stages | ||
timings *timingAggregator | ||
} | ||
|
||
func (e *executor) basicEnv() []string { | ||
|
@@ -254,8 +255,7 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l | |
args = append(args, "-var", variable) | ||
} | ||
|
||
timingsAgg := newTimingsAggregator(database.ProvisionerJobTimingStagePlan) | ||
outWriter, doneOut := e.provisionLogWriter(logr, timingsAgg) | ||
outWriter, doneOut := e.provisionLogWriter(logr) | ||
errWriter, doneErr := logWriter(logr, proto.LogLevel_ERROR) | ||
defer func() { | ||
_ = outWriter.Close() | ||
|
@@ -277,7 +277,7 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l | |
Parameters: state.Parameters, | ||
Resources: state.Resources, | ||
ExternalAuthProviders: state.ExternalAuthProviders, | ||
Timings: timingsAgg.aggregate(), | ||
Timings: e.timings.aggregate(), | ||
}, nil | ||
} | ||
|
||
|
@@ -404,8 +404,7 @@ func (e *executor) apply( | |
getPlanFilePath(e.workdir), | ||
} | ||
|
||
timingsAgg := newTimingsAggregator(database.ProvisionerJobTimingStageApply) | ||
outWriter, doneOut := e.provisionLogWriter(logr, timingsAgg) | ||
outWriter, doneOut := e.provisionLogWriter(logr) | ||
errWriter, doneErr := logWriter(logr, proto.LogLevel_ERROR) | ||
defer func() { | ||
_ = outWriter.Close() | ||
|
@@ -433,7 +432,7 @@ func (e *executor) apply( | |
Resources: state.Resources, | ||
ExternalAuthProviders: state.ExternalAuthProviders, | ||
State: stateContent, | ||
Timings: timingsAgg.aggregate(), | ||
Timings: e.timings.aggregate(), | ||
}, nil | ||
} | ||
|
||
|
@@ -547,15 +546,15 @@ func readAndLog(sink logSink, r io.Reader, done chan<- any, level proto.LogLevel | |
// provisionLogWriter creates a WriteCloser that will log each JSON formatted terraform log. The WriteCloser must be | ||
// closed by the caller to end logging, after which the returned channel will be closed to indicate that logging of the | ||
// written data has finished. Failure to close the WriteCloser will leak a goroutine. | ||
func (e *executor) provisionLogWriter(sink logSink, timings *timingsAggregator) (io.WriteCloser, <-chan any) { | ||
func (e *executor) provisionLogWriter(sink logSink) (io.WriteCloser, <-chan any) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved these under the |
||
r, w := io.Pipe() | ||
done := make(chan any) | ||
|
||
go e.provisionReadAndLog(sink, r, timings, done) | ||
go e.provisionReadAndLog(sink, r, done) | ||
return w, done | ||
} | ||
|
||
func (e *executor) provisionReadAndLog(sink logSink, r io.Reader, timings *timingsAggregator, done chan<- any) { | ||
func (e *executor) provisionReadAndLog(sink logSink, r io.Reader, done chan<- any) { | ||
defer close(done) | ||
scanner := bufio.NewScanner(r) | ||
for scanner.Scan() { | ||
|
@@ -588,13 +587,13 @@ func (e *executor) provisionReadAndLog(sink logSink, r io.Reader, timings *timin | |
logLevel := convertTerraformLogLevel(log.Level, sink) | ||
sink.ProvisionLog(logLevel, log.Message) | ||
|
||
ts, te, err := extractTimingsEntry(log) | ||
ts, span, err := extractTimingSpan(log) | ||
if err != nil { | ||
e.logger.Debug(context.Background(), "failed to extract timings entry from log line", | ||
slog.F("line", log.Message), slog.Error(err)) | ||
} else { | ||
// Only ingest valid timings. | ||
timings.ingest(ts, te) | ||
e.timings.ingest(ts, span) | ||
} | ||
|
||
// If the diagnostic is provided, let's provide a bit more info! | ||
|
@@ -608,13 +607,13 @@ func (e *executor) provisionReadAndLog(sink logSink, r io.Reader, timings *timin | |
} | ||
} | ||
|
||
func extractTimingsEntry(log terraformProvisionLog) (time.Time, *timingsEntry, error) { | ||
func extractTimingSpan(log terraformProvisionLog) (time.Time, *timingSpan, error) { | ||
// Input is not well-formed, bail out. | ||
if log.Type == "" { | ||
return time.Time{}, nil, xerrors.Errorf("invalid type: %q", log.Type) | ||
} | ||
|
||
typ := logType(log.Type) | ||
typ := timingKind(log.Type) | ||
if !typ.Valid() { | ||
return time.Time{}, nil, xerrors.Errorf("invalid type: %q", log.Type) | ||
} | ||
|
@@ -624,9 +623,8 @@ func extractTimingsEntry(log terraformProvisionLog) (time.Time, *timingsEntry, e | |
// TODO: log | ||
ts = time.Now() | ||
dannykopping marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
ts = ts.UTC() | ||
|
||
return ts, &timingsEntry{ | ||
return ts, &timingSpan{ | ||
kind: typ, | ||
action: log.Hook.Action, | ||
provider: log.Hook.Resource.Provider, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.