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

Add autoinstrumentation of NodeJS #507

Merged
merged 20 commits into from
Nov 10, 2021

Conversation

anuraaga
Copy link
Contributor

@anuraaga anuraaga commented Nov 5, 2021

@anuraaga anuraaga requested review from a team and bogdandrutu November 5, 2021 08:00
@anuraaga anuraaga marked this pull request as draft November 5, 2021 08:00
@anuraaga
Copy link
Contributor Author

anuraaga commented Nov 5, 2021

I think this is basically code complete for a first version, I will add docs but want to confirm the approach for supporting multiple languages. I went with a language annotation as it seemed the most straight forward among a few options I thought of such as changing the language specs to pointers and apply all specs that are defined (assuming there should only be one in practice). But let me know if this makes sense or of any better ideas.

Also this is my first significant change - I was able to verify things fine with a normal app on minikube, but currently when I run USE_EXISTING_CLUSTER make test I get many cgo-type of undecipherable crashes (maybe because of MacOS Monterey?) so will need to figure out how to check those.

@jpkrohling
Copy link
Member

I'm really excited about this one, thank you for the PR!

There are a couple of tests failing:

=== RUN   TestMutatePod/missing_language
    podmutator_test.go:450: 
        	Error Trace:	podmutator_test.go:450
        	Error:      	Received unexpected error:
        	            	instrumentation.opentelemetry.io/language must be set to the desired SDK language
        	Test:       	TestMutatePod/missing_language
=== RUN   TestMutatePod/missing_annotation
=== RUN   TestMutatePod/annotation_set_to_false
=== RUN   TestMutatePod/annotation_set_to_non_existing_instance
    podmutator_test.go:453: 
        	Error Trace:	podmutator_test.go:453
        	Error:      	"instrumentation.opentelemetry.io/language must be set to the desired SDK language" does not contain "instrumentations.opentelemetry.io \"doesnotexists\" not found"
        	Test:       	TestMutatePod/annotation_set_to_non_existing_instance
--- FAIL: TestMutatePod (0.07s)
    --- PASS: TestMutatePod/javaagent_injection,_true (0.03s)
    --- PASS: TestMutatePod/nodejs_injection,_true (0.01s)
    --- FAIL: TestMutatePod/missing_language (0.00s)
    --- PASS: TestMutatePod/missing_annotation (0.01s)
    --- PASS: TestMutatePod/annotation_set_to_false (0.01s)
    --- FAIL: TestMutatePod/annotation_set_to_non_existing_instance (0.00s)

As the original author of the auto-instrumentation for Java, I'll let @pavolloffay review this one.

@jpkrohling jpkrohling requested review from pavolloffay and removed request for bogdandrutu November 5, 2021 09:04
Copy link
Member

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

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

I would like to know why the annotations changes. Could you do this change in a separate PR?

@@ -23,15 +23,16 @@ import (
const (
// annotationInjectJava indicates whether java auto-instrumentation should be injected or not.
// Possible values are "true", "false" or "<Instrumentation>" name.
annotationInjectJava = "instrumentation.opentelemetry.io/inject-java"
Copy link
Member

Choose a reason for hiding this comment

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

can you explain the intentions for changing this annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I'm happy to split out the annotation change if it makes sense.

I found our current, SDK-agnostic (?) sdk.go uses this Java annotation. I need it to be able to support multiple languages and came up with this change. Any idea that could work better?

Copy link
Member

Choose a reason for hiding this comment

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

Could you please explain why we need two annotations?

We can have "instrumentation.opentelemetry.io/inject-java", "instrumentation.opentelemetry.io/inject-node" and then `"instrumentation.opentelemetry.io/inject" - to just inject the basic configuration (users could use the operator as a control plane to manage instrumentations).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we want to allow multiple languages on the same pod as that shouldn't ever be a use case I think. While we could check the annotations and fail if there are multiple this split seemed to model more directly that only one language can be injected.

I made language required without thinking too much but could definitely remove that to allow the control plane only injection if this otherwise makes sense.

Copy link
Member

Choose a reason for hiding this comment

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

I don't see much value of limiting it to only a single language, quite the opposite.

What I don't like is to have two annotations from the UX perspective.

	annotationInject   = "instrumentation.opentelemetry.io/inject"
	annotationLanguage = "instrumentation.opentelemetry.io/language"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe these sort of annotations are always copy-pasted or frameworked, so I don't think there is a usability difference between the two patterns. If we think there is a use case for multiple annotations, then it makes sense but for example having both otel.inject=true and otel.inject-java=true on the same pod would be redundant and I think that leads to some cognitive dissonance.

Great to hear everyone's ideas on the matter :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed with @pavolloffay offline and for now sticking to the current annotation format, but we'll need to address it soon. We can see the awkwardness here

https://github.com/open-telemetry/opentelemetry-operator/pull/507/files#diff-92f790ce871022e5e7de195a2f96235dac6ac3fb04337974f8584c7c020a67cbR48

where common config can be injected from different instrumentations in a surprising way. Having separate annotations for the instrumentation config and what languages to use in the future will hopefully solve that.

Copy link
Member

Choose a reason for hiding this comment

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

+1 let's discuss it in a separate issue. maybe there are other ways we can mitigate the issue

@anuraaga anuraaga force-pushed the nodejs-autoinstrumentatioon branch 2 times, most recently from bf8bc85 to 0636df0 Compare November 9, 2021 09:33
@anuraaga anuraaga force-pushed the nodejs-autoinstrumentatioon branch 2 times, most recently from 6e0ad24 to b36d889 Compare November 9, 2021 11:37
Anuraag Agrawal added 2 commits November 10, 2021 16:01
@anuraaga anuraaga marked this pull request as ready for review November 10, 2021 07:36
@anuraaga
Copy link
Contributor Author

Sorry for the churn - I filed a couple of issues for some of the challenges I run into while developing here. But this should finally be ready @pavolloffay @jpkrohling

README.md Outdated
- baggage
- b3
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pavolloffay I didn't document this image like you did in Java since I think it's too complicated to create oneself, at least unless someone asks for that.

Copy link
Member

Choose a reason for hiding this comment

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

I think, that is fine. I do not expect many people providing custom builds.

I hoped that vendors could use this operator with their agent distros in the future.

README.md Outdated

```yaml
kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
Copy link
Member

Choose a reason for hiding this comment

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

I think we should have only a single instrumentation CR in the readme and then have a bulletoints/section for each language with annotations.

Copy link
Contributor Author

@anuraaga anuraaga Nov 10, 2021

Choose a reason for hiding this comment

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

Tweaked the README - hoping to be able to follow up with additional doc nits in another PR since it's been a big struggle keeping up with merge conflicts.

Copy link
Member

Choose a reason for hiding this comment

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

Agree I had to rebase yesterday like 100k times

@@ -23,15 +23,16 @@ import (
const (
// annotationInjectJava indicates whether java auto-instrumentation should be injected or not.
// Possible values are "true", "false" or "<Instrumentation>" name.
annotationInjectJava = "instrumentation.opentelemetry.io/inject-java"
Copy link
Member

Choose a reason for hiding this comment

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

+1 let's discuss it in a separate issue. maybe there are other ways we can mitigate the issue

spec:
containers:
- name: myapp
image: ghcr.io/anuraaga/express-hello-world:latest
Copy link
Member

Choose a reason for hiding this comment

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

We should probably create an application that would call an API on our test apps (java, js) that would result in a trace.
Then report the trace to an inmemory storage and asser it exists (e.g. what we do in the java auto-instrumentation tests).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup think we will want this

README.md Outdated
EOF
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
EOF
Copy link
Member

Choose a reason for hiding this comment

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

there are empty spaces which should not be there

README.md Outdated
instrumentation.opentelemetry.io/inject-nodejs: "true"
```

The value can be
Copy link
Member

Choose a reason for hiding this comment

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

I think we should DRY this, the semantics for the annotation are the same for all languages, no need to repeat this.

README.md Outdated
```

The above CR can be queried by `kubectl get otelinst`.

1. Container image with [OpenTelemetry Java auto-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation). The image must contain the Java agent JAR `/javaagent.jar`, and the operator will copy it to a shared volume mounted to the application container.
Copy link
Member

Choose a reason for hiding this comment

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

Let's delete this and consider it as impl detail for now

@jpkrohling jpkrohling enabled auto-merge (squash) November 10, 2021 12:48
Copy link
Member

@jpkrohling jpkrohling left a comment

Choose a reason for hiding this comment

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

I'm approving based on @pavolloffay's approval.

@jpkrohling jpkrohling merged commit 15b2f70 into open-telemetry:main Nov 10, 2021
shree007 pushed a commit to shree007/opentelemetry-operator that referenced this pull request Dec 12, 2021
* Add autoinstrumentation of NodeJS

* Drift

* Switch to single annotation

* Fix merge

* Fix

* Hurts

* Format

* Revert autogen

* Drift

* Revert autogen

* autogen

* Drift

* Add doc

* e2e

* Less doc

* Cleanup
ItielOlenick pushed a commit to ItielOlenick/opentelemetry-operator that referenced this pull request May 1, 2024
* Add autoinstrumentation of NodeJS

* Drift

* Switch to single annotation

* Fix merge

* Fix

* Hurts

* Format

* Revert autogen

* Drift

* Revert autogen

* autogen

* Drift

* Add doc

* e2e

* Less doc

* Cleanup
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