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

Make jaeger-ui installable by npm #248

Closed
aljesusg opened this issue Sep 17, 2018 · 13 comments
Closed

Make jaeger-ui installable by npm #248

aljesusg opened this issue Sep 17, 2018 · 13 comments

Comments

@aljesusg
Copy link
Contributor

aljesusg commented Sep 17, 2018

Requirement - what kind of business use case are you trying to solve?

I am from Jaeger team and Kiali in RH.
Kiali is the UI for Istio, we are currently integrating the jaeger with some external links.

We want to collect the information provided by jaeger and the information of Kiali and show the relation to improve the tracing and observability of the service mesh so for example if we can show the component of the traceresults with our information, will be useful for the user.

Actually we have an external link to the full UI jaeger in tabs, our idea is contribute/improve the component to import them to our project from the jaeger UI for example the last 10 traces in our view using the component TraceTimelineViewer.

Problem - what in Jaeger blocks you from solving the requirement?

We can't integrate components of Jaeger UI So we are using external links to the Jaeger-UI in a new tabs.

Proposal - what do you suggest to solve the problem or improve the existing situation?

  1. Change the package.json to publish the releases
  2. Compile al build the components to export them
  3. Improve/contribute in the component

cc @jpkrohling @objectiser

@aljesusg aljesusg reopened this Sep 17, 2018
@yurishkuro
Copy link
Member

@tiffon thoughts?

@mtho11
Copy link

mtho11 commented Sep 18, 2018

It would be great to see these components published to npm so that others could use the jaeger-ui components directly in applications.

@saminzadeh
Copy link
Member

saminzadeh commented Sep 19, 2018

It would be great to see these components published to npm so that others could use the jaeger-ui components directly in applications.

+1. This would be nice as a component library.

A few initial ideas on how to approach this:

  • Stateless Components that take the standardized Trace object. You will responsible for providing the Trace object to the component.
import { TraceViewTimeline, TraceDAG } from '@jaegertracing/ui-kit';
import trace from './samples/my-jaeger-trace.json'

<TraceViewTimeline trace={trace} />
<TraceDAG trace={trace} customOverrides={...} />
  • React Provider Pattern (eg. Redux, Apollo GraphQL, etc). Similar to how SearchKit makes it easy to integrate with ElasticSearch. We could do something similar for the JaegerQuery API.
import { 
  TraceViewTimeline, 
  JaegerClient, 
  JaegerProvider, 
  JaegerRenderer 
} from '@jaegertracing/ui-kit';

// Init Jaeger client
const jaegerClient = new JaegerClient("http://my.jaeger.host.com")

const App = ()=> (
  <JaegerProvider jaegerClient={jaegerClient}>
    <Layout>
      <h2>My Trace</h2>

      // Predefined component
      <TraceViewTimeline traceId="e29208c2-bc23-11e8-a355-529269fb1459" />

      // Custom components via Render Props
      <JaegerRenderer traceId="e29208c2-bc23-11e8-a355-529269fb1459">
        {({ trace, loading }) => {
          if(loading) {
            return "Loading trace..."
          }

          return (
            //... do custom logic with trace here
          )
        }}
      </ JaegerRenderer>
    </Layout>
  </JaegerProvider>
)

ReactDOM.render(<App/>, document.getElementById('root'))

@tiffon
Copy link
Member

tiffon commented Sep 20, 2018

@aljesusg – Thanks for creating this ticket! This topic is actually something that is coming up for us, internally, as well.

The two main avenues for integration we've been exploring are either publishing React components or using iframes to create an embedded experience.

One drawback for wholesale publishing the React components, in their current form, is that when all of the components become public, their combined API becomes the API contract. That's a massive contract. So much so it would essentially become impossible to maintain backwards compatibility while making any significant changes to the UI.

So, if we go down the path of publishing React components, I think the approach outlined by @saminzadeh would make the API contract more manageable.

But, it'd be nice to get a sense of the current use-cases and to see what, concretely, needs to be supported.

Can you elaborate a bit on the types of integrations you have in mind?

@saminzadeh
Copy link
Member

One drawback for wholesale publishing the React components, in their current form, is that when all of the components become public, their combined API becomes the API contract. That's a massive contract.

@tiffon I agree with you here. The components in their current form were not built with a public API in mind and it could be a maintenance burden if we published them today.

@yurishkuro
Copy link
Member

Perhaps I'm missing something, but why do we need to publish ALL components instead of just the ones on the highest level?

@aljesusg
Copy link
Contributor Author

aljesusg commented Sep 21, 2018

But, it'd be nice to get a sense of the current use-cases and to see what, concretely, needs to be supported.

Can you elaborate a bit on the types of integrations you have in mind?

@tiffon we want to integrate the trace search UI and allow navigation to the trace instance view, allowing the integrating app to supplied some initial search criteria. I think these components are
SearchResults of a service. Thanks

aljesusg added a commit to aljesusg/jaeger-ui that referenced this issue Sep 24, 2018
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
aljesusg added a commit to aljesusg/jaeger-ui that referenced this issue Sep 24, 2018
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
aljesusg added a commit to aljesusg/jaeger-ui that referenced this issue Sep 24, 2018
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
aljesusg added a commit to aljesusg/jaeger-ui that referenced this issue Sep 25, 2018
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
aljesusg added a commit to aljesusg/jaeger-ui that referenced this issue Sep 25, 2018
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
@yurishkuro
Copy link
Member

@aljesusg I see you're creating PRs, but we have not agreed to what approach we want to take. I completely agree with @tiffon that we do not want to explore the public API surface of React components. If we still want to publish some embeddable components, I would prefer to design them from scratch, ie define a narrow interface and implement it with the existing components treating the latter as internal/private. It will allow us to change them freely without affecting the public facade.

