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

blog(add article): how to contribute to the otel demo #3671

Conversation

adnanrahic
Copy link
Contributor

This PR adds an article that explains:

  1. How to demystify OpenTelemetry by adding automatic and manual code
    instrumentation.
  2. How to use trace-based testing in the OpenTelemetry Demo to maintain feature
    functionality and telemetry integrity.
  3. How to contribute to the OpenTelemetry Demo safely while avoiding
    regressions.

@adnanrahic adnanrahic requested review from a team December 11, 2023 15:37
@svrnm svrnm added the blog label Dec 12, 2023
Copy link
Member

@svrnm svrnm left a comment

Choose a reason for hiding this comment

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

Thank you for suggesting this blog post, @adnanrahic. I appreciate the effort that you took to write it down, however there are some major concerns I have with the current form, I outlined them in my review comments already, but to summarize:

  • The blog post suggest that it teaches you how to contribute to the otel demo, I don't see anything in the blog post around creating a PR, committing it, interacting with the community etc.
  • The blog post makes unnecessary use of tracetest. Since tracetest is oss, there are cases where it can be used (like in https://opentelemetry.io/blog/2023/testing-otel-demo/), but it doesn't fit the title and content of the blog post. Please make use of Jaeger.
  • The blog post is very long, so I made a lot of suggestions around reducing the size, mainly to skip a major part at the beginning explaining the demo, and that you start with a fork without the instrumentation and work from there.

Comment on lines +15 to +290

[ Output ]
docker compose run traceBasedTests payment-service
[+] Creating 21/0
✔ Container jaeger Running 0.0s
✔ Container kafka Running 0.0s
✔ Container tracetest-postgres Running 0.0s
✔ Container postgres Running 0.0s
✔ Container redis-cart Running 0.0s
✔ Container feature-flag-service Running 0.0s
✔ Container otel-col Running 0.0s
✔ Container currency-service Running 0.0s
✔ Container cart-service Running 0.0s
✔ Container payment-service Running 0.0s
✔ Container tracetest-server Running 0.0s
✔ Container quote-service Running 0.0s
✔ Container accounting-service Running 0.0s
✔ Container frauddetection-service Running 0.0s
✔ Container product-catalog-service Running 0.0s
✔ Container ad-service Running 0.0s
✔ Container email-service Running 0.0s
✔ Container recommendation-service Running 0.0s
✔ Container shipping-service Running 0.0s
✔ Container checkout-service Running 0.0s
✔ Container frontend Running 0.0s
[+] Running 3/3
✔ Container postgres Healthy 0.5s
✔ Container kafka Healthy 0.5s
✔ Container tracetest-postgres Healthy 0.5s
Starting tests...

Running trace-based tests...

✔ Payment Service (http://tracetest-server:11633/testsuite/payment-service-all/run/2)
✔ Payment: valid credit card (http://tracetest-server:11633/test/payment-valid-credit-card/run/2/test) - trace id: 7774d4754957e5fa5b916e4d6d5880e7
✔ It should call Charge method successfully
✔ It should return a transaction ID
✔ It should return a valid credit card
✔ Payment: invalid credit card (http://tracetest-server:11633/test/payment-invalid-credit-card/run/2/test) - trace id: a20c1d166cd6edf4d8f288e407e76623
✔ It should call Charge method and receive a gRPC error
✔ It should return a return an gRPC error code to the caller
✔ Payment: Amex credit card not allowed (http://tracetest-server:11633/test/payment-amex-credit-card-not-allowed/run/2/test) - trace id: a5812bf50ac61a387dc991ba0dd3020a
✔ It should call Charge method and receive a gRPC error
✔ It should return a return an gRPC error code to the caller
✔ Payment: expired credit card (http://tracetest-server:11633/test/payment-expired-credit-card/run/2/test) - trace id: fecb6368104b0fc27e7806136fc1ab1c
✔ It should call Charge method and receive a gRPC error
✔ It should return a return an gRPC error code to the caller

Tests done! Exit code: 0
```

You can also start the Tracetest services alongside all the Core Demo Services,
Dependent Services, and Telemetry Components as part of your development
lifecycle to enable
[Observability-driven Development (ODD)](https://stackoverflow.blog/2022/10/12/how-observability-driven-development-creates-elite-performers/).
Mainly to trigger your APIs and validate both the response and trace data they
generate. You can also build tests visually and save them as YAML files to add
to your code repository for automated testing. I’ll walk you through all of this
a bit later as well.

To do this, you’ll use the `odd`
[Docker Compose profile](https://docs.docker.com/compose/profiles/). Run the
demo like this:

```bash
docker compose --profile odd up --force-recreate --remove-orphans --detach

# OR

make start-odd
```

Go ahead and start the OpenTelemetry Demo including Tracetest, with the `odd`
profile.

Once the images are built and containers are started you can access:

- Web store: [http://localhost:8080/](http://localhost:8080/)
- Grafana: [http://localhost:8080/grafana/](http://localhost:8080/grafana/)
- Feature Flags
UI: [http://localhost:8080/feature/](http://localhost:8080/feature/)
- Load Generator
UI: [http://localhost:8080/loadgen/](http://localhost:8080/loadgen/)
- Jaeger
UI: [http://localhost:8080/jaeger/ui/](http://localhost:8080/jaeger/ui/)
- Tracetest UI: [http://localhost:11633/](http://localhost:11633/), only when
using `make start-odd`

To run a test against the Payment Service, I’ll use a YAML file and trigger it
with the
[Tracetest CLI](https://docs.tracetest.io/getting-started/installation#install-the-tracetest-cli).
Alternatively, you can also build tests visually in the Tracetest UI
on [http://localhost:11633/](http://localhost:11633/).

> _Here’s a
> [short guide on how to create tests programatically](https://docs.tracetest.io/getting-started/open#creating-trace-based-tests-programatically)
> with Tracetest._

Next, let’s move on to explaining and adding code instrumentation in the
`paymentservice`.
Copy link
Member

Choose a reason for hiding this comment

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

Can all of this be replaced with a reference to https://opentelemetry.io/docs/demo/ ? It duplicates a lot of words from there

Comment on lines +294 to +301
I’ve prepared a fork with detailed code examples and three demos. This will help
you understand how to add OpenTelemetry code instrumentation.

```bash
git clone https://github.com/kubeshop/opentelemetry-demo.git
cd opentelemetry-demo/
make start-odd
```
Copy link
Member

Choose a reason for hiding this comment

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

how is this fork different from upstream, when I follow that link I get This branch is up to date with open-telemetry/opentelemetry-demo:main., also I would prefer you to use your personal github and not your org github for such a fork

Comment on lines +306 to +358
```jsx
// src/paymentservice/opentelemetry.js

const opentelemetry = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-grpc');
const {
OTLPMetricExporter,
} = require('@opentelemetry/exporter-metrics-otlp-grpc');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const {
alibabaCloudEcsDetector,
} = require('@opentelemetry/resource-detector-alibaba-cloud');
const {
awsEc2Detector,
awsEksDetector,
} = require('@opentelemetry/resource-detector-aws');
const {
containerDetector,
} = require('@opentelemetry/resource-detector-container');
const { gcpDetector } = require('@opentelemetry/resource-detector-gcp');
const {
envDetector,
hostDetector,
osDetector,
processDetector,
} = require('@opentelemetry/resources');

const sdk = new opentelemetry.NodeSDK({
// OTLPTraceExporter() uses the env var "OTEL_EXPORTER_OTLP_ENDPOINT" when not explicitly set.
traceExporter: new OTLPTraceExporter(),
instrumentations: [getNodeAutoInstrumentations()],
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter(),
}),
resourceDetectors: [
containerDetector,
envDetector,
hostDetector,
osDetector,
processDetector,
alibabaCloudEcsDetector,
awsEksDetector,
awsEc2Detector,
gcpDetector,
],
});
sdk.start();
```
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 make this (and other) code examples a little bit compacter? I think you can write more things in one line than you do it in the original code

Comment on lines +426 to +440
I’ll walk you through these three demos, with one sample without telemetry.

1. **Demo 0**: What’s it like without OpenTelemetry traces?
2. **Demo 1**: Get the active span from the context and use it as the main span
in the `chargeServiceHandler` .
3. **Demo 2**: Get the active span from the context to create a new context.
Create a new span for the `chargeServiceHandler` and pass the new context in
as a parameter.
4. **Demo 3**: Create a new active span for the `chargeServiceHandler` without
the need to pass a parent span and context.

But first, let’s make it harder! It’s easy to get started when somebody is
holding your hand. Let’s remove the guardrails for a second. Literally, let’s
remove the OpenTelemetry instrumentation and run some API tests to see what
happens.
Copy link
Member

Choose a reason for hiding this comment

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

This belongs to the very top of the blog post, you should explain people what they are going to do. It's promised that they learn how to contribute, but the core of the blog post starts here.


Without the `opentelemetry.js` file that contains auto instrumentation,
triggering the `paymentservice/charge` API endpoint will result in no traces
showing up. Let’s reproduce this by running an API test with Tracetest. First,
Copy link
Member

Choose a reason for hiding this comment

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

Let me be frank: to me it feels unnecessary to use Tracetest here. It totally makes sense on the tracetest blog, it also makes sense to talk about tracetest in the previous blog post https://opentelemetry.io/blog/2023/testing-otel-demo/, but this blog post is titled "How to contribute to the otel demo", so stick to that topic, aka use Jaeger for visualization

Comment on lines +447 to +448
I’ll comment out all the content in the `opentelemetry.js` file. Then, comment
out all the OpenTelemetry-specific code in the `index.js` and `charge.js`.
Copy link
Member

Choose a reason for hiding this comment

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

Since you ask people above to take the code from a fork, this would be a place where you can shorten your blog post significantly. Make a version without the instrumentation and let people add it back in.

Comment on lines +1020 to +1021
3. How to contribute to the OpenTelemetry Demo safely while avoiding
regressions.
Copy link
Member

Choose a reason for hiding this comment

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

where did I learn that? I would have expected some words around raising a PR, etc

@adnanrahic
Copy link
Contributor Author

Thanks a lot for the very detailed review @svrnm !! 🙌

You make great points. 🤝

I've summarized a todo list to work on:

  • Add a dedicated section about creating a PR, committing it, and interacting with the community.
  • Add Jaeger to the use case for trace visualization instead of Tracetest.
  • Shorten the overall length of the article.
  • Use the upstream repo (open-telemetry/opentelemetry-demo:main) as the base for explanations. Note: I used the fork because some features were not yet merged into upstream at the time of writing. That can be changed now since they are merged.)
  • Use a fork in my personal GitHub account without instrumentation as the starting point of the tutorial and work from there.
  • Move the Demo X. list of what the reader will learn to the top of the article.
  • Make code blocks more compact and easy to read.
  • Replace the make start section with a reference to https://opentelemetry.io/docs/demo/ since there is a lot of content duplication.

@svrnm
Copy link
Member

svrnm commented Dec 13, 2023

* [ ]  Add a dedicated section about creating a PR, committing it, and interacting with the community.

That or you rename your blog post to something more fitting

* [ ]  Add Jaeger to the use case for trace visualization instead of Tracetest.

Exactly, since this is mainly about tracing, if you need something for metrics take prometheus

* [ ]  Shorten the overall length of the article.

Yes. And also try to keep the number of topics in the blog post "low". Right now there is a variety of things, that are only semi-related to the topic. Make cuts where possible.

* [ ]  Use the upstream repo (`open-telemetry/opentelemetry-demo:main`) as the base for explanations. _Note: I used the fork because some features were not yet merged into upstream at the time of writing. That can be changed now since they are merged.)_

You can use your fork throughout the doc if it adds value, but don't send people to a fork that in sync with upstream.

* [ ]  Use a fork in my personal GitHub account without instrumentation as the starting point of the tutorial and work from there.

Exactly, ideally you put things in a special branch, since you might want to work with the demo in the future still.

* [ ]  Move the `Demo X.` list of what the reader will learn to the top of the article.

Don't see this as a purely mechanical advice: this is the core of what you are talking about in this blog post, think about how you can lead with that and what is not part of that can be removed.

* [ ]  Make code blocks more compact and easy to read.

Yes.

* [ ]  Replace the `make start` section with a reference to `https://opentelemetry.io/docs/demo/` since there is a lot of content duplication.

Keep the things that are necessary for the flow of the blog, but otherwise point to the docs, yes.

@svrnm
Copy link
Member

svrnm commented Jan 12, 2024

@adnanrahic any updates?

@adnanrahic
Copy link
Contributor Author

Hey @svrnm!
Apologies for the delay on my end. I got accepted for a conference presentation and will get back to writing a new version of this once it is off my plate. 😬
We are clear on the tasks, it's just up to me to get the free time. 🙌

Copy link
Contributor

@chalin chalin left a comment

Choose a reason for hiding this comment

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

Drive-by comment that this post will need a copyedit pass or two once the major rework has landed. /cc @theletterf

@svrnm
Copy link
Member

svrnm commented Jan 29, 2024

Apologies for the delay on my end. I got accepted for a conference presentation and will get back to writing a new version of this once it is off my plate. 😬

Thanks, I'll close this PR for now and you can raise a new one whenever you are ready! This makes it easier for us maintainers to keep all the open PRs visible.

@svrnm svrnm closed this Jan 29, 2024
@adnanrahic
Copy link
Contributor Author

Sounds good. Sorry for the delay. I should be able to pick it back up next week since my conf presentation is this weekend. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants