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

Support template paths as part of span names for go versions >= 1.22 #740

Merged
merged 17 commits into from
May 1, 2024

Conversation

RonFed
Copy link
Contributor

@RonFed RonFed commented Mar 27, 2024

In go v1.22 the net/http package added support for pattern handlers https://go.dev/blog/routing-enhancements.
This allows us to add a low cardinality path for span names in http server.
There were a few discussions about this topic (one of them in #627), and I think this solution allows for a much more informative span name while keeping it with low cardinality.

  • Change the span name to {method} {http.route} when a route is available.
  • Added the http.route attribute when the path template is available.
  • Update the net/http e2e test to use a path template.

@RonFed RonFed marked this pull request as ready for review March 28, 2024 13:40
@RonFed RonFed requested a review from a team March 28, 2024 13:40
Copy link
Contributor

@damemi damemi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this LGTM, just want to double check this line from semconv:

Instrumentation MUST NOT default to using URI path as span name, but MAY provide hooks to allow custom logic to override the default span name.

I think what this is doing would count as "providing hooks" (using the option consts) rather than defaulting to using the path. But, our instrumentation agent will be using that hook by default. @MrAlias does this seem right or does that line mean this should be behind some non-default option for the agent?

CHANGELOG.md Outdated Show resolved Hide resolved
internal/pkg/instrumentation/bpf/net/http/http_event.go Outdated Show resolved Hide resolved
internal/pkg/inject/offset_results.json Show resolved Hide resolved
internal/pkg/inject/offset_results.json Show resolved Hide resolved
@MrAlias
Copy link
Contributor

MrAlias commented Apr 5, 2024

this LGTM, just want to double check this line from semconv:

Instrumentation MUST NOT default to using URI path as span name, but MAY provide hooks to allow custom logic to override the default span name.

I think what this is doing would count as "providing hooks" (using the option consts) rather than defaulting to using the path. But, our instrumentation agent will be using that hook by default. @MrAlias does this seem right or does that line mean this should be behind some non-default option for the agent?

This seems correct to me given it will only ever use a templatized path. The hooks are there when a templitized version of this is not available in the language, but is something the user could provide.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 5, 2024

For those also interested to see how this handles non-exact matches: https://go.dev/play/p/9ZZz4BjTQ6C

@damemi
Copy link
Contributor

damemi commented Apr 5, 2024

this LGTM, just want to double check this line from semconv:

Instrumentation MUST NOT default to using URI path as span name, but MAY provide hooks to allow custom logic to override the default span name.

I think what this is doing would count as "providing hooks" (using the option consts) rather than defaulting to using the path. But, our instrumentation agent will be using that hook by default. @MrAlias does this seem right or does that line mean this should be behind some non-default option for the agent?

This seems correct to me given it will only ever use a templatized path. The hooks are there when a templitized version of this is not available in the language, but is something the user could provide.

Ah so URI Path in that section of semconv is referring to the full non-templatized path. Makes sense thanks 👍

@RonFed
Copy link
Contributor Author

RonFed commented Apr 9, 2024

@MrAlias Can you please have another look?

@MrAlias
Copy link
Contributor

MrAlias commented Apr 9, 2024

@MrAlias Can you please have another look?

We talked about this PR in the SIG meeting today. I'm hesitant to merge this without the offsets generator being fixed.

If I understand this correctly, if a user is using a version of Go prior to 1.22 the offsets will be "found" and the instrumentation loaded, but that offset is invalid an the system would fail to handle it.

I would not want to include this in the instrumentation without first having correct offsets.

@RonFed
Copy link
Contributor Author

RonFed commented Apr 9, 2024

@MrAlias Can you please have another look?

We talked about this PR in the SIG meeting today. I'm hesitant to merge this without the offsets generator being fixed.

If I understand this correctly, if a user is using a version of Go prior to 1.22 the offsets will be "found" and the instrumentation loaded, but that offset is invalid an the system would fail to handle it.

I would not want to include this in the instrumentation without first having correct offsets.

The following part should make sure that if we instrument an app with go version lower than 1.22 the pattern parts are not taken into account (we won't consider the offsets in eBPF if we are not detecting a valid version), hence I think it should not necessarily block this PR.

type patternPathSupportedConst struct{}

var (
	patternPathMinVersion  = version.Must(version.NewVersion("1.22.0"))
	isPatternPathSupported = false
)

func (c patternPathSupportedConst) InjectOption(td *process.TargetDetails) (inject.Option, error) {
	isPatternPathSupported = td.GoVersion.GreaterThanOrEqual(patternPathMinVersion)
	return inject.WithKeyValue("pattern_path_supported", isPatternPathSupported), nil
}

@RonFed RonFed mentioned this pull request Apr 13, 2024
@MrAlias MrAlias closed this in #781 Apr 24, 2024
@RonFed RonFed reopened this Apr 24, 2024
@MrAlias
Copy link
Contributor

MrAlias commented Apr 24, 2024

Ah! I couldn't find this. Guess closing the other PR closed this. Thanks for reopening. I'll try to review this next.

@RonFed
Copy link
Contributor Author

RonFed commented Apr 25, 2024

Not sure why the offsets action is failing with "msg"="failed get offsets" "error"="Error response from daemon: No such image: golang:1.14.1"

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Not sure why the offsets action is failing with "msg"="failed get offsets" "error"="Error response from daemon: No such image: golang:1.14.1"

That is strange. The image does appear to still exist: https://hub.docker.com/layers/library/golang/1.14.1/images/sha256-23405c683ba88dffcb1493c66305533bb5b3cef179e419e2e5c2f5cb92a06891?context=explore

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

This seems unique to this PR. The auto-offset-gen action still works fine: https://github.com/open-telemetry/opentelemetry-go-instrumentation/actions/runs/8850141574/job/24303716999

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

I tried reproducing the failure locally, but was unsuccessful. I even deleted the local golang:1.14.1 image but it still succeeded. This looks unique to the action.

I'm wondering if there is some caching we can clear.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Yikes. Looks like there is no space left on the device(?)

2024/04/26 16:11:56 inspector/builder: "level"=1 "msg"="pulling image" "image"="golang:1.14.1" "output"="{"status":"Pulling from library/golang","id":"1.14.1"}\r\n{"status":"Already exists","progressDetail":{},"id":"f15005b0235f"}\r\n{"status":"Already exists","progressDetail":{},"id":"41ebfd3d2fd0"}\r\n{"status":"Already exists","progressDetail":{},"id":"b998346ba308"}\r\n{"status":"Already exists","progressDetail":{},"id":"f01ec562c947"}\r\n{"status":"Already exists","progressDetail":{},"id":"c5e092b8639b"}\r\n{"status":"Pulling fs layer","progressDetail":{},"id":"6ee82bba3116"}\r\n{"status":"Pulling fs layer","progressDetail":{},"id":"3b36b05a8864"}\r\n{"status":"Downloading","progressDetail":{"current":126,"total":126},"progress":"[==================================================\u003e] 126B/126B","id":"3b36b05a8864"}\r\n{"status":"Verifying Checksum","progressDetail":{},"id":"3b36b05a8864"}\r\n{"status":"Download complete","progressDetail":{},"id":"3b36b05a8864"}\r\n{"status":"Downloading","progressDetail":{"current":531698,"total":123632532},"progress":"[\u003e ] 531.7kB/123.6MB","id":"6ee82bba3116"}\r\n{"status":"Downloading","progressDetail":{"current":10180900,"total":123632532},"progress":"[====\u003e ] 10.18MB/123.6MB","id":"6ee82bba3116"}\r\n{"status":"Downloading","progressDetail":{"current":123632532,"total":123632532},"progress":"[==================================================\u003e] 123.6MB/123.6MB","id":"6ee82bba3116"}\r\n{"errorDetail":{"message":"write /var/lib/docker/tmp/GetImageBlob3791904830: no space left on device"},"error":"write /var/lib/docker/tmp/GetImageBlob3791904830: no space left on device"}\r\n"

https://github.com/MrAlias/opentelemetry-go-instrumentation/actions/runs/8851119331/job/24306956117?pr=237

I bumped the logging verbosity to show this.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Guessing this comes down to the fact that we are having to check all the old versions of Go for the new symbols added here. Prior to this we used to just hit the cache for all the symbols and never pulled the Go images.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Guessing this comes down to the fact that we are having to check all the old versions of Go for the new symbols added here. Prior to this we used to just hit the cache for all the symbols and never pulled the Go images.

Guessing we're going to need to add a "hint" to the offset manifests about what minimum version the symbol was added in.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Guessing this comes down to the fact that we are having to check all the old versions of Go for the new symbols added here. Prior to this we used to just hit the cache for all the symbols and never pulled the Go images.

Guessing we're going to need to add a "hint" to the offset manifests about what minimum version the symbol was added in.

#799

Going to try and resolve this later today.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

@RonFed
Copy link
Contributor Author

RonFed commented Apr 26, 2024

Guessing this comes down to the fact that we are having to check all the old versions of Go for the new symbols added here. Prior to this we used to just hit the cache for all the symbols and never pulled the Go images.

Yeah, that makes sense.

@RonFed RonFed#1

That looks to resolve the "out of space" issue: https://github.com/MrAlias/opentelemetry-go-instrumentation/actions/runs/8852585249/job/24311585805?pr=237

Do you think we should use this as a quick fix or add some generic logic to the cache lookup?

For general solution I think that if for a given module the minimal version is vModMin and some field in that module has cache entries starting from version vFieldMin and vFieldMin > vModMin we won't consider the versions smaller than vFieldMin

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

For general solution I think that if for a given module the minimal version is vModMin and some field in that module has cache entries starting from version vFieldMin and vFieldMin > vModMin we won't consider the versions smaller than vFieldMin

This would mean that patch releases to prior minor/major versions would not be evaluated. I don't think that is the correct approach.

@RonFed
Copy link
Contributor Author

RonFed commented Apr 26, 2024

For general solution I think that if for a given module the minimal version is vModMin and some field in that module has cache entries starting from version vFieldMin and vFieldMin > vModMin we won't consider the versions smaller than vFieldMin

This would mean that patch releases to prior minor/major versions would not be evaluated. I don't think that is the correct approach.

Right. Another idea is to add "null" offsets to the cache for versions where there is no valid offset. It makes sense to cache the evaluation of no valid offset in a given version, but it will make the offset file much bigger.

@MrAlias
Copy link
Contributor

MrAlias commented Apr 26, 2024

Right. Another idea is to add "null" offsets to the cache for versions where there is no valid offset. It makes sense to cache the evaluation of no valid offset in a given version, but it will make the offset file much bigger.

That sounds reasonable to me. It would be a bit harder for a human to read, but that's not critical if we can solve #26

@MrAlias MrAlias merged commit 88e2702 into open-telemetry:main May 1, 2024
17 checks passed
@MrAlias MrAlias added this to the v0.12.0-alpha milestone Jun 4, 2024
@MrAlias MrAlias mentioned this pull request Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants