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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elasticsearch: Handle multiple annotation structures #66762
Conversation
Backend code coverage report for PR #66762 |
Frontend code coverage report for PR #66762
|
@@ -23,9 +23,15 @@ export function ElasticsearchAnnotationsQueryEditor(props: Props) { | |||
<ElasticSearchQueryField | |||
value={annotation.target?.query} | |||
onChange={(query) => { | |||
const currentTarget = annotation.target ?? { refId: 'annotation_query' }; |
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.
using this refId
-value is inspired by
refId: 'annotation_query', |
Hello @gabor!
Please, if the current pull request addresses a bug fix, label it with the |
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.
LGTM! Thank you for the extensive how to test this. Helped a ltop with making sure it works as expeted.
elastic: fix annotation handling (cherry picked from commit 82ac2ba)
elastic: fix annotation handling
since the elastic annotation handling was migrated from Angular to react in #49529 , we have a bug in how they are handled. this PR fixes the problem.
in Grafana versions up to
9.0.9
the annotation editor for elastic was angular based, and this is how it worked:you entered a lucene query, and it stored in the annotation-structure like this (there are other fields there too, but they are not important here, i'm ignoring them):
this is stored in the dashboard-json, and then the datasource's
annotationQuery
method reads it at:grafana/public/app/plugins/datasource/elasticsearch/datasource.ts
Line 246 in 720fe9d
NOTE: an unrelated thing that will be important here is: we are doing custom annotation-handling here. Grafana is able to do a generic annotation-handling-thing (for other datasources), and in such a case it creates the JSON like this:
(it basically stores a whole Query-object at
annotation.target
.with Grafana
9.1.0
, we switched for elastic-annotations to React, and wrote custom code to handle this. we tried to keep the JSON shape the same, so we still write to the top-level"query"
field:grafana/public/app/plugins/datasource/elasticsearch/components/QueryEditor/AnnotationQueryEditor.tsx
Lines 26 to 29 in b33ce06
this worked well, but there's a complication. with this being in React, some other generic Grafana code gets activated, that tries to "migrat" from the OLD toplevel-query-format to the NEW inside-target-format:
grafana/public/app/features/annotations/standardAnnotationSupport.ts
Lines 24 to 37 in b33ce06
this always happens whenever an annotation-query is opened for editing. and when this happens, the shape of our JSON changes,
query
becomestarget.query
. and when this happens, thedatasource.annotationQuery
function is not able to do it's work, because it expect the value atquery
, not attarget.query
.also, note that the elastic AnnotationQueryEditor, when editing an existing annotation, READS from
target.query
, but WRITES toquery
:grafana/public/app/plugins/datasource/elasticsearch/components/QueryEditor/AnnotationQueryEditor.tsx
Lines 24 to 30 in b33ce06
(this works because when an annotation is opened for editing, that generic grafana migration code happens, and the annotation received by the react component is already in the NEW format)
but this causes problems too. imagine that we have this JSON in dashboard-json, that we open for editing:
now, in the react annotation-editor we will see
level:error
in the text-field. we change it tolevel:info
, and save the JSON.but, the JSON stored to dashboard-json will be this:
(the automatic grafana migration thing happens when the form is opened for editing, not when the content is saved at the end)
so, to handle all this, this pull request does two changes:
datasource.annotationQuery
to look for both places (query
for old annotations, andtarget.query
for new annotations).. when both exist, we take the old-format one, because of the bug i described just above.. i think it's better to prefer the old value in this scenario.target.query
this should cover all the possible cases.
how to test:
(technically we should start with a locally built grafana 9.0.9, but i was not able to build it locally anymore, it complained about some yarn-thing, so i used grafana-in-docker instead)
make devenv=grafana grafana_version=9.0.9
counter:42
.42
.counter:43
counter:43
and an inside-targetcounter:42
.43
. (so that the new code shows.query
when both.query
and.target.query
exists.counter:44
.target.query
exists withcounter:44
, and no.query
exists.44
. (so that the new code is able to read.target.query
too)counter:45
. save dashboard, and verify in the JSON that.target.query
is set tocounter:45
, and.query
does not exist. refresh dashboard, verify the annotation says45
(so a newly created annotation works too)(fixes #61107)