Can we start with defining the API? Or even better, listing your specific requirements for embedding. Maybe they can be satisfied with embedding an iframe.

@aljesusg
Copy link
Contributor Author

Yes @yurishkuro, sorry I saw later that you used nbw to create the plexus package, so I learned about and I redo the package, my idea was help you in this. About your comment I agree with you so I'll wait until your decision, It will be cleaner if it is done separately in another repo.

@tiffon
Copy link
Member

tiffon commented Sep 26, 2018

@aljesusg, if we take a step back and evaluate the intent of this ticket, it implies a paradigm shift for Jaeger.

At the heart of this ticket is establishing a new objective for Jaeger: empowering other product experiences through integrations with Jaeger UI.

Empowering other product experiences through integrations can either be in addition to providing an end-user experience (e.g. the current Jaeger UI), or it can supplant the current UI and integrations can become the sole focus of Jaeger UI.

Mapbox is an eample of focusing almost exclusively on integrations with other products.

Searchkit (searchkit.co, GitHub), which @saminzadeh mentioned, is an interesting second example. Searchkit is a set of UI components intended solely to empower other product experiences.

The approaches exemplified by Mapbox and Searchkit is not quite right for Jaeger UI – I don't think it's practical to focus only on integrations; Jaeger needs an end-user experience in order to meet the basic needs of a distributed tracing solution – people need to be able to consume traces.

Google Maps is an example of providing both an end-user experience and empowering other product experiences through integrations.

Google Maps has a highly effective end-user experience (IMO) and integrations with Google Maps are all over the place (over 1,000,000 websites as of 2013). And, we can safely say integrations are also a first-class aspect of the product as the Google Maps API dates to four months after the product's launch in 2005.

One of the fundamental considerations for integrations is the API contract. The downside of publishing the current UI components, wholesale, is that it would create an API contract that is impossible to maintain. This is because the underlying implementation and the API contract are one and the same.

Using Google Maps as an exemplar, we can take a look at their approach for decoupling their API contract from the underlying implementation of the product.

Google Maps has a massive API, but it's very abstracted from the underlying implementation. They provide a JavaScript SDK (among others) which avails JS classes to create and manage map views. The JS classes generate and interface with an iframe, but the developer is not concerned with the iframe; they work only with the JS classes provided by the SDK.

So far, I'd say this approach would be a good fit for Jaeger UI.

A brief look at two Google Maps APIs

Maps has a number of APIs (overview), three are relevant to JS:

Embed API

The embed API is an iframe based approach using query parameters to customize the view. The ability to customize is pretty limited:

  • Highlight an address
  • Show search results (e.g. provide a string query)
  • Show driving directions (see below)
  • Show a panorama or street view
  • Show a map of an area

Code to embed driving directions:

<iframe
	width="600" height="450" frameborder="0" style="border:0"
	src="https://www.google.com/maps/embed/v1/directions?origin=1400%20Broadway%2C%20New%20York%2C%20NY&destination=636%20West%2028th%20Street%2C%20New%20York%2C%20NY&key=YOUR_API_KEY"
	allowfullscreen
></iframe>

The crux of the embed approach is "create it and forget about it" – You pass in query parameters and you're done.

JavaScript SDK

The JS SDK is very extensive (looks like 109 symbols) with a wide variety of customization options. Users can add markers, clusters of markers, generate a heatmap, use something called Fusion Tables, draw on the map, etc. The API reference.

The SDK is a JavaScript file, hosted on Google servers, which is included in the page via a <script> tag. It takes a few query parameters which are used by the file to hook into the page, e.g. &callback=initMap where initMap is a JS function in the global scope. The file also populates JS classes into the global scope, name-spaced on window.google.maps.*. These classes can then be used to customize the creation and management of the map view.

The JS SDK generates and interfaces with an iframe. This is nice because the consumer can create the map and then later modify and manipulate it, through the SDK API.

A code snippet using this API:

  <body>
    <div id="map"></div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          zoom: 2,
          center: {lat: -33.865427, lng: 151.196123},
          mapTypeId: 'terrain'
        });

        // Create a <script> tag and set the USGS URL as the source.
        var script = document.createElement('script');

        // This example uses a local copy of the GeoJSON stored at
        // http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
        script.src = 'https://developers.google.com/maps/documentation/javascript/examples/json/earthquake_GeoJSONP.js';
        document.getElementsByTagName('head')[0].appendChild(script);

      }

      function eqfeed_callback(results) {
        var heatmapData = [];
        for (var i = 0; i < results.features.length; i++) {
          var coords = results.features[i].geometry.coordinates;
          var latLng = new google.maps.LatLng(coords[1], coords[0]);
          heatmapData.push(latLng);
        }
        var heatmap = new google.maps.visualization.HeatmapLayer({
          data: heatmapData,
          dissipating: false,
          map: map
        });
      }
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
  </body>
  • The initMap function

    • Initializes the map, centered on a lat, long
    • Loads a data file which is hardcoded (for the example) to call a global function with the data
  • The eqfeed_callback function

    • Converts the data as required by the maps API
    • Adds a heatmap to the map created in initMap

@jpkrohling
Copy link
Contributor

I think GitLab is also planning on doing something with Jaeger's UI, they may want to get aware of this issue :)

/cc @SuperQ

@lambertjosh
Copy link

Thanks @jpkrohling for the heads up on this. We've been looking for ways to best integrate the Jaeger UI, similar to Kiali, and this would be a great help.

I'd vote for the API route, as it would be more broadly adoptable than a React component. For example at GitLab we use Vue.

@aljesusg
Copy link
Contributor Author

I think that we can close this in favor #279

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

No branches or pull requests

7 participants