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

feat: add used build plugins and their versions to exec-build span #5584

Merged
merged 1 commit into from
Apr 22, 2024

Conversation

pieh
Copy link
Contributor

@pieh pieh commented Apr 5, 2024

Summary

We are currently unable to create SLO in honeycomb that target just Next Runtime v5 to capture overall build error rates with it.

We do have individual build steps annotated with plugin name and version that is being executed, but we can't join exec-build span with those to extract needed information. This PR adds information about used Build Plugins to exec-build by adding 1 span attribute per plugin with name containing plugin name and value being its version to be able to filter exec-build by specific plugins (and their versions).

This will allow queries like below to be able to create actual SLO and alerting
image

Related to https://linear.app/netlify/issue/FRA-367/update-build-time-metrics
Relevant slack discussion: https://netlify.slack.com/archives/C031MPNJWK1/p1712068846389239

Comment on lines 466 to 472
if (execBuildSpan && pluginsOptionsA?.length) {
for (const plugin of pluginsOptionsA) {
if (plugin?.pluginPackageJson?.name) {
execBuildSpan.setAttribute(
`build.plugins['${plugin.pluginPackageJson.name}']`,
plugin?.pluginPackageJson?.version ?? 'N/A',
)
}
}
}

Copy link
Contributor Author

@pieh pieh Apr 5, 2024

Choose a reason for hiding this comment

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

There is a bit of argument drilling to make sure we set those attributes on exec-build span (instead of using something like active span) so this doesn't accidentally start putting this attributes on other spans as we do want to ensure those are on exec-build.

I'm not sure if it's possible to have plugin name without actual version, so 'N/A' is just fallback to ensure the plugin is at least logged even if we didn't manage to get its version.

build.plugins['<plugin-name>'] is just something that made some sense initially to me, but if there is better semantic name to use - I'm more than happy to adjust.

Similarly if there is maybe other approach that could be used instead of those individual attributes with ['<plugin-name>'] syntax that you think is better that will still allow us to filter spans for @netlify/plugin-nextjs with version above or equal 5 - also happy to adjust it

Copy link
Contributor

Choose a reason for hiding this comment

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

make sure we set those attributes on exec-build span (instead of using something like active span) so this doesn't accidentally start putting this attributes on other spans as we do want to ensure those are on exec-build.

Ah missed this bit before creating - #5587. Sorry about that. I wonder though if there's other alternative besides passing the span all the way down 😬 I'm affraid of creating an anti pattern here.

The way contexts are setup for JS otel is really annoying in this sense 😞

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can use something like AsyncLocalStorage directly (same thing that powers OTEL's active span tracking), but just put exec-build span on it directly and get access to it this way without "argument drilling".

I'm not sure if there are features in (JS) OTEL API / packages / helpers that could maybe allow us to use something like that with "first-class otel citizen" approach

Copy link
Contributor

Choose a reason for hiding this comment

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

Nevertheless I think we should be good to just tap into wtv the active span is here.

If your biggest concern is that we may end up changing the span here leading your query (being filtered by exec-build) to comeback empty in terms of build.plugins we could instead create a specific span here which could:

  • Have a well known name to y'all, making sure the span you most rely on suddently doesn't change.
  • Passing the over the plugins options as baggage to the child spans, so that way we could even ensure we could filter other spans by these new properties

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://opentelemetry.io/docs/languages/js/context/ is potentially OTEL abstraction for AsyncLocalStorage (or other async_hooks) that might do that, but I'm not sure if we don't use it in some way where this could be problematic. We could add exec-build and create new derived context so that all descendent spans could get exec-build span from it, but we might use context already to propagate other kind of data so it might mess with that (i.e. - would this mess with something like this

return context.with(getGlobalContext(), async () => {
)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just come clarification here as well - all those attributes don't necessarily need to land exec-build span - we can use anything else but the actual requirement is that whatever span we use need to have build status (success / failure) and ideally build error "location"/"type" (so for example we can rule out failed builds because user's build command failed because of user error and only track build/deploy errors that in some way were possibly caused by Next runtime doing something wrong - either directly in their build step or possibly producing problematic function that later failed to bundle/upload etc).

exec-build seems to be the span that always have build status and build errors (location/type) attributes on it and hence this was used as target for new attributes in this PR. It also seem like only span today that wrap entire build with all its steps so at least now it seem to be only span that fit the requirements, but creating new span could work too (tho it feels it will have similar "challenges" as exec-build with either argument drilling or trying to use async_hooks in some way - either directly or via OTEL ContextManager, so that doesn't seem to solve the problem to me (?) )

Alternatively entire assumption that all the attributes need to be on the same span is wrong and we can do some kind of "joins" in honeycomb to find traces that has some attributes/values on one span and then other attributes/values on other span, but I couldn't find anything like that and only filtering I was able to achieve was about attribute combination on same span.

@pieh pieh marked this pull request as ready for review April 5, 2024 11:35
@pieh pieh requested review from a team as code owners April 5, 2024 11:35
Copy link
Contributor

@JGAntunes JGAntunes left a comment

Choose a reason for hiding this comment

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

Left a comment in here, but something else we need to be aware of is changing the coventional commit prefix here so this triggers a release.

@pieh
Copy link
Contributor Author

pieh commented Apr 8, 2024

Left a comment in here, but something else we need to be aware of is changing the coventional commit prefix here so this triggers a release.

Should this be feat? I wasn't clear on how to classify OTEL adjustments, so went with "safe" chore, but happy to adjust

@lukasholzer
Copy link
Contributor

lukasholzer commented Apr 8, 2024

Should this be feat? I wasn't clear on how to classify OTEL adjustments, so went with "safe" chore, but happy to adjust

yep needs to be a feat a chore does not trigger a release and we need to release it to update the npm package inside buildbot

@pieh pieh force-pushed the add-plugins-and-versions-attributes-to-exec-span branch from 67160b1 to 90446fa Compare April 9, 2024 09:26
@pieh pieh changed the title chore: add used build plugins and their versions to exec-build span feat: add used build plugins and their versions to exec-build span Apr 9, 2024
@pieh
Copy link
Contributor Author

pieh commented Apr 9, 2024

I pushed change to use activeSpan.

Not sure wether using utility from #5587 would be preferable? If so I can maybe cherry-pick that in here (or maybe retarget PR to get access to it before it's merged)

PR is now using util from #5587 (now merged)

@pieh pieh force-pushed the add-plugins-and-versions-attributes-to-exec-span branch from 90446fa to bf55141 Compare April 22, 2024 15:33
@pieh pieh merged commit 0be6927 into main Apr 22, 2024
34 checks passed
@pieh pieh deleted the add-plugins-and-versions-attributes-to-exec-span branch April 22, 2024 17:21
This was referenced Jun 26, 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