-
Notifications
You must be signed in to change notification settings - Fork 505
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
metrics: add build command duration metric #2225
Conversation
997c258
to
006b74d
Compare
|
||
import "golang.org/x/sys/windows" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I'll have to watch for that in the future. I didn't realize my IDE wasn't running goimports
on files that didn't match my build constraints.
99bea90
to
43ffe95
Compare
commands/build.go
Outdated
|
||
// getVCSPath returns the vcs:source attribute for a context path. | ||
func getVCSPath(contextPath string) string { | ||
var wd string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name should remain contextPath. Otherwise it is confusing why wd
is passed to git command.
commands/build.go
Outdated
return o.result | ||
} | ||
|
||
// getVCSPath returns the vcs:source attribute for a context path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is wrong as this does not share implementation with vcs:source
. Atm it would be "returns git remote URL". Rename the function as well as this isn't "Path".
commands/build.go
Outdated
func getVCSPath(contextPath string) string { | ||
var wd string | ||
if filepath.IsAbs(contextPath) { | ||
wd = contextPath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contextPath
in here can be -
or a URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getGitAttributes
function in build/git.go
doesn't seem to handle this case. Does that need to be fixed too? It seems to get passed these parameters directly.
This code will also just fail and ignore the error if the git commands don't succeed. Is that suitable or do we need to catch the URL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @crazy-max
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated this to include a Stat
call before the logic. That should catch any paths that don't make sense before we start to try running git commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contextPath
in here can be-
or a URL.
Hum right this was never checked when getting Git attributes.
commands/build.go
Outdated
@@ -279,6 +362,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) | |||
return err | |||
} | |||
|
|||
done := timeBuildCommand(mp, options.Attributes(dockerCli)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this (build)metricsAttributes(b, dockerCli, options) attribute.Set
.
Don't need options.newBuilder()
or other methods on options
.
Inside the function, read the b.Driver
directly from input without the struct/once. If you want then for the hash you can leave the lazy evaluation, but for just reading the driver property, there is no need for this overhead.
The call could also be inside timeBuildCommand
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the change. This isn't called inside of timeBuildCommand
as there's another section of code that's going to use these same attributes in another PR.
commands/build.go
Outdated
func timeBuildCommand(mp metric.MeterProvider, attrs attribute.Set) func(err error) { | ||
meter := metricutil.Meter(mp) | ||
counter, _ := meter.Float64Counter("command.time", | ||
metric.WithDescription("Measures the duration of the buildx command."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"build command" seems more appropriate as looks specific to that command atm.
commands/build.go
Outdated
|
||
// errorType returns an attribute for the error type based on the error category. | ||
// If nil, this function returns an invalid attribute. | ||
func errorType(err error) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
otelErrorType/metricsErrorType
maybe to make it clearer what "type" this is.
db17998
to
af1350b
Compare
func (o *buildOptionsHash) String() string { | ||
o.resultOnce.Do(func() { | ||
target := o.target | ||
contextPath := o.contextPath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These paths need to be normalized so they always generate same hash(Eg. made absolute).
As this is leaking the system paths and Git info it still needs the salt like #2185 (comment) . The multi-machine case doesn't apply anyway as system paths are different, and I don't think there is a way to implement it safely with some other way.
If the path is a URL then the URL should go into hash. If it is -
then maybe workdir is better than just const character? (but it needs salt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this code is in a new place, I don't have easy access to the node identifier anymore. I'd have to make that function public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've also now changed this so it will attempt to transform context path into a relative path. If a git directory is present, the relative path will be dependent on the root directory of the git repository.
commands/build.go
Outdated
func getGitRemoteURL(contextPath string) string { | ||
// Check if this is a valid path to begin with before attempting | ||
// to run git. It might be a non-filesystem URL. | ||
if _, err := os.Stat(contextPath); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should do the URL/- detection to match LoadInputs
and unless I'm missing something, same validation would need to be called for the vcs
codepath.
If you think this is outside of scope, then create a follow-up issue for it and assign to yourself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a look at LoadInputs
and it checks if the path is a local directory before checking for a URL. It seems to use this same code for that same functionality so I just exposed it and used that function instead. I've also included an explicit check for -
to avoid attempting to call stat on that path and to avoid performing this logic at all in those circumstances.
We'll only do git remote url detection when it's a local directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsternberg Looks good
555c4eb
to
3d93cd6
Compare
build/utils.go
Outdated
@@ -34,7 +34,7 @@ func IsRemoteURL(c string) bool { | |||
return false | |||
} | |||
|
|||
func isLocalDir(c string) bool { | |||
func IsLocalDir(c string) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move this to osutil
?
util/gitutil/gitutil.go
Outdated
func ToAbs(path string) string { | ||
if !filepath.IsAbs(path) { | ||
path, _ = filepath.Abs(filepath.Join(osutil.GetWd(), path)) | ||
} | ||
return SanitizePath(path) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be moved to osutil
as well but needs to move SanitizePath
there too, can be for a follow-up.
commands/build.go
Outdated
func getVCSPath(contextPath string) string { | ||
var wd string | ||
if filepath.IsAbs(contextPath) { | ||
wd = contextPath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contextPath
in here can be-
or a URL.
Hum right this was never checked when getting Git attributes.
commands/build.go
Outdated
func getGitRemoteURL(contextPath string) string { | ||
// Check if this is a valid path to begin with before attempting | ||
// to run git. It might be a non-filesystem URL. | ||
if _, err := os.Stat(contextPath); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsternberg Looks good
3d93cd6
to
a60f069
Compare
This PR is now also semi-dependent on this PR here: docker/cli#4875 At the current moment, we don't have a way of obtaining the alias that was used to launch buildx. That PR sets an environment variable so the plugin can find the original command name so we can include it in the metric. |
a60f069
to
8f88d0e
Compare
I've removed the section of this that's dependent on I don't want to prevent this PR from being merged while we hash that out so I've removed it. |
8f88d0e
to
c42265f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsternberg Check the windows CI
This adds a build duration metric for the build command with attributes related to the buildx driver, the error type (if any), and which options were used to perform the build from a subset of the options. This also refactors some of the utility methods used by the git tool to determine filepaths into its own separate package so they can be reused in another place. Also adds a test to ensure the resource is initialized correctly and doesn't error. The otel handler logging message is suppressed on buildx invocations so we never see the error if there's a problem with the schema url. It's so easy to mess up the schema url when upgrading OTEL that we need a proper test to make sure we haven't broken the functionality. Signed-off-by: Jonathan A. Sternberg <[email protected]>
c42265f
to
bda968a
Compare
Was missing an import on the Windows build because my setup doesn't auto perform imports for systems that aren't compiled on my platform (aka windows in this case). Fixed it by adding the correct import. I'll keep an eye out because some stuff got moved around and that commonly means imports get removed and readded in new places so hopefully there's no more missing areas. |
This adds a build duration metric for the build command with attributes
related to the buildx driver, the error type (if any), and which options
were used to perform the build from a subset of the options.