[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions#213278
[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions#213278Kerry350 merged 24 commits intoelastic:mainfrom
Conversation
…t --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --include-path /api/dashboards --update'
There was a problem hiding this comment.
This is great work - it's pretty complex to get such a thing to work reliably, but I think you made good choices to get it working in a clean way.
There is one part I'm not sure about, left a comment in the code.
Some higher level questions - you might want to tackle that on a follow-up PR but it wasn't called out explicitly so just brain dumping here:
- It seems like the current logic to do the highlighting doesn't know about which part of the highlight corresponds to which extracted value (or whether it corresponds to an extracted value at all or is just part of the pattern). What's the plan for that? At first I thought "oh that's very simple, just search for the first occurrence of the extracted value", but that might not be the right one if the same value gets extracted into multiple places. It doesn't seem like there is a really easy way to do this in a stable fashion, do you have ideas around this already?
I've copied over the patterns from the ES repo for now, with a light script to generate an object from them
- At least for the autocomplete, we probably shouldn't show all of the patterns. A lot are probably irrelevant by now (who is still using nagios?) and would be more confusing than helpful for the average users. At least we should order them in a way to put the most common ones to the top.
| // Will match %{subPattern} or %{subPattern:fieldName} | ||
| const SUBPATTERNS_REGEX = /%\{[A-Z0-9_]+(?::[A-Za-z0-9_]+)?(?::[A-Za-z]+)?\}/g; | ||
|
|
||
| const NESTED_FIELD_NAMES_REGEX = |
There was a problem hiding this comment.
I'm really scared of the day I need to fix a bug in here - could we add more explanatory comments to this and the parser?
Alternatively, have you looked into using a library like https://github.com/DmitrySoshnikov/regexp-tree instead of implementing it yourself? Might be a bit easier to maintain that way.
There was a problem hiding this comment.
I can add more comments for sure 👍
I didn't look at using something like regexp-tree or ASTs in general, but I could look into it. I took a lot of inspiration from Grok Debugger and Grok Constructor and both just leaned on an approach like this, but I can certainly have a look at the library you've linked.
There was a problem hiding this comment.
Makes sense, if it's a good fit it might be worth it.
|
@flash1293 Thanks for reviewing.
Yeah, so for the highlighting it's basically a case of "does this line match this pattern in a continuous way", and this mirrors the other Grok tools that I looked at. Values are tracked in the sense of the named fields (via capture groups and the
Yeah, we can remove ones we don't think are needed. And I can add an order / weight to them. |
Maybe we need to chat more about the user experience with @patpscal and @LucaWintergerst - what I imagined was something where you can hover over the individual segments that are highlighted in different ways and it will tell you which part of the regex is matches (and maybe highlights both at the same time) |
Ah okay, I see what you mean. It'll be quite hard to implement. I don't think it's impossible, but just much harder. With Regex 101 there is realistically just the one layer to deal with, regex itself. With Grok we are essentially dealing with the 3 layers of Grok > Oniguruma > JS Regex. We'd somehow need to map each part to the other parts (and it's likely why no current Grok tools support this). Like I say, possible, just hard. I've been thinking through today how the implementation would work. Monaco supports hover additions on ranges so that part, at least, shouldn't be a problem. Do you mind if we defer that to a followup and once the UI / UX is nailed down a little more? |
|
Yes, talking to Kerry last week we also discussed that it would be much more complex now and we can follow up later. I'll leave it up to you to decide if it's better to do the harder work now or later as I can't estimate how much extra time that is. |
|
Sure, happy to defer this - let's solve the main features first and get back to it. There's already quite some complexity in this, we don't need to frontload the hardest parts. |
flash1293
left a comment
There was a problem hiding this comment.
Looks pretty good, thanks! The comments are super helpful with dense code like this.
Left two small comments about the suggestions.
| return { | ||
| label: key, | ||
| kind: monaco.languages.CompletionItemKind.Keyword, | ||
| insertText: key + (nextCharacterIsClosingPatternBracket ? '' : '}'), |
There was a problem hiding this comment.
I'm not sure about this - when I'm at the end of the pattern so far, I guess it's more common to add a semantic name than just moving on.
By autocompleting the } this is made harder. Maybe we should even autocomplete a generic semantic name? Like if I'm typing %{WO and accept the WORD completion, it will put %{WORD:field_<n>} (with n being the number of semantic names so far).
We could even be smart about it - if you use the SPACE pattern, then you probably don't want to give a semantic name, so we autocomplete } right away.
Wdyt?
There was a problem hiding this comment.
By autocompleting the } this is made harder. Maybe we should even autocomplete a generic semantic name? Like if I'm typing %{WO and accept the WORD completion, it will put %{WORD:field_} (with n being the number of semantic names so far).
Yeah, possibly. I might be missing something but I can't find a combination of these options where you can basically say "insert this, at this range, AND pull the cursor position back". So we could just omit the } entirely, but it's hard to say right now how this will be used most.
I don't agree that inserting a semantic by default is right, necessarily. Patterns without a semantic are just as valid and potentially valuable as those without. They still form a valid part of the expression, and may well be used to parse / skip parts of information but without wanting to extract them. By defaulting to adding the semantic users would have to then remove it each time they don't need, this seems more cumbersome than the opposite behaviour. (Not hard to add this one, just not sure it's better).
Not sure how the SPACE part would work accurately, as by the time you insert a space we wouldn't be offering suggestions.
| // Can be used with Monaco code editor to provide suggestions. | ||
| public getSuggestionProvider = () => { | ||
| const provider: monaco.languages.CompletionItemProvider = { | ||
| triggerCharacters: ['{'], |
There was a problem hiding this comment.
Should %{ be the trigger? { is just a normal character in grok, so it could trigger at the wrong time.
There was a problem hiding this comment.
It's kind of hard to find detailed information on how they work, but the behaviour is the same whether this is { or %{. I think we'd probably have to do a bunch of manual inspection via the text model if this becomes a problem (nothing is actually selected even if things displaying might not be necessary).
There was a problem hiding this comment.
got it, not a blocker or anything.
|
@flash1293 Thanks for the reviews. Just an overall note on the list here: #213278 (comment), the two main parts were implemented. I played a bit with the automatic placeholder behaviour, I'm not 100% sure it's a good thing to add by default, I think this would make more sense with something like a toggle to turn it on / off, and will defer this for now. For displaying the colour alongside the structured output I didn't actually render this out as the UI / UX is changing anyway, but the information is 100% there to render in any way we need (cc @patpscal). @thomheymann also had a suggestion on Slack:
This is a good suggestion, it's just a little tricky to implement. Doing this for "proper" patterns e.g. @flash1293 Unless you see any hard blockers that can't be followed up on I'd like to get this merged in as the priorities are switching to processors 👌 (I'll remove this from the enrichment page when you're okay with it). |
flash1293
left a comment
There was a problem hiding this comment.
Thanks for looking into the potential improvements, none of them are blocking, LGTM
💚 Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Unknown metric groupsAPI count
ESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
History
cc @Kerry350 |
|
Starting backport for target branches: 8.x https://github.com/elastic/kibana/actions/runs/13935064664 |
💔 All backports failed
Manual backportTo create the backport manually run: Questions ?Please refer to the Backport tool documentation |
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
… / suggestions (#213278) (#215204) # Backport This will backport the following commits from `main` to `8.x`: - [[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions (#213278)](#213278) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Kerry Gallagher","email":"kerry.gallagher@elastic.co"},"sourceCommit":{"committedDate":"2025-03-18T22:56:58Z","message":"[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions (#213278)\n\n## Summary\n\nCloses elastic/streams-program#170 and\nhttps://github.com/elastic/streams-program/issues/171\n\n## Reviewer notes\n\nIt's worth reading the research in\nhttps://github.com/elastic/streams-program/issues/168 to understand why\ncertain decisions were made. Some of the resolving code is inspired by\n`grok-js`, unfortunately this wasn't something we could use directly.\n\nThe design / UX is **not** final. This is just a functional version. The\neditor is currently on the streams > enrichment page so it can be played\nwith, this will **not** be merged.\n\nThere is pattern support for our ECS patterns, I have not added the\nlegacy ones.\n\nThere will almost certainly be some edge cases that don't work, every\nrepo for a Grok tool I looked at had their own 😅 I've tried to test this\nwith lots of varied examples though.\n\nI'd recommend unticking \"No extension\" from the file filter to remove\nthe pattern files.\n\n<img width=\"323\" alt=\"Screenshot 2025-03-06 at 22 40 19\"\nsrc=\"https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a\"\n/>\n\n## Possible improvements / followups\n\n- We could in the future expand the UI to toggle on and off certain\npattern collections.\n\n- Ability to add custom patterns (like in our Grok debugger). This can\nstill be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax.\n\n- Point out when regex is invalid (right now it's silent).\n\n- I've copied over the patterns from the ES repo for now, with a light\nscript to generate an object from them. There's a CLI skeleton in place\nif we feel we want to actually pull these from the ES repo directly.\nThese patterns don't change often, and aren't heavy size wise.\n\n- Debouncing etc for processing, but I'd like to see how the final UX\nends up.\n\n## Media\n\nScreenshot\n\n\n\nSimple example\n\n\n\n\nComplex example\n\n\n\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"f9783504bbc9993027967c36cdcfb8d2a37bddfb","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:version","Feature:Streams","v9.1.0","v8.19.0"],"title":"[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions","number":213278,"url":"https://github.com/elastic/kibana/pull/213278","mergeCommit":{"message":"[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions (#213278)\n\n## Summary\n\nCloses elastic/streams-program#170 and\nhttps://github.com/elastic/streams-program/issues/171\n\n## Reviewer notes\n\nIt's worth reading the research in\nhttps://github.com/elastic/streams-program/issues/168 to understand why\ncertain decisions were made. Some of the resolving code is inspired by\n`grok-js`, unfortunately this wasn't something we could use directly.\n\nThe design / UX is **not** final. This is just a functional version. The\neditor is currently on the streams > enrichment page so it can be played\nwith, this will **not** be merged.\n\nThere is pattern support for our ECS patterns, I have not added the\nlegacy ones.\n\nThere will almost certainly be some edge cases that don't work, every\nrepo for a Grok tool I looked at had their own 😅 I've tried to test this\nwith lots of varied examples though.\n\nI'd recommend unticking \"No extension\" from the file filter to remove\nthe pattern files.\n\n<img width=\"323\" alt=\"Screenshot 2025-03-06 at 22 40 19\"\nsrc=\"https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a\"\n/>\n\n## Possible improvements / followups\n\n- We could in the future expand the UI to toggle on and off certain\npattern collections.\n\n- Ability to add custom patterns (like in our Grok debugger). This can\nstill be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax.\n\n- Point out when regex is invalid (right now it's silent).\n\n- I've copied over the patterns from the ES repo for now, with a light\nscript to generate an object from them. There's a CLI skeleton in place\nif we feel we want to actually pull these from the ES repo directly.\nThese patterns don't change often, and aren't heavy size wise.\n\n- Debouncing etc for processing, but I'd like to see how the final UX\nends up.\n\n## Media\n\nScreenshot\n\n\n\nSimple example\n\n\n\n\nComplex example\n\n\n\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"f9783504bbc9993027967c36cdcfb8d2a37bddfb"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/213278","number":213278,"mergeCommit":{"message":"[Streams] [Dedicated Grok UI] Package / highlight matched parts / suggestions (#213278)\n\n## Summary\n\nCloses elastic/streams-program#170 and\nhttps://github.com/elastic/streams-program/issues/171\n\n## Reviewer notes\n\nIt's worth reading the research in\nhttps://github.com/elastic/streams-program/issues/168 to understand why\ncertain decisions were made. Some of the resolving code is inspired by\n`grok-js`, unfortunately this wasn't something we could use directly.\n\nThe design / UX is **not** final. This is just a functional version. The\neditor is currently on the streams > enrichment page so it can be played\nwith, this will **not** be merged.\n\nThere is pattern support for our ECS patterns, I have not added the\nlegacy ones.\n\nThere will almost certainly be some edge cases that don't work, every\nrepo for a Grok tool I looked at had their own 😅 I've tried to test this\nwith lots of varied examples though.\n\nI'd recommend unticking \"No extension\" from the file filter to remove\nthe pattern files.\n\n<img width=\"323\" alt=\"Screenshot 2025-03-06 at 22 40 19\"\nsrc=\"https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a\"\n/>\n\n## Possible improvements / followups\n\n- We could in the future expand the UI to toggle on and off certain\npattern collections.\n\n- Ability to add custom patterns (like in our Grok debugger). This can\nstill be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax.\n\n- Point out when regex is invalid (right now it's silent).\n\n- I've copied over the patterns from the ES repo for now, with a light\nscript to generate an object from them. There's a CLI skeleton in place\nif we feel we want to actually pull these from the ES repo directly.\nThese patterns don't change often, and aren't heavy size wise.\n\n- Debouncing etc for processing, but I'd like to see how the final UX\nends up.\n\n## Media\n\nScreenshot\n\n\n\nSimple example\n\n\n\n\nComplex example\n\n\n\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"f9783504bbc9993027967c36cdcfb8d2a37bddfb"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…gestions (elastic#213278) ## Summary Closes elastic/streams-program#170 and elastic/streams-program#171 ## Reviewer notes It's worth reading the research in elastic/streams-program#168 to understand why certain decisions were made. Some of the resolving code is inspired by `grok-js`, unfortunately this wasn't something we could use directly. The design / UX is **not** final. This is just a functional version. The editor is currently on the streams > enrichment page so it can be played with, this will **not** be merged. There is pattern support for our ECS patterns, I have not added the legacy ones. There will almost certainly be some edge cases that don't work, every repo for a Grok tool I looked at had their own 😅 I've tried to test this with lots of varied examples though. I'd recommend unticking "No extension" from the file filter to remove the pattern files. <img width="323" alt="Screenshot 2025-03-06 at 22 40 19" src="https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a" /> ## Possible improvements / followups - We could in the future expand the UI to toggle on and off certain pattern collections. - Ability to add custom patterns (like in our Grok debugger). This can still be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax. - Point out when regex is invalid (right now it's silent). - I've copied over the patterns from the ES repo for now, with a light script to generate an object from them. There's a CLI skeleton in place if we feel we want to actually pull these from the ES repo directly. These patterns don't change often, and aren't heavy size wise. - Debouncing etc for processing, but I'd like to see how the final UX ends up. ## Media Screenshot  Simple example  Complex example  --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…gestions (elastic#213278) ## Summary Closes elastic/streams-program#170 and elastic/streams-program#171 ## Reviewer notes It's worth reading the research in elastic/streams-program#168 to understand why certain decisions were made. Some of the resolving code is inspired by `grok-js`, unfortunately this wasn't something we could use directly. The design / UX is **not** final. This is just a functional version. The editor is currently on the streams > enrichment page so it can be played with, this will **not** be merged. There is pattern support for our ECS patterns, I have not added the legacy ones. There will almost certainly be some edge cases that don't work, every repo for a Grok tool I looked at had their own 😅 I've tried to test this with lots of varied examples though. I'd recommend unticking "No extension" from the file filter to remove the pattern files. <img width="323" alt="Screenshot 2025-03-06 at 22 40 19" src="https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a" /> ## Possible improvements / followups - We could in the future expand the UI to toggle on and off certain pattern collections. - Ability to add custom patterns (like in our Grok debugger). This can still be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax. - Point out when regex is invalid (right now it's silent). - I've copied over the patterns from the ES repo for now, with a light script to generate an object from them. There's a CLI skeleton in place if we feel we want to actually pull these from the ES repo directly. These patterns don't change often, and aren't heavy size wise. - Debouncing etc for processing, but I'd like to see how the final UX ends up. ## Media Screenshot  Simple example  Complex example  --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…gestions (elastic#213278) ## Summary Closes elastic/streams-program#170 and elastic/streams-program#171 ## Reviewer notes It's worth reading the research in elastic/streams-program#168 to understand why certain decisions were made. Some of the resolving code is inspired by `grok-js`, unfortunately this wasn't something we could use directly. The design / UX is **not** final. This is just a functional version. The editor is currently on the streams > enrichment page so it can be played with, this will **not** be merged. There is pattern support for our ECS patterns, I have not added the legacy ones. There will almost certainly be some edge cases that don't work, every repo for a Grok tool I looked at had their own 😅 I've tried to test this with lots of varied examples though. I'd recommend unticking "No extension" from the file filter to remove the pattern files. <img width="323" alt="Screenshot 2025-03-06 at 22 40 19" src="https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a" /> ## Possible improvements / followups - We could in the future expand the UI to toggle on and off certain pattern collections. - Ability to add custom patterns (like in our Grok debugger). This can still be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax. - Point out when regex is invalid (right now it's silent). - I've copied over the patterns from the ES repo for now, with a light script to generate an object from them. There's a CLI skeleton in place if we feel we want to actually pull these from the ES repo directly. These patterns don't change often, and aren't heavy size wise. - Debouncing etc for processing, but I'd like to see how the final UX ends up. ## Media Screenshot  Simple example  Complex example  --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…gestions (elastic#213278) ## Summary Closes elastic/streams-program#170 and elastic/streams-program#171 ## Reviewer notes It's worth reading the research in elastic/streams-program#168 to understand why certain decisions were made. Some of the resolving code is inspired by `grok-js`, unfortunately this wasn't something we could use directly. The design / UX is **not** final. This is just a functional version. The editor is currently on the streams > enrichment page so it can be played with, this will **not** be merged. There is pattern support for our ECS patterns, I have not added the legacy ones. There will almost certainly be some edge cases that don't work, every repo for a Grok tool I looked at had their own 😅 I've tried to test this with lots of varied examples though. I'd recommend unticking "No extension" from the file filter to remove the pattern files. <img width="323" alt="Screenshot 2025-03-06 at 22 40 19" src="https://github.com/user-attachments/assets/5b594f5f-0b0f-4ed0-ae10-2412fcf9e31a" /> ## Possible improvements / followups - We could in the future expand the UI to toggle on and off certain pattern collections. - Ability to add custom patterns (like in our Grok debugger). This can still be achieved with `(?<queue_id>[0-9A-F]{10,11})` syntax. - Point out when regex is invalid (right now it's silent). - I've copied over the patterns from the ES repo for now, with a light script to generate an object from them. There's a CLI skeleton in place if we feel we want to actually pull these from the ES repo directly. These patterns don't change often, and aren't heavy size wise. - Debouncing etc for processing, but I'd like to see how the final UX ends up. ## Media Screenshot  Simple example  Complex example  --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary Closes #214994 This PR removes the Observability version of the `unflattenObject` helper and updates its usages to use the `kbn-object-utils` package. It also fixes several edge cases: #213278 (review) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary Closes elastic#214994 This PR removes the Observability version of the `unflattenObject` helper and updates its usages to use the `kbn-object-utils` package. It also fixes several edge cases: elastic#213278 (review) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary Closes elastic#214994 This PR removes the Observability version of the `unflattenObject` helper and updates its usages to use the `kbn-object-utils` package. It also fixes several edge cases: elastic#213278 (review) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>

Summary
Closes https://github.com/elastic/streams-program/issues/170 and https://github.com/elastic/streams-program/issues/171
Reviewer notes
It's worth reading the research in https://github.com/elastic/streams-program/issues/168 to understand why certain decisions were made. Some of the resolving code is inspired by
grok-js, unfortunately this wasn't something we could use directly.The design / UX is not final. This is just a functional version. The editor is currently on the streams > enrichment page so it can be played with, this will not be merged.
There is pattern support for our ECS patterns, I have not added the legacy ones.
There will almost certainly be some edge cases that don't work, every repo for a Grok tool I looked at had their own 😅 I've tried to test this with lots of varied examples though.
I'd recommend unticking "No extension" from the file filter to remove the pattern files.
Possible improvements / followups
We could in the future expand the UI to toggle on and off certain pattern collections.
Ability to add custom patterns (like in our Grok debugger). This can still be achieved with
(?<queue_id>[0-9A-F]{10,11})syntax.Point out when regex is invalid (right now it's silent).
I've copied over the patterns from the ES repo for now, with a light script to generate an object from them. There's a CLI skeleton in place if we feel we want to actually pull these from the ES repo directly. These patterns don't change often, and aren't heavy size wise.
Debouncing etc for processing, but I'd like to see how the final UX ends up.
Media
Screenshot