hypertrace-ui icon indicating copy to clipboard operation
hypertrace-ui copied to clipboard

Make Time Ranges Configurable on the Dashboard

Open suddendust opened this issue 4 years ago • 22 comments

Use Case

We would like to have configurable time ranges on the UI.

Proposal

The current UI gives the following options:

Screenshot 2021-07-09 at 11 12 21 AM

Our daily ingestion is > 2T/day. Given the huge amount of data, queries time-out for time ranges > 3 days. Our users are more likely to select a large time range declaratively than fill in a custom time range (for example, if I want to fetch data for last Sunday, I am much more likely to select "Last 1 week" than fill in the custom range). If these values are made configurable, we will have a greater control on our query patterns.

suddendust avatar Jul 09 '21 05:07 suddendust

cc : @itssharmasandeep @anandtiwary

kotharironak avatar Jul 09 '21 05:07 kotharironak

started working on this

jyothishjose6190 avatar Jul 26 '21 11:07 jyothishjose6190

Could you please propose a design on this? Given that there's no current user preference persistence, this may not be a good fit for work until prerequisites are put in place.

aaron-steinfeld avatar Jul 26 '21 11:07 aaron-steinfeld

This is my suggestion. By default, current time durations will be there, As an option Users can load their custom configuration from a file (JSON or something else). It will replace default time durations. Since we are not saving user preferences, it will not be saved for now. if you can suggest a better design, we can go with that.

jyothishjose6190 avatar Jul 26 '21 12:07 jyothishjose6190

This is my suggestion. By default, current time durations will be there, As an option Users can load their custom configuration from a file (JSON or something else). It will replace default time durations. Since we are not saving user preferences, it will not be saved for now. if you can suggest a better design, we can go with that.

Just to understand, are you imagining this config be provided in the image and loaded at runtime (affecting all users of the deployment), at build time (being resolved similarly to environment.ts), or as a session-long upload by a particular user?

aaron-steinfeld avatar Jul 26 '21 12:07 aaron-steinfeld

as a session-long upload by a particular user

jyothishjose6190 avatar Jul 26 '21 12:07 jyothishjose6190

as a session-long upload by a particular user

That seems like a pretty rough user experience - at that point, wouldn't the user be just as well configuring a custom range (or just changing the url, for that matter - e.g. replacing the time=1h query param with time=90m? I'm trying to understand the use case a little better where this would be a helpful change for a user.

As an alternative, which may be feasible, would be to create the "real" edit time ranges flow and give the user a full time range customization experience, but persist any changes into local storage for now, so they would be scoped to that user/browser, but at least persist across sessions. It would be a more involved change, for sure - since it would require building the editing/management experience, at least to some extent, but it would also set us up so we can just swap out the persistence layer with a backend implementation when we're ready for that. What do you think?

aaron-steinfeld avatar Jul 26 '21 12:07 aaron-steinfeld

You are suggesting edit for individual time ranges and persist any changes locally. right? sounds good

jyothishjose6190 avatar Jul 26 '21 15:07 jyothishjose6190

You are suggesting edit for individual time ranges and persist any changes locally. right? sounds good

I'm suggesting some work arounds that seem no more difficult than loading up a JSON file on each session to me from a user experience standpoint (but certainly far from ideal) - I think the right long term change is to have a full fledged management of time ranges, starting with some defaults (similar to how many applications allow creating and saving filters - another thing we need to add at some point). So in that world, I could add a new time range to my list, remove one, or edit an existing one. Eventually, we'd want such changes to be persisted to server disk, but we could start with storing it in the user's browser and seamlessly swap the storage provider when available. This is a significantly larger scope and requires a good bit of new UI that I don't think we have mocks or even wire frames for at the moment, though - but my larger point is that any change we make here should be in the direction of this ultimate goal, rather than some alternative we'd have to either support forever or break in the future.

aaron-steinfeld avatar Jul 26 '21 16:07 aaron-steinfeld

@aaron-steinfeld @jyothishjose6190 just to clarify why we raised this request:

  1. We want to control what options users see in the drop-down.
  2. This is to ensure that users are not indiscriminately selecting long time ranges because it's more convenient than filling in a custom range.
  3. Ideally, we would like the drop-down to have time range no longer than 3 days - Our access patterns show most of the queries lie in this range.
  4. So we want this drop-down to be configurable - If I want to remove the option of "Last 1 Month", I should be able to do that.

The proposed solution doesn't seem to be solving this problem. Please let us know what you think about this.

suddendust avatar Jul 27 '21 08:07 suddendust

@aaron-steinfeld @suddendust, I am suggesting, moving time range configurations to the environments. What is your opinion?

jyothishjose6190 avatar Jul 28 '21 04:07 jyothishjose6190

So the use case described by @suddendust is significantly different - instead of per user, its per tenant. Easy enough to do at build time (for all tenants across a deployment), but to do it at run time, it's basically as proposed with the config being saved at the tenant level rather than the user level. The real catch is that hypertrace does not yet have the concept of user permissions or roles, so until that's introduced, any user would be able to do this admin level action.

I am suggesting, moving time range configurations to the environments. What is your opinion?

Not sure I'm following - what do you mean by the environments?

aaron-steinfeld avatar Jul 29 '21 12:07 aaron-steinfeld

@aaron-steinfeld By "Easy enough to do at build time (for all tenants across a deployment)", you mean edit time ranges accordingly and deploy?

In angular, there are files called environment.prod.ts, environment.ts, etc. If a tenant wants its own configuration, it can create a separate environment file and load these configurations at the build time. I dont know its a recommended pattern that we follow here

jyothishjose6190 avatar Jul 29 '21 12:07 jyothishjose6190

So there's really a few places where config can happen:

  • At build time, when producing the docker image. This is more or less equivalent to a source code change/fork (this is what I had been referring to as at build time - and affects all tenants for that deployment).
  • At deploy time, when spinning up a docker image (either via helm or directly via docker/compose). We do this for example via helm values files for other services, but since the UI is static content, we don't really do any configuration in this way today. That said, it's technically possible if we either do some scripting on startup or load config files into the browser and apply them. I'm pretty hesitant to go down either path though, to be honest. This option would also affect all tenants of the deployment.
  • At run time, via a configuration UI (or api). This would be scoped to the tenant applying the change and is what I described above.

aaron-steinfeld avatar Jul 29 '21 12:07 aaron-steinfeld

In angular, there are files called environment.prod.ts, environment.ts, etc. If a tenant wants its own configuration, it can create a separate environment file and load these configurations at the build time. I dont know its a recommended pattern that we follow here

Gotcha - so this is one way of doing the build time approach I just described in the previous comment, but if doing this, you're forking the source code and producing a custom image, anyway - so at that point, I'm not sure I see much benefit compared to just changing the actual list of time ranges in code (PredefinedTimeDurationService)

aaron-steinfeld avatar Jul 29 '21 13:07 aaron-steinfeld

@aaron-steinfeld Can you please elaborate a little more. "At run time, via a configuration UI".

jyothishjose6190 avatar Jul 29 '21 13:07 jyothishjose6190

See my comments above - https://github.com/hypertrace/hypertrace-ui/issues/980#issuecomment-886834326

aaron-steinfeld avatar Jul 29 '21 13:07 aaron-steinfeld

thanks

jyothishjose6190 avatar Jul 29 '21 13:07 jyothishjose6190

I agree with what @aaron-steinfeld suggested.

@aaron-steinfeld, as you explained there are two options. I was thinking around doing this with helm as it's deployment wide change. But after a brief discussion with @skjindal93 , we thought that having GQL API for fetching time range with some default configs and that seems a better option.

what is your opinion on it?

JBAhire avatar Jul 30 '21 10:07 JBAhire

I agree with what @aaron-steinfeld suggested.

@aaron-steinfeld, as you explained there are two options. I was thinking around doing this with helm as it's deployment wide change. But after a brief discussion with @skjindal93 , we thought that having GQL API for fetching time range with some default configs and that seems a better option.

what is your opinion on it?

I think that makes sense as a way to take my proposal with local storage, and push it one step closer to the full implementation - close enough that it sounds like it would satisfy these requirements. We wouldn't need to introduce the edit api yet, but I would want to make sure we build out this api in the manner we'd want to for user preferences, rather than just another top level api.

The UI side and gql part are a bit independent though, so for here we really just need to pull together some mocks to proceed.

aaron-steinfeld avatar Jul 30 '21 11:07 aaron-steinfeld

I agree with what @aaron-steinfeld suggested. @aaron-steinfeld, as you explained there are two options. I was thinking around doing this with helm as it's deployment wide change. But after a brief discussion with @skjindal93 , we thought that having GQL API for fetching time range with some default configs and that seems a better option. what is your opinion on it?

I think that makes sense as a way to take my proposal with local storage, and push it one step closer to the full implementation - close enough that it sounds like it would satisfy these requirements. We wouldn't need to introduce the edit api yet, but I would want to make sure we build out this api in the manner we'd want to for user preferences, rather than just another top level api.

The UI side and gql part are a bit independent though, so for here we really just need to pull together some mocks to proceed.

I think we can just expose a GET GraphQL API, where we return a list of ordered time ranges(start time and end time), and we can always extend on that whenever we have more requirements

Currently, we can override the time ranges just via helm configs, though definitely any change in the time ranges would need a redeployment

skjindal93 avatar Aug 02 '21 14:08 skjindal93

I agree with what @aaron-steinfeld suggested. @aaron-steinfeld, as you explained there are two options. I was thinking around doing this with helm as it's deployment wide change. But after a brief discussion with @skjindal93 , we thought that having GQL API for fetching time range with some default configs and that seems a better option. what is your opinion on it?

I think that makes sense as a way to take my proposal with local storage, and push it one step closer to the full implementation - close enough that it sounds like it would satisfy these requirements. We wouldn't need to introduce the edit api yet, but I would want to make sure we build out this api in the manner we'd want to for user preferences, rather than just another top level api. The UI side and gql part are a bit independent though, so for here we really just need to pull together some mocks to proceed.

I think we can just expose a GET GraphQL API, where we return a list of ordered time ranges(start time and end time), and we can always extend on that whenever we have more requirements

Currently, we can override the time ranges just via helm configs, though definitely any change in the time ranges would need a redeployment

A few things I'd want to resolve here:

  • I think we should have a different relative and fixed gql representation - we don't want to make server call on refresh of a relative range, for example.
  • I agree we don't need a mutate for this right now, but I would want to position the query so it is part of a user preference object (which we don't really have as of today), so we don't require a brand new top level gql endpoint for each new preference.
  • Can we do this on the UI side without blocking first load? In other words, populate the initial time range before this server call returns, so we can make other data load calls in parallel. This would require keeping the default time range in the UI code and resolving a time range from the query parameter independent of the response, which IMO is fine - the response really just controls the UI selection options.

Dropping the edit/UI side of the proposal would probably be the fastest route to get this feature in here - it's not needed to accomplish the main ask.

aaron-steinfeld avatar Aug 02 '21 14:08 aaron-steinfeld