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 UI tracing #2608

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Add UI tracing #2608

wants to merge 8 commits into from

Conversation

MAX-786
Copy link

@MAX-786 MAX-786 commented Jan 22, 2025

Which problem is this PR solving?

Resolves #1307

Description of the changes

  • Lets you enable tracing the 'jaeger-ui' itself.

Additional step to fix CORS error (for now):

You have to run docker image of jaeger-all-in-one (if that's what you are using) with following options:

 docker run -d --rm --name jaeger   -p 16686:16686   -p 4318:4318   -e COLLECTOR_OTLP_ENABLED=true   -e COLLECTOR_OTLP_HTTP_CORS_ALLOWED_ORIGINS="http://localhost:5173"   -e COLLECTOR_OTLP_HTTP_CORS_ALLOWED_HEADERS="Content-Type"   jaegertracing/all-in-one:latest

Demo

  1. Run your collector.
    For example, we can use jaeger-all-in-one docker image which includes jaeger-collector and I am setting explicitly, allowed CORS origins/headers (see the above bash command).
  2. Run Jaeger UI.
    You can send traces from jaeger UI to your collector via config. You can checkout more here. Like for sending UI traces to jaeger-collector you can use following config:
"tracing": {
      "endpoint": "http://localhost:4138/v1/traces",
      "serviceName": "jaeger-ui"
  }

By default it is disabled and it's default config are as follows:

// ... rest config  
tracing: {
      endpoint: '', // Disabled by default
      serviceName: 'jaeger-ui',
  },

Demo below, click here and there and see the traces show up in jaeger-ui.

2025-01-23.19-54-25.mp4

How was this change tested?

  • still testing

Checklist

@MAX-786
Copy link
Author

MAX-786 commented Jan 22, 2025

Hey @yurishkuro ,
sorry :) for coming back to you so late (got stuck in academic stuff) but here i am and back to the point, I opened a draft PR and as you guessed we require additional CORS settings for now.
And I am also looking into a way to turn on/off tracing jaeger-ui.


