-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Logs UI] Use the Unified Search Bar for date range selection #144351
[Logs UI] Use the Unified Search Bar for date range selection #144351
Conversation
25eff4e
to
e35620f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed description
Dropping a comment on from my functional review before I look at the code. On the whole this seemed to work really well, and I know the state wasn't simple to untangle so big kudos for how solid everything felt.
I did run in to some issues with "Stream live" and refresh intervals. When I turn on streaming this is persisted to the URL (the streamLive
boolean), but the refresh interval isn't.
This results in some surprising behaviour on refresh of the page:
On refresh this is set to 0 and I see a small warning icon:
Due to the overall streamLive
boolean state being persisted to the URL the button does return to being "on", and the streaming message does display at the bottom of the stream, but no requests are actually dispatched on an interval.
Quickly looking at the code this makes sense as refreshInterval
ends up getting set to:
{
pause: false,
value: 0
}
in this scenario (due to updateStateFromTimefilterState()
, where a 0 bug exists: https://github.com/elastic/kibana/pull/144389/files#r1011529270), and the useInterval
returns null
when latestLogPositionState.refreshInterval.value <= 0
.
Apart from this my other tests seemed to work as expected. I'll take a look at the code now.
That's true. We never had the interval in the URL and I didn't want to change the URL param structure for now due to BWC. I'll look into working around that by setting it to 5s if it's 0s. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few minor comments / questions regarding the code but all in all it looks really solid to me. Thanks for investing the time with the state containers, state storage etc. Even though some of this might change with the state refactoring I think it sets up a really good foundation overall β it was definitely a lot easier to follow than what we had previously. I might just have to brush up on some functional programming concepts π
x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts
Outdated
Show resolved
Hide resolved
x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts
Outdated
Show resolved
Hide resolved
x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts
Show resolved
Hide resolved
x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts
Show resolved
Hide resolved
x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts
Show resolved
Hide resolved
@Kerry350 thanks for the feedback I hope to have fixed the tests by reducing the strictness of the url state parsing a bit by making all properties optional (as they were before). I also tried to address the refresh interval problem you discovered. To do that I had to move the Additionally, I removed the dependency on |
Pinging @elastic/infra-monitoring-ui (Team:Infra Monitoring UI) |
The functionality seems to work as expected now with regards to refresh intervals π Unfortunately, my testing was a bit inconsistent with regards to the stream live button. When I try to turn streaming on or off (via the button) I seem to hit something that causes the call stack to be exceeded and the browser locks up. I've tried this with and without Redux dev tools, and with the dev tools closed entirely, and it still seems to happen. I don't see anything obvious (like Redux dev tools being spammed with actions or something similar). But there is a message about payloads being too large (sometimes), but I don't see an abnormally sized payload in the dev tools. This doesn't happen via the "Refresh every" toggle in the date picker, it's just the button. I'd say it happens 90% of the time. (I guess it's not 100% clear in the gif, but the mouse cursor kind of denotes when it's locked up). In terms of data I'm using an oblt-cli generated cluster against Edge. |
Good catch! I was able to reproduce that and find the cause: The I added a safeguard against that. Unfortunately there's no "official" way to check whether a value is a |
π Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
Unknown metric groupsAPI count
ESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @weltenwort |
await setTimeRangeToXDaysAgo(10); | ||
await (await find.byLinkText('Alerts')).click(); | ||
await pageObjects.observability.clickSolutionNavigationEntry( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ππ»
await numerOfDaysField.clearValueWithKeyboard(); | ||
await numerOfDaysField.type(numberOfDays.toString()); | ||
const numberField = await find.byCssSelector('[aria-label="Time value"]'); | ||
await numberField.clearValueWithKeyboard(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there an issue that led to this change or is it an improvement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, previously the test assumed that "days" was selected as the time unit and it therefore just changed the number. But now the previous date picker state might contain "hours", so the test needs to explicitly set it to "days".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AO changes LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patience whilst I worked through the review π I couldn't find any issues. I know this wasn't a trivial issue at all, great work π
I think it works out pretty well with latestPosition taking over the role of the separate visibleMidpoint state we had before. Let me know what you think.
Agreed, this seemed like a positive change to me, and a better location.
I added a safeguard against that. Unfortunately there's no "official" way to check whether a value is a SyntheticEvent. π¬
Nice one catching the problem here. For all it would be nice to have an "official" method thanks for making it obvious with the helper functions.
I can confirm this was fixed in my testing:
...config, | ||
serialize: { | ||
...(typeof config?.serialize === 'object' ? config.serialize : {}), | ||
replacer: (_key: string, value: unknown) => replaceReactSyntheticEvent(value), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ππ
refreshInterval?: RefreshInterval; | ||
} | ||
|
||
export const createTimefilterStateStorage = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting approach! haven't thought of it.
There is an existing util that sets up syncing between a state container and data services. In addition to time range it also supports filters and query, but can be configured to only sync time range
src/plugins/data/public/query/state_sync/connect_to_query_state.ts
The usage would be something like this:
const stop = connectToQueryState(data.query, stateContainer, { time: true, refreshInterval: true})
Take a look! Maybe this could work well and will allow to clean up some code (the new code looks good tbh π )
Otherwise lgtm, no objections exporting more interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about that utility π‘ thanks for pointing it out
π Summary
This enables the date-picker of the unified search bar introduced into the Logs UI in #143222 and simultaneously removes the custom date picker.
closes #142767
π¨ Previews
π΅οΈββοΈ Implementation notes
kibana_utils
changesThe
kibana_utils
plugin now also exportsIStateStorage
so additional storages can be implemented.Alerts page test changes
The functional test of the observability alerts page were coupled to the assumed default state of the log stream. I changed them to use the observability overview for external timefilter checks instead and cleaned up some of the navigation code.
logPosition
stateThe log position state is now expressed using a state container, which is synced with the url and unified search bar via the common
syncState
utility in combination with aKbnUrlStateStorage
and a newly implementedTimefilterStateStorage
respectively.The structure of the
logPosition
URL query parameter remains compatible, but is now validated viaio-ts
and ignored if invalid.For simplicity, the actual representation of the
timeRange
andrefreshInterval
states are closer to the structure used in thetimefilter
service. The streaming state is derived on-the-fly from the refresh pause toggle and value.TimefilterStateStorage
In order to be able to use the common
syncState
utility, I added a state storage that is backed by thetimefilter
service. That means in contrast to other state storages it doesn't support arbitrary key-value pairs. I tried to represent that in its interface types.Date-picker and "stream live" buttom
I left the "stream live" buttom on the second row and reduced it to an
EuiEmptyButton
to prevent clashes with the refresh button of the search bar.The streaming mode can be enabled/disabled both via that button or via the refresh settings of the datepicker.