mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
enable partial tag matches for annotations
This commit is contained in:
parent
19c7dd9834
commit
1638c6bea1
@ -14,16 +14,17 @@ import (
|
||||
func GetAnnotations(c *m.ReqContext) Response {
|
||||
|
||||
query := &annotations.ItemQuery{
|
||||
From: c.QueryInt64("from"),
|
||||
To: c.QueryInt64("to"),
|
||||
OrgId: c.OrgId,
|
||||
UserId: c.QueryInt64("userId"),
|
||||
AlertId: c.QueryInt64("alertId"),
|
||||
DashboardId: c.QueryInt64("dashboardId"),
|
||||
PanelId: c.QueryInt64("panelId"),
|
||||
Limit: c.QueryInt64("limit"),
|
||||
Tags: c.QueryStrings("tags"),
|
||||
Type: c.Query("type"),
|
||||
From: c.QueryInt64("from"),
|
||||
To: c.QueryInt64("to"),
|
||||
OrgId: c.OrgId,
|
||||
UserId: c.QueryInt64("userId"),
|
||||
AlertId: c.QueryInt64("alertId"),
|
||||
DashboardId: c.QueryInt64("dashboardId"),
|
||||
PanelId: c.QueryInt64("panelId"),
|
||||
Limit: c.QueryInt64("limit"),
|
||||
Tags: c.QueryStrings("tags"),
|
||||
Type: c.Query("type"),
|
||||
PartialMatch: c.QueryBool("partialMatch"),
|
||||
}
|
||||
|
||||
repo := annotations.GetRepository()
|
||||
|
@ -21,6 +21,7 @@ type ItemQuery struct {
|
||||
RegionId int64 `json:"regionId"`
|
||||
Tags []string `json:"tags"`
|
||||
Type string `json:"type"`
|
||||
PartialMatch bool `json:"partialMatch"`
|
||||
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
@ -211,7 +211,12 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I
|
||||
)
|
||||
`, strings.Join(keyValueFilters, " OR "))
|
||||
|
||||
sql.WriteString(fmt.Sprintf(" AND (%s) = %d ", tagsSubQuery, len(tags)))
|
||||
if query.PartialMatch {
|
||||
sql.WriteString(fmt.Sprintf(" AND (%s) > 0 ", tagsSubQuery))
|
||||
} else {
|
||||
sql.WriteString(fmt.Sprintf(" AND (%s) = %d ", tagsSubQuery, len(tags)))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,31 @@ func TestAnnotations(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(annotation2.Id, ShouldBeGreaterThan, 0)
|
||||
|
||||
Convey("Can query for annotation", func() {
|
||||
globalAnnotation1 := &annotations.Item{
|
||||
OrgId: 1,
|
||||
UserId: 1,
|
||||
Text: "deploy",
|
||||
Type: "",
|
||||
Epoch: 15,
|
||||
Tags: []string{"deploy"},
|
||||
}
|
||||
err = repo.Save(globalAnnotation1)
|
||||
So(err, ShouldBeNil)
|
||||
So(globalAnnotation1.Id, ShouldBeGreaterThan, 0)
|
||||
|
||||
globalAnnotation2 := &annotations.Item{
|
||||
OrgId: 1,
|
||||
UserId: 1,
|
||||
Text: "rollback",
|
||||
Type: "",
|
||||
Epoch: 17,
|
||||
Tags: []string{"rollback"},
|
||||
}
|
||||
err = repo.Save(globalAnnotation2)
|
||||
So(err, ShouldBeNil)
|
||||
So(globalAnnotation2.Id, ShouldBeGreaterThan, 0)
|
||||
|
||||
Convey("Can query for annotation by dashboard id", func() {
|
||||
items, err := repo.Find(&annotations.ItemQuery{
|
||||
OrgId: 1,
|
||||
DashboardId: 1,
|
||||
@ -165,7 +189,7 @@ func TestAnnotations(t *testing.T) {
|
||||
OrgId: 1,
|
||||
DashboardId: 1,
|
||||
From: 1,
|
||||
To: 15,
|
||||
To: 15, //this will exclude the second test annotation
|
||||
Tags: []string{"outage", "error"},
|
||||
})
|
||||
|
||||
@ -173,6 +197,19 @@ func TestAnnotations(t *testing.T) {
|
||||
So(items, ShouldHaveLength, 1)
|
||||
})
|
||||
|
||||
Convey("Should find two annotations using partial match", func() {
|
||||
items, err := repo.Find(&annotations.ItemQuery{
|
||||
OrgId: 1,
|
||||
From: 1,
|
||||
To: 25,
|
||||
PartialMatch: true,
|
||||
Tags: []string{"rollback", "deploy"},
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(items, ShouldHaveLength, 2)
|
||||
})
|
||||
|
||||
Convey("Should find one when all key value tag filters does match", func() {
|
||||
items, err := repo.Find(&annotations.ItemQuery{
|
||||
OrgId: 1,
|
||||
|
@ -40,6 +40,7 @@ class GrafanaDatasource {
|
||||
to: options.range.to.valueOf(),
|
||||
limit: options.annotation.limit,
|
||||
tags: options.annotation.tags,
|
||||
partialMatch: options.annotation.partialMatch,
|
||||
};
|
||||
|
||||
if (options.annotation.type === 'dashboard') {
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-8">
|
||||
<span class="gf-form-label width-9">
|
||||
Filter by
|
||||
<info-popover mode="right-normal">
|
||||
<ul>
|
||||
@ -11,18 +11,11 @@
|
||||
</ul>
|
||||
</info-popover>
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper width-9">
|
||||
<div class="gf-form-select-wrapper width-8">
|
||||
<select class="gf-form-input" ng-model="ctrl.annotation.type" ng-options="f.value as f.text for f in ctrl.types">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-if="ctrl.annotation.type === 'tags'">
|
||||
<span class="gf-form-label">Tags</span>
|
||||
<bootstrap-tagsinput ng-model="ctrl.annotation.tags" tagclass="label label-tag" placeholder="add tags">
|
||||
</bootstrap-tagsinput>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Max limit</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
@ -31,6 +24,22 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form" ng-if="ctrl.annotation.type === 'tags'">
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Partial match"
|
||||
label-class="width-9"
|
||||
checked="ctrl.annotation.partialMatch"
|
||||
on-change="ctrl.refresh()"
|
||||
tooltip="By default Grafana will only show annotation that matches all tags in the query. Enabling this will make Grafana return any annotation with the tags you specify."></gf-form-switch>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.annotation.type === 'tags'">
|
||||
<span class="gf-form-label">Tags</span>
|
||||
<bootstrap-tagsinput ng-model="ctrl.annotation.tags" tagclass="label label-tag" placeholder="add tags">
|
||||
</bootstrap-tagsinput>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user