try {
const exporter = new OTLPTraceExporter({
url: 'http://localhost:4318/v1/traces', // why relative URL doesn't work? '/v1/traces' ???
Copy link
Member

Choose a reason for hiding this comment

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

this doesn't address my main concerns in #1627. Why localhost? If I deploy Jaeger in production and access as jaeger.mycompany.com, what does localhost have to do with the destination for traces?

Copy link
Author

@MAX-786 MAX-786 Jan 22, 2025

Choose a reason for hiding this comment

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

@yurishkuro hmm I tried with multiple ways to make it work with relative path and then proxying it where ever jaeger exits, i was configuring proxy in vite.config.mts something like :

server: {
  proxy: {

    '/v1/traces': {
      target: 'http://localhost:4318',  // OTLP endpoint
      secure: false,
      changeOrigin: true, 
    },
  },
},

But then in opentelemetry.ts it gets stuck at exporting which results in blocking react to render anything... I might be doing something wrong perhaps.
I am still thinking what you mean here (comment). When you said we need UI config option, means like there should something in UI itself or in the codebase like above we got vite.config.tmts where operator can configure .
hmmm let me look deeper ig or anything you want to add ?

Copy link
Member

Choose a reason for hiding this comment

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

Jaeger UI is historically served by jaeger-query binary that is mostly a read-only service, but it does have an internal tracing that could be configured via OTEL env vars to send the data to another service (by default it sends to localhost which happens to work when running in all-in-one mode). When the UI part involves its own tracing, it needs to export the data. The question is where.

Option 1: to an external URL, e.g. a jaeger-collector running somewhere. This was the approach in the previous PR where the endpoint was configurable and passed to the UI, except that it wasn't passed using the right mechanism #1627 (comment). This will work as long as the collector is set up with a correct CORS policy.

Option 2: UI can export data back into query-service via a dedicated endpoint, e.g. we could mount an OTLP receiver in the query-service as well. This avoids any cross-site issues but requires a lot more implementation to support this endpoint and then somehow export the data elsewhere.

I would recommend going with option 1. It just means we need to have a configuration option in the UI config where the user can specify the OTLP endpoint to export the data.

I am adding it to the issue description.

MAX-786 and others added 2 commits January 23, 2025 02:03
@MAX-786
Copy link
Author

MAX-786 commented Jan 23, 2025

This was the approach in the previous PR where the endpoint was configurable and passed to the UI, except that it wasn't passed using the right mechanism

Looked for standard way of using configs and also implemented type for tracing config.
Now, what operators need to do is just give endpoint of where they want to send traces via configs (can set serviceName optionally ) otherwise it's disable by default.
Is this the way you were looking for? as option 1

@yurishkuro yurishkuro changed the title Trace jaeger UI Add UI tracing Jan 23, 2025
Copy link
Member

@yurishkuro yurishkuro left a comment

Choose a reason for hiding this comment

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

lgtm. Two open questions:

  • did you test it? please document the steps in the description and include screenshots of captured traces
  • how we can test this automatically? for example, we could run jaeger in a container and the UI separately via npm run start, load some UI pages and validate that traces are stored in jaeger. But I am not sure how to "load some UI pages", do we need to run some headless browser with JS support?

packages/jaeger-ui/package.json Outdated Show resolved Hide resolved
packages/jaeger-ui/src/types/config.tsx Outdated Show resolved Hide resolved
@MAX-786
Copy link
Author

MAX-786 commented Jan 23, 2025

I'll try to answer your questions with best of my knowledge so..

  • did you test it? please document the steps in the description and include screenshots of captured traces

Yes, I should've done it earlier my mistake.

  • how we can test this automatically? for example, we could run jaeger in a container and the UI separately via npm run start, load some UI pages and validate that traces are stored in jaeger

hmm... yes that's exactly what i shown in above demo but..

I am not sure how to "load some UI pages", do we need to run some headless browser with JS support?

one thing we can do is click on certain links and buttons and see if it's exporting traces to collector or not? and for loading some UI pages part, wouldn't rendering components would trigger documentLoad traces?

Btw in the last commit i set a check, so the file is not loaded if tracing is disabled.

@MAX-786 MAX-786 marked this pull request as ready for review January 23, 2025 17:25
@MAX-786 MAX-786 requested a review from a team as a code owner January 23, 2025 17:25
@MAX-786 MAX-786 requested review from jkowall and removed request for a team January 23, 2025 17:25
@yurishkuro
Copy link
Member

one thing we can do is click on certain links and buttons and see if it's exporting traces to collector or not? and for loading some UI pages part, wouldn't rendering components would trigger documentLoad traces?

we can test manually, my question was about automated testing during CI. For example, what if something changes in OTEL about how instrumentation is supposed to be initialize, like an extra step that we're not doing, how would our CI tests catch that?

Regarding the screencast you uploaded, is it correct that all UI-produced traces only have UI service in them? I was expecting something that actually spans UI and server, given that the server also captures traces.

Copy link

codecov bot commented Jan 23, 2025

Codecov Report

Attention: Patch coverage is 0% with 13 lines in your changes missing coverage. Please review.

Project coverage is 96.45%. Comparing base (2159753) to head (deadda1).

Files with missing lines Patch % Lines
packages/jaeger-ui/src/opentelemetry.ts 0.00% 8 Missing ⚠️
packages/jaeger-ui/src/index.jsx 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2608      +/-   ##
==========================================
- Coverage   96.61%   96.45%   -0.17%     
==========================================
  Files         255      256       +1     
  Lines        7745     7758      +13     
  Branches     1937     1939       +2     
==========================================
  Hits         7483     7483              
- Misses        262      275      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@MAX-786
Copy link
Author

MAX-786 commented Jan 23, 2025

we can test manually, my question was about automated testing during CI. For example, what if something changes in OTEL about how instrumentation is supposed to be initialize, like an extra step that we're not doing, how would our CI tests catch that?

Hmm, I know that unit tests can check if the setup code is correctly structured. Maybe we can write tests that verify if all necessary components are initialized. Like checking if the WebTracerProvider is created, if the exporter is set up with the right URL, and if the span processors and instrumentations are added. We could mock the OpenTelemetry modules and see if the right functions are called. Also, maybe integration tests that start a test collector and see if traces are actually sent when the UI interacts. That way, if OTEL changes something, the tests would fail if our code doesn't adapt.

Regarding the screencast you uploaded, is it correct that all UI-produced traces only have UI service in them? I was expecting something that actually spans UI and server, given that the server also captures traces.

yes, right now UI service only only track client-side browser activities.

@yurishkuro
Copy link
Member

yes, right now UI service only only track client-side browser activities.

can you elaborate why that is? If activities like Click initiate a trace and result in a backend request, the UI should be able to pass the trace context to that request such that the server side spans will be in the same trace. This was my main motivation for this ticket in the first place, otherwise I don't think the UI tracing is particularly useful.

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.

[Fun task]: Add React tracing
2 participants