mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'grafana/master' into alpha-text2
* grafana/master: Explore: Enable click on name label Bumping grafana ui version (#15669) Need this to be available for plugins docs: 6.0 whats new Updated latest.json with 6.0 Update CHANGELOG.md docs: grafana 6.0 has been released. moves social package to /login moves tracing packge into /infra Update CHANGELOG.md changelog: adds notes for #14509 and #15179 graph: fixes click after scroll in series override menu moves metric package to /infra stackdriver: change reducer mapping for distribution metrics stackdriver: fix for float64 bounds for distribution metrics Fixed value dropdown not updating when it's current value updates, fixes #15566
This commit is contained in:
commit
d3cbc5638c
@ -1,4 +1,10 @@
|
|||||||
# Unreleased
|
# 6.0.0 stable (2019-02-25)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
* **Stackdriver**: fix for float64 bounds for distribution metrics [#14509](https://github.com/grafana/grafana/issues/14509)
|
||||||
|
* **Stackdriver**: no reducers available for distribution type [#15179](https://github.com/grafana/grafana/issues/15179)
|
||||||
|
* **Dashboard**: fixes click after scroll in series override menu [#15621](https://github.com/grafana/grafana/issues/15621)
|
||||||
|
* **MySQL**: fix mysql query using _interval_ms variable throws error [#14507](https://github.com/grafana/grafana/issues/14507)
|
||||||
|
|
||||||
# 6.0.0-beta3 (2019-02-19)
|
# 6.0.0-beta3 (2019-02-19)
|
||||||
|
|
||||||
|
@ -14,8 +14,6 @@ weight = -11
|
|||||||
|
|
||||||
This update to Grafana introduces a new way of exploring your data, support for log data and tons of other features.
|
This update to Grafana introduces a new way of exploring your data, support for log data and tons of other features.
|
||||||
|
|
||||||
Grafana v6.0 is out in **Beta**, [Download Now!](https://grafana.com/grafana/download/beta)
|
|
||||||
|
|
||||||
The main highlights are:
|
The main highlights are:
|
||||||
|
|
||||||
- [Explore]({{< relref "#explore" >}}) - A new query focused workflow for ad-hoc data exploration and troubleshooting.
|
- [Explore]({{< relref "#explore" >}}) - A new query focused workflow for ad-hoc data exploration and troubleshooting.
|
||||||
@ -107,9 +105,9 @@ continue to refine and start using in other panels.
|
|||||||
### React Panels & Query Editors
|
### React Panels & Query Editors
|
||||||
|
|
||||||
A major part of all the work that has gone into Grafana v6.0 has been on the migration to React. This investment
|
A major part of all the work that has gone into Grafana v6.0 has been on the migration to React. This investment
|
||||||
is part of the future proofing of Grafana and it's code base and ecosystem. Starting in v6.0 **Panels** and **Data
|
is part of the future proofing of Grafana's code base and ecosystem. Starting in v6.0 **Panels** and **Data
|
||||||
source** plugins can be written in React using our published `@grafana/ui` sdk library. More information on this
|
source** plugins can be written in React using our published `@grafana/ui` sdk library. More information on this
|
||||||
will be shared closer to or just after release.
|
will be shared soon.
|
||||||
|
|
||||||
{{< docs-imagebox img="/img/docs/v60/react_panels.png" max-width="600px" caption="React Panel" >}}
|
{{< docs-imagebox img="/img/docs/v60/react_panels.png" max-width="600px" caption="React Panel" >}}
|
||||||
<br />
|
<br />
|
||||||
@ -122,7 +120,7 @@ To get started read the guide: [Using Google Stackdriver in Grafana](/features/d
|
|||||||
|
|
||||||
## Azure Monitor Datasource
|
## Azure Monitor Datasource
|
||||||
|
|
||||||
One of the goals of the Grafana v6.0 release is to add support for the three major clouds. Amazon Cloudwatch has been a core datasource for years and Google Stackdriver is also now supported. We developed an external plugin for Azure Monitor last year and for this release the [plugin](https://grafana.com/plugins/grafana-azure-monitor-datasource) is being moved into Grafana to be one of the built-in datasources. For users of the external plugin, Grafana will automatically start using the built-in version. As a core datasource, the Azure Monitor datasource will get alerting support for the official 6.0 release.
|
One of the goals of the Grafana v6.0 release is to add support for the three major clouds. Amazon Cloudwatch has been a core datasource for years and Google Stackdriver is also now supported. We developed an external plugin for Azure Monitor last year and for this release the [plugin](https://grafana.com/plugins/grafana-azure-monitor-datasource) is being moved into Grafana to be one of the built-in datasources. For users of the external plugin, Grafana will automatically start using the built-in version. As a core datasource, the Azure Monitor datasource is able to get alerting support, in the 6.0 release alerting is supported for the Azure Monitor service, with the rest to follow.
|
||||||
|
|
||||||
The Azure Monitor datasource integrates four Azure services with Grafana - Azure Monitor, Azure Log Analytics, Azure Application Insights and Azure Application Insights Analytics.
|
The Azure Monitor datasource integrates four Azure services with Grafana - Azure Monitor, Azure Log Analytics, Azure Application Insights and Azure Application Insights Analytics.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"stable": "5.4.3",
|
"stable": "6.0.0",
|
||||||
"testing": "5.4.3"
|
"testing": "6.0.0"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@grafana/ui",
|
"name": "@grafana/ui",
|
||||||
"version": "6.0.0-alpha.0",
|
"version": "6.0.1-alpha.0",
|
||||||
"description": "Grafana Components Library",
|
"description": "Grafana Components Library",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"typescript",
|
"typescript",
|
||||||
|
@ -2,3 +2,4 @@ export * from './processTimeSeries';
|
|||||||
export * from './valueFormats/valueFormats';
|
export * from './valueFormats/valueFormats';
|
||||||
export * from './colors';
|
export * from './colors';
|
||||||
export * from './namedColorsPalette';
|
export * from './namedColorsPalette';
|
||||||
|
export { getMappedValue } from './valueMappings';
|
||||||
|
@ -3,7 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
@ -2,7 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/api/pluginproxy"
|
"github.com/grafana/grafana/pkg/api/pluginproxy"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
)
|
)
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/login"
|
"github.com/grafana/grafana/pkg/login"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
@ -16,12 +16,12 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/login"
|
"github.com/grafana/grafana/pkg/login"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/login/social"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/social"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -3,7 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/events"
|
"github.com/grafana/grafana/pkg/events"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/events"
|
"github.com/grafana/grafana/pkg/events"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
@ -14,8 +14,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/extensions"
|
"github.com/grafana/grafana/pkg/extensions"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
_ "github.com/grafana/grafana/pkg/services/alerting/conditions"
|
_ "github.com/grafana/grafana/pkg/services/alerting/conditions"
|
||||||
_ "github.com/grafana/grafana/pkg/services/alerting/notifiers"
|
_ "github.com/grafana/grafana/pkg/services/alerting/notifiers"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
@ -16,9 +16,9 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/login"
|
"github.com/grafana/grafana/pkg/login"
|
||||||
|
"github.com/grafana/grafana/pkg/login/social"
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
"github.com/grafana/grafana/pkg/social"
|
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
@ -28,8 +28,9 @@ import (
|
|||||||
|
|
||||||
// self registering services
|
// self registering services
|
||||||
_ "github.com/grafana/grafana/pkg/extensions"
|
_ "github.com/grafana/grafana/pkg/extensions"
|
||||||
|
_ "github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
_ "github.com/grafana/grafana/pkg/infra/serverlock"
|
_ "github.com/grafana/grafana/pkg/infra/serverlock"
|
||||||
_ "github.com/grafana/grafana/pkg/metrics"
|
_ "github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
_ "github.com/grafana/grafana/pkg/plugins"
|
_ "github.com/grafana/grafana/pkg/plugins"
|
||||||
_ "github.com/grafana/grafana/pkg/services/alerting"
|
_ "github.com/grafana/grafana/pkg/services/alerting"
|
||||||
_ "github.com/grafana/grafana/pkg/services/auth"
|
_ "github.com/grafana/grafana/pkg/services/auth"
|
||||||
@ -39,7 +40,6 @@ import (
|
|||||||
_ "github.com/grafana/grafana/pkg/services/rendering"
|
_ "github.com/grafana/grafana/pkg/services/rendering"
|
||||||
_ "github.com/grafana/grafana/pkg/services/search"
|
_ "github.com/grafana/grafana/pkg/services/search"
|
||||||
_ "github.com/grafana/grafana/pkg/services/sqlstore"
|
_ "github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
_ "github.com/grafana/grafana/pkg/tracing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewGrafanaServer() *GrafanaServerImpl {
|
func NewGrafanaServer() *GrafanaServerImpl {
|
||||||
|
@ -3,8 +3,8 @@ package metrics
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics/graphitebridge"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics/graphitebridge"
|
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/metrics/graphitebridge"
|
"github.com/grafana/grafana/pkg/infra/metrics/graphitebridge"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
@ -5,8 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/login/social"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/social"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DefaultEvalHandler struct {
|
type DefaultEvalHandler struct {
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/imguploader"
|
"github.com/grafana/grafana/pkg/components/imguploader"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
"github.com/grafana/grafana/pkg/services/rendering"
|
"github.com/grafana/grafana/pkg/services/rendering"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations"
|
"github.com/grafana/grafana/pkg/services/annotations"
|
||||||
"github.com/grafana/grafana/pkg/services/rendering"
|
"github.com/grafana/grafana/pkg/services/rendering"
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface"
|
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface"
|
||||||
"github.com/grafana/grafana/pkg/components/null"
|
"github.com/grafana/grafana/pkg/components/null"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CloudWatchExecutor struct {
|
type CloudWatchExecutor struct {
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/tsdb"
|
"github.com/grafana/grafana/pkg/tsdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -336,6 +336,8 @@ func (e *StackdriverExecutor) unmarshalResponse(res *http.Response) (Stackdriver
|
|||||||
return StackdriverResponse{}, err
|
return StackdriverResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slog.Info("stackdriver", "response", string(body))
|
||||||
|
|
||||||
if res.StatusCode/100 != 2 {
|
if res.StatusCode/100 != 2 {
|
||||||
slog.Error("Request failed", "status", res.Status, "body", string(body))
|
slog.Error("Request failed", "status", res.Status, "body", string(body))
|
||||||
return StackdriverResponse{}, fmt.Errorf(string(body))
|
return StackdriverResponse{}, fmt.Errorf(string(body))
|
||||||
@ -559,7 +561,7 @@ func calcBucketBound(bucketOptions StackdriverBucketOptions, n int) string {
|
|||||||
} else if bucketOptions.ExponentialBuckets != nil {
|
} else if bucketOptions.ExponentialBuckets != nil {
|
||||||
bucketBound = strconv.FormatInt(int64(bucketOptions.ExponentialBuckets.Scale*math.Pow(bucketOptions.ExponentialBuckets.GrowthFactor, float64(n-1))), 10)
|
bucketBound = strconv.FormatInt(int64(bucketOptions.ExponentialBuckets.Scale*math.Pow(bucketOptions.ExponentialBuckets.GrowthFactor, float64(n-1))), 10)
|
||||||
} else if bucketOptions.ExplicitBuckets != nil {
|
} else if bucketOptions.ExplicitBuckets != nil {
|
||||||
bucketBound = strconv.FormatInt(bucketOptions.ExplicitBuckets.Bounds[(n-1)], 10)
|
bucketBound = fmt.Sprintf("%g", bucketOptions.ExplicitBuckets.Bounds[n])
|
||||||
}
|
}
|
||||||
return bucketBound
|
return bucketBound
|
||||||
}
|
}
|
||||||
|
@ -344,8 +344,8 @@ func TestStackdriver(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("when data from query is distribution", func() {
|
Convey("when data from query is distribution with exponential bounds", func() {
|
||||||
data, err := loadTestFile("./test-data/3-series-response-distribution.json")
|
data, err := loadTestFile("./test-data/3-series-response-distribution-exponential.json")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(data.TimeSeries), ShouldEqual, 1)
|
So(len(data.TimeSeries), ShouldEqual, 1)
|
||||||
|
|
||||||
@ -370,6 +370,14 @@ func TestStackdriver(t *testing.T) {
|
|||||||
So(res.Series[0].Points[2][1].Float64, ShouldEqual, 1536669060000)
|
So(res.Series[0].Points[2][1].Float64, ShouldEqual, 1536669060000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("bucket bounds should be correct", func() {
|
||||||
|
So(res.Series[0].Name, ShouldEqual, "0")
|
||||||
|
So(res.Series[1].Name, ShouldEqual, "1")
|
||||||
|
So(res.Series[2].Name, ShouldEqual, "2")
|
||||||
|
So(res.Series[3].Name, ShouldEqual, "4")
|
||||||
|
So(res.Series[4].Name, ShouldEqual, "8")
|
||||||
|
})
|
||||||
|
|
||||||
Convey("value should be correct", func() {
|
Convey("value should be correct", func() {
|
||||||
So(res.Series[8].Points[0][0].Float64, ShouldEqual, 1)
|
So(res.Series[8].Points[0][0].Float64, ShouldEqual, 1)
|
||||||
So(res.Series[9].Points[0][0].Float64, ShouldEqual, 1)
|
So(res.Series[9].Points[0][0].Float64, ShouldEqual, 1)
|
||||||
@ -383,6 +391,45 @@ func TestStackdriver(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("when data from query is distribution with explicit bounds", func() {
|
||||||
|
data, err := loadTestFile("./test-data/4-series-response-distribution-explicit.json")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(len(data.TimeSeries), ShouldEqual, 1)
|
||||||
|
|
||||||
|
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
|
||||||
|
query := &StackdriverQuery{AliasBy: "{{bucket}}"}
|
||||||
|
err = executor.parseResponse(res, data, query)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
So(len(res.Series), ShouldEqual, 33)
|
||||||
|
for i := 0; i < 33; i++ {
|
||||||
|
if i == 0 {
|
||||||
|
So(res.Series[i].Name, ShouldEqual, "0")
|
||||||
|
}
|
||||||
|
So(len(res.Series[i].Points), ShouldEqual, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
Convey("timestamps should be in ascending order", func() {
|
||||||
|
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1550859086000)
|
||||||
|
So(res.Series[0].Points[1][1].Float64, ShouldEqual, 1550859146000)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("bucket bounds should be correct", func() {
|
||||||
|
So(res.Series[0].Name, ShouldEqual, "0")
|
||||||
|
So(res.Series[1].Name, ShouldEqual, "0.01")
|
||||||
|
So(res.Series[2].Name, ShouldEqual, "0.05")
|
||||||
|
So(res.Series[3].Name, ShouldEqual, "0.1")
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("value should be correct", func() {
|
||||||
|
So(res.Series[8].Points[0][0].Float64, ShouldEqual, 381)
|
||||||
|
So(res.Series[9].Points[0][0].Float64, ShouldEqual, 212)
|
||||||
|
So(res.Series[10].Points[0][0].Float64, ShouldEqual, 56)
|
||||||
|
So(res.Series[8].Points[1][0].Float64, ShouldEqual, 375)
|
||||||
|
So(res.Series[9].Points[1][0].Float64, ShouldEqual, 213)
|
||||||
|
So(res.Series[10].Points[1][0].Float64, ShouldEqual, 56)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("when interpolating filter wildcards", func() {
|
Convey("when interpolating filter wildcards", func() {
|
||||||
|
@ -0,0 +1,209 @@
|
|||||||
|
{
|
||||||
|
"timeSeries": [
|
||||||
|
{
|
||||||
|
"metric": {
|
||||||
|
"type": "custom.googleapis.com\/opencensus\/grpc.io\/client\/roundtrip_latency"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"type": "global",
|
||||||
|
"labels": {
|
||||||
|
"project_id": "grafana-demo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"metricKind": "DELTA",
|
||||||
|
"valueType": "DISTRIBUTION",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"interval": {
|
||||||
|
"startTime": "2019-02-22T18:11:26Z",
|
||||||
|
"endTime": "2019-02-22T18:12:26Z"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"distributionValue": {
|
||||||
|
"count": "1878",
|
||||||
|
"mean": 17.813718392255,
|
||||||
|
"sumOfSquaredDeviation": 7141630.651914,
|
||||||
|
"bucketOptions": {
|
||||||
|
"explicitBuckets": {
|
||||||
|
"bounds": [
|
||||||
|
0,
|
||||||
|
0.01,
|
||||||
|
0.05,
|
||||||
|
0.1,
|
||||||
|
0.3,
|
||||||
|
0.6,
|
||||||
|
0.8,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
8,
|
||||||
|
10,
|
||||||
|
13,
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
25,
|
||||||
|
30,
|
||||||
|
40,
|
||||||
|
50,
|
||||||
|
65,
|
||||||
|
80,
|
||||||
|
100,
|
||||||
|
130,
|
||||||
|
160,
|
||||||
|
200,
|
||||||
|
250,
|
||||||
|
300,
|
||||||
|
400,
|
||||||
|
500,
|
||||||
|
650,
|
||||||
|
800,
|
||||||
|
1000,
|
||||||
|
2000,
|
||||||
|
5000,
|
||||||
|
10000,
|
||||||
|
20000,
|
||||||
|
50000,
|
||||||
|
100000
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bucketCounts": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"403",
|
||||||
|
"297",
|
||||||
|
"184",
|
||||||
|
"375",
|
||||||
|
"213",
|
||||||
|
"56",
|
||||||
|
"31",
|
||||||
|
"15",
|
||||||
|
"13",
|
||||||
|
"4",
|
||||||
|
"1",
|
||||||
|
"5",
|
||||||
|
"2",
|
||||||
|
"8",
|
||||||
|
"13",
|
||||||
|
"26",
|
||||||
|
"13",
|
||||||
|
"45",
|
||||||
|
"48",
|
||||||
|
"61",
|
||||||
|
"10",
|
||||||
|
"3",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"4",
|
||||||
|
"7",
|
||||||
|
"12",
|
||||||
|
"8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interval": {
|
||||||
|
"startTime": "2019-02-22T18:10:26Z",
|
||||||
|
"endTime": "2019-02-22T18:11:26Z"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"distributionValue": {
|
||||||
|
"count": "1887",
|
||||||
|
"mean": 17.654277577766,
|
||||||
|
"sumOfSquaredDeviation": 7082587.2133073,
|
||||||
|
"bucketOptions": {
|
||||||
|
"explicitBuckets": {
|
||||||
|
"bounds": [
|
||||||
|
0,
|
||||||
|
0.01,
|
||||||
|
0.05,
|
||||||
|
0.1,
|
||||||
|
0.3,
|
||||||
|
0.6,
|
||||||
|
0.8,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
8,
|
||||||
|
10,
|
||||||
|
13,
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
25,
|
||||||
|
30,
|
||||||
|
40,
|
||||||
|
50,
|
||||||
|
65,
|
||||||
|
80,
|
||||||
|
100,
|
||||||
|
130,
|
||||||
|
160,
|
||||||
|
200,
|
||||||
|
250,
|
||||||
|
300,
|
||||||
|
400,
|
||||||
|
500,
|
||||||
|
650,
|
||||||
|
800,
|
||||||
|
1000,
|
||||||
|
2000,
|
||||||
|
5000,
|
||||||
|
10000,
|
||||||
|
20000,
|
||||||
|
50000,
|
||||||
|
100000
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bucketCounts": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"404",
|
||||||
|
"298",
|
||||||
|
"187",
|
||||||
|
"381",
|
||||||
|
"212",
|
||||||
|
"56",
|
||||||
|
"31",
|
||||||
|
"15",
|
||||||
|
"14",
|
||||||
|
"4",
|
||||||
|
"1",
|
||||||
|
"4",
|
||||||
|
"2",
|
||||||
|
"9",
|
||||||
|
"13",
|
||||||
|
"24",
|
||||||
|
"13",
|
||||||
|
"46",
|
||||||
|
"46",
|
||||||
|
"61",
|
||||||
|
"11",
|
||||||
|
"3",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"5",
|
||||||
|
"7",
|
||||||
|
"11",
|
||||||
|
"8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -26,7 +26,7 @@ type StackdriverBucketOptions struct {
|
|||||||
Scale float64 `json:"scale"`
|
Scale float64 `json:"scale"`
|
||||||
} `json:"exponentialBuckets"`
|
} `json:"exponentialBuckets"`
|
||||||
ExplicitBuckets *struct {
|
ExplicitBuckets *struct {
|
||||||
Bounds []int64 `json:"bounds"`
|
Bounds []float64 `json:"bounds"`
|
||||||
} `json:"explicitBuckets"`
|
} `json:"explicitBuckets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ export function dropdownTypeahead2($compile) {
|
|||||||
'<input type="text"' + ' class="gf-form-input"' + ' spellcheck="false" style="display:none"></input>';
|
'<input type="text"' + ' class="gf-form-input"' + ' spellcheck="false" style="display:none"></input>';
|
||||||
|
|
||||||
const buttonTemplate =
|
const buttonTemplate =
|
||||||
'<a class="gf-form-input dropdown-toggle"' +
|
'<a class="{{buttonTemplateClass}} dropdown-toggle"' +
|
||||||
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
||||||
' ><i class="fa fa-plus"></i></a>';
|
' ><i class="fa fa-plus"></i></a>';
|
||||||
|
|
||||||
@ -137,9 +137,15 @@ export function dropdownTypeahead2($compile) {
|
|||||||
menuItems: '=dropdownTypeahead2',
|
menuItems: '=dropdownTypeahead2',
|
||||||
dropdownTypeaheadOnSelect: '&dropdownTypeaheadOnSelect',
|
dropdownTypeaheadOnSelect: '&dropdownTypeaheadOnSelect',
|
||||||
model: '=ngModel',
|
model: '=ngModel',
|
||||||
|
buttonTemplateClass: '@',
|
||||||
},
|
},
|
||||||
link: ($scope, elem, attrs) => {
|
link: ($scope, elem, attrs) => {
|
||||||
const $input = $(inputTemplate);
|
const $input = $(inputTemplate);
|
||||||
|
|
||||||
|
if (!$scope.buttonTemplateClass) {
|
||||||
|
$scope.buttonTemplateClass = 'gf-form-input';
|
||||||
|
}
|
||||||
|
|
||||||
const $button = $(buttonTemplate);
|
const $button = $(buttonTemplate);
|
||||||
const timeoutId = {
|
const timeoutId = {
|
||||||
blur: null,
|
blur: null,
|
||||||
|
@ -240,7 +240,7 @@ export class ValueSelectDropdownCtrl {
|
|||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
|
export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
|
||||||
return {
|
return {
|
||||||
scope: { variable: '=', onUpdated: '&' },
|
scope: { dashboard: '=', variable: '=', onUpdated: '&' },
|
||||||
templateUrl: 'public/app/partials/valueSelectDropdown.html',
|
templateUrl: 'public/app/partials/valueSelectDropdown.html',
|
||||||
controller: 'ValueSelectDropdownCtrl',
|
controller: 'ValueSelectDropdownCtrl',
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
@ -288,13 +288,13 @@ export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const cleanUp = $rootScope.$on('template-variable-value-updated', () => {
|
scope.vm.dashboard.on(
|
||||||
scope.vm.updateLinkText();
|
'template-variable-value-updated',
|
||||||
});
|
() => {
|
||||||
|
scope.vm.updateLinkText();
|
||||||
scope.$on('$destroy', () => {
|
},
|
||||||
cleanUp();
|
scope
|
||||||
});
|
);
|
||||||
|
|
||||||
scope.vm.init();
|
scope.vm.init();
|
||||||
},
|
},
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<label class="gf-form-label template-variable" ng-hide="variable.hide === 1">
|
<label class="gf-form-label template-variable" ng-hide="variable.hide === 1">
|
||||||
{{variable.label || variable.name}}
|
{{variable.label || variable.name}}
|
||||||
</label>
|
</label>
|
||||||
<value-select-dropdown ng-if="variable.type !== 'adhoc' && variable.type !== 'textbox'" variable="variable" on-updated="ctrl.variableUpdated(variable)"></value-select-dropdown>
|
<value-select-dropdown ng-if="variable.type !== 'adhoc' && variable.type !== 'textbox'" dashboard="ctrl.dashboard" variable="variable" on-updated="ctrl.variableUpdated(variable)"></value-select-dropdown>
|
||||||
<input type="text" ng-if="variable.type === 'textbox'" ng-model="variable.query" class="gf-form-input width-12" ng-blur="variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ng-keydown="$event.keyCode === 13 && variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ></input>
|
<input type="text" ng-if="variable.type === 'textbox'" ng-model="variable.query" class="gf-form-input width-12" ng-blur="variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ng-keydown="$event.keyCode === 13 && variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ></input>
|
||||||
</div>
|
</div>
|
||||||
<ad-hoc-filters ng-if="variable.type === 'adhoc'" variable="variable" dashboard="ctrl.dashboard"></ad-hoc-filters>
|
<ad-hoc-filters ng-if="variable.type === 'adhoc'" variable="variable" dashboard="ctrl.dashboard"></ad-hoc-filters>
|
||||||
|
@ -1,19 +1,38 @@
|
|||||||
<query-editor-row query-ctrl="ctrl" can-collapse="true" has-text-edit-mode="true">
|
<query-editor-row query-ctrl="ctrl" can-collapse="true" has-text-edit-mode="true">
|
||||||
|
<div ng-if="ctrl.target.rawQuery">
|
||||||
<div ng-if="ctrl.target.rawQuery">
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<textarea rows="3" class="gf-form-input" ng-model="ctrl.target.query" spellcheck="false" placeholder="InfluxDB Query" ng-model-onblur ng-change="ctrl.refresh()"></textarea>
|
<textarea
|
||||||
|
rows="3"
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.target.query"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="InfluxDB Query"
|
||||||
|
ng-model-onblur
|
||||||
|
ng-change="ctrl.refresh()"
|
||||||
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form-inline">
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword">FORMAT AS</label>
|
<label class="gf-form-label query-keyword">FORMAT AS</label>
|
||||||
<div class="gf-form-select-wrapper">
|
<div class="gf-form-select-wrapper">
|
||||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
<select
|
||||||
|
class="gf-form-input gf-size-auto"
|
||||||
|
ng-model="ctrl.target.resultFormat"
|
||||||
|
ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||||
|
ng-change="ctrl.refresh()"
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form max-width-25" ng-hide="ctrl.target.resultFormat === 'table'">
|
<div class="gf-form max-width-25" ng-hide="ctrl.target.resultFormat === 'table'">
|
||||||
<label class="gf-form-label query-keyword">ALIAS BY</label>
|
<label class="gf-form-label query-keyword">ALIAS BY</label>
|
||||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
<input
|
||||||
|
type="text"
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.target.alias"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="Naming pattern"
|
||||||
|
ng-blur="ctrl.refresh()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
@ -21,108 +40,154 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="!ctrl.target.rawQuery">
|
<div ng-if="!ctrl.target.rawQuery">
|
||||||
|
<div class="gf-form-inline">
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label query-keyword width-7">FROM</label>
|
||||||
|
|
||||||
<div class="gf-form-inline">
|
<metric-segment
|
||||||
<div class="gf-form">
|
segment="ctrl.policySegment"
|
||||||
<label class="gf-form-label query-keyword width-7">FROM</label>
|
get-options="ctrl.getPolicySegments()"
|
||||||
|
on-change="ctrl.policyChanged()"
|
||||||
|
></metric-segment>
|
||||||
|
<metric-segment
|
||||||
|
segment="ctrl.measurementSegment"
|
||||||
|
get-options="ctrl.getMeasurements($query)"
|
||||||
|
on-change="ctrl.measurementChanged()"
|
||||||
|
></metric-segment>
|
||||||
|
</div>
|
||||||
|
|
||||||
<metric-segment segment="ctrl.policySegment" get-options="ctrl.getPolicySegments()" on-change="ctrl.policyChanged()"></metric-segment>
|
<div class="gf-form">
|
||||||
<metric-segment segment="ctrl.measurementSegment" get-options="ctrl.getMeasurements($query)" on-change="ctrl.measurementChanged()"></metric-segment>
|
<label class="gf-form-label query-keyword">WHERE</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form" ng-repeat="segment in ctrl.tagSegments">
|
||||||
<label class="gf-form-label query-keyword">WHERE</label>
|
<metric-segment
|
||||||
</div>
|
segment="segment"
|
||||||
|
get-options="ctrl.getTagsOrValues(segment, $index)"
|
||||||
|
on-change="ctrl.tagSegmentUpdated(segment, $index)"
|
||||||
|
></metric-segment>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form" ng-repeat="segment in ctrl.tagSegments">
|
<div class="gf-form gf-form--grow">
|
||||||
<metric-segment segment="segment" get-options="ctrl.getTagsOrValues(segment, $index)" on-change="ctrl.tagSegmentUpdated(segment, $index)"></metric-segment>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form">
|
||||||
</div>
|
<label class="gf-form-label query-keyword width-7"> <span ng-show="$index === 0">SELECT</span> </label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
|
<div class="gf-form" ng-repeat="part in selectParts">
|
||||||
<div class="gf-form">
|
<query-part-editor
|
||||||
<label class="gf-form-label query-keyword width-7">
|
class="gf-form-label query-part"
|
||||||
<span ng-show="$index === 0">SELECT</span>
|
part="part"
|
||||||
</label>
|
handle-event="ctrl.handleSelectPartEvent(selectParts, part, $event)"
|
||||||
</div>
|
>
|
||||||
|
</query-part-editor>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form" ng-repeat="part in selectParts">
|
<div class="gf-form">
|
||||||
<query-part-editor class="gf-form-label query-part" part="part" handle-event="ctrl.handleSelectPartEvent(selectParts, part, $event)">
|
<label
|
||||||
</query-part-editor>
|
class="dropdown"
|
||||||
</div>
|
dropdown-typeahead2="ctrl.selectMenu"
|
||||||
|
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||||
|
button-template-class="gf-form-label query-part"
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form gf-form--grow">
|
||||||
<label class="dropdown"
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
dropdown-typeahead="ctrl.selectMenu"
|
</div>
|
||||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
</div>
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form">
|
||||||
</div>
|
<label class="gf-form-label query-keyword width-7">
|
||||||
</div>
|
<span>GROUP BY</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="gf-form-inline">
|
<query-part-editor
|
||||||
<div class="gf-form">
|
ng-repeat="part in ctrl.queryModel.groupByParts"
|
||||||
<label class="gf-form-label query-keyword width-7">
|
part="part"
|
||||||
<span>GROUP BY</span>
|
class="gf-form-label query-part"
|
||||||
</label>
|
handle-event="ctrl.handleGroupByPartEvent(part, $index, $event)"
|
||||||
|
>
|
||||||
|
</query-part-editor>
|
||||||
|
</div>
|
||||||
|
|
||||||
<query-part-editor ng-repeat="part in ctrl.queryModel.groupByParts"
|
<div class="gf-form">
|
||||||
part="part" class="gf-form-label query-part"
|
<metric-segment
|
||||||
handle-event="ctrl.handleGroupByPartEvent(part, $index, $event)">
|
segment="ctrl.groupBySegment"
|
||||||
</query-part-editor>
|
get-options="ctrl.getGroupByOptions()"
|
||||||
</div>
|
on-change="ctrl.groupByAction(part, $index)"
|
||||||
|
></metric-segment>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form gf-form--grow">
|
||||||
<metric-segment segment="ctrl.groupBySegment" get-options="ctrl.getGroupByOptions()" on-change="ctrl.groupByAction(part, $index)"></metric-segment>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="ctrl.target.orderByTime === 'DESC'">
|
<div class="gf-form-inline" ng-if="ctrl.target.orderByTime === 'DESC'">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword width-7">ORDER BY</label>
|
<label class="gf-form-label query-keyword width-7">ORDER BY</label>
|
||||||
<label class="gf-form-label pointer" ng-click="ctrl.removeOrderByTime()">time <span class="query-keyword">DESC</span> <i class="fa fa-remove"></i></label>
|
<label class="gf-form-label pointer" ng-click="ctrl.removeOrderByTime()"
|
||||||
|
>time <span class="query-keyword">DESC</span> <i class="fa fa-remove"></i
|
||||||
|
></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="ctrl.target.limit">
|
<div class="gf-form-inline" ng-if="ctrl.target.limit">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword width-7">LIMIT</label>
|
<label class="gf-form-label query-keyword width-7">LIMIT</label>
|
||||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.limit" spellcheck='false' placeholder="No Limit" ng-blur="ctrl.refresh()">
|
<input
|
||||||
|
type="text"
|
||||||
|
class="gf-form-input width-9"
|
||||||
|
ng-model="ctrl.target.limit"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="No Limit"
|
||||||
|
ng-blur="ctrl.refresh()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="ctrl.target.slimit">
|
<div class="gf-form-inline" ng-if="ctrl.target.slimit">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword width-7">SLIMIT</label>
|
<label class="gf-form-label query-keyword width-7">SLIMIT</label>
|
||||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.slimit" spellcheck='false' placeholder="No Limit" ng-blur="ctrl.refresh()">
|
<input
|
||||||
|
type="text"
|
||||||
|
class="gf-form-input width-9"
|
||||||
|
ng-model="ctrl.target.slimit"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="No Limit"
|
||||||
|
ng-blur="ctrl.refresh()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="ctrl.target.tz">
|
<div class="gf-form-inline" ng-if="ctrl.target.tz">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword width-7">tz</label>
|
<label class="gf-form-label query-keyword width-7">tz</label>
|
||||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.tz" spellcheck='false' placeholder="No Timezone" ng-blur="ctrl.refresh()">
|
<input
|
||||||
|
type="text"
|
||||||
|
class="gf-form-input width-9"
|
||||||
|
ng-model="ctrl.target.tz"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="No Timezone"
|
||||||
|
ng-blur="ctrl.refresh()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
@ -133,7 +198,12 @@
|
|||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label query-keyword width-7">FORMAT AS</label>
|
<label class="gf-form-label query-keyword width-7">FORMAT AS</label>
|
||||||
<div class="gf-form-select-wrapper">
|
<div class="gf-form-select-wrapper">
|
||||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
<select
|
||||||
|
class="gf-form-input gf-size-auto"
|
||||||
|
ng-model="ctrl.target.resultFormat"
|
||||||
|
ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||||
|
ng-change="ctrl.refresh()"
|
||||||
|
></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
@ -141,15 +211,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-hide="ctrl.target.resultFormat === 'table'">
|
<div class="gf-form-inline" ng-hide="ctrl.target.resultFormat === 'table'">
|
||||||
<div class="gf-form max-width-30">
|
<div class="gf-form max-width-30">
|
||||||
<label class="gf-form-label query-keyword width-7">ALIAS BY</label>
|
<label class="gf-form-label query-keyword width-7">ALIAS BY</label>
|
||||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
<input
|
||||||
|
type="text"
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.target.alias"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="Naming pattern"
|
||||||
|
ng-blur="ctrl.refresh()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</query-editor-row>
|
</query-editor-row>
|
||||||
|
@ -45,8 +45,10 @@
|
|||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="dropdown"
|
<label class="dropdown"
|
||||||
dropdown-typeahead="ctrl.selectMenu"
|
dropdown-typeahead2="ctrl.selectMenu"
|
||||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||||
|
button-template-class="gf-form-label query-part"
|
||||||
|
>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -45,8 +45,10 @@
|
|||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="dropdown"
|
<label class="dropdown"
|
||||||
dropdown-typeahead="ctrl.selectMenu"
|
dropdown-typeahead2="ctrl.selectMenu"
|
||||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||||
|
button-template-class="gf-form-label query-part"
|
||||||
|
>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ export class ResultTransformer {
|
|||||||
table.columns.push({ text: 'Time', type: 'time' });
|
table.columns.push({ text: 'Time', type: 'time' });
|
||||||
_.each(sortedLabels, (label, labelIndex) => {
|
_.each(sortedLabels, (label, labelIndex) => {
|
||||||
metricLabels[label] = labelIndex + 1;
|
metricLabels[label] = labelIndex + 1;
|
||||||
table.columns.push({ text: label, filterable: !label.startsWith('__') });
|
table.columns.push({ text: label, filterable: true });
|
||||||
});
|
});
|
||||||
const valueText = resultCount > 1 || valueWithRefId ? `Value #${refId}` : 'Value';
|
const valueText = resultCount > 1 || valueWithRefId ? `Value #${refId}` : 'Value';
|
||||||
table.columns.push({ text: valueText });
|
table.columns.push({ text: valueText });
|
||||||
|
@ -66,11 +66,12 @@ describe('Prometheus Result Transformer', () => {
|
|||||||
]);
|
]);
|
||||||
expect(table.columns).toMatchObject([
|
expect(table.columns).toMatchObject([
|
||||||
{ text: 'Time', type: 'time' },
|
{ text: 'Time', type: 'time' },
|
||||||
{ text: '__name__' },
|
{ text: '__name__', filterable: true },
|
||||||
{ text: 'instance' },
|
{ text: 'instance', filterable: true },
|
||||||
{ text: 'job' },
|
{ text: 'job' },
|
||||||
{ text: 'Value' },
|
{ text: 'Value' },
|
||||||
]);
|
]);
|
||||||
|
expect(table.columns[4].filterable).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should column title include refId if response count is more than 2', () => {
|
it('should column title include refId if response count is more than 2', () => {
|
||||||
|
@ -49,7 +49,8 @@ describe('Aggregations', () => {
|
|||||||
});
|
});
|
||||||
it('', () => {
|
it('', () => {
|
||||||
const options = wrapper.state().aggOptions[0].options;
|
const options = wrapper.state().aggOptions[0].options;
|
||||||
expect(options.length).toEqual(5);
|
|
||||||
|
expect(options.length).toEqual(10);
|
||||||
expect(options.map(o => o.value)).toEqual(expect.arrayContaining(['REDUCE_NONE']));
|
expect(options.map(o => o.value)).toEqual(expect.arrayContaining(['REDUCE_NONE']));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -73,7 +73,7 @@ export class Aggregations extends React.Component<Props, State> {
|
|||||||
value={crossSeriesReducer}
|
value={crossSeriesReducer}
|
||||||
variables={templateSrv.variables}
|
variables={templateSrv.variables}
|
||||||
options={aggOptions}
|
options={aggOptions}
|
||||||
placeholder="Select Aggregation"
|
placeholder="Select Reducer"
|
||||||
className="width-15"
|
className="width-15"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -185,7 +185,7 @@ export class Metrics extends React.Component<Props, State> {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
placeholder="Select Metric"
|
placeholder="Select Metric"
|
||||||
className="width-15"
|
className="width-26"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="gf-form gf-form--grow">
|
<div className="gf-form gf-form--grow">
|
||||||
|
@ -28,7 +28,7 @@ Array [
|
|||||||
<div
|
<div
|
||||||
className="css-0 gf-form-select-box__placeholder"
|
className="css-0 gf-form-select-box__placeholder"
|
||||||
>
|
>
|
||||||
Select Aggregation
|
Select Reducer
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="css-0"
|
className="css-0"
|
||||||
|
@ -72,7 +72,7 @@ Array [
|
|||||||
Metric
|
Metric
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
className="css-0 gf-form-input gf-form-input--form-dropdown width-15"
|
className="css-0 gf-form-input gf-form-input--form-dropdown width-26"
|
||||||
onKeyDown={[Function]}
|
onKeyDown={[Function]}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -196,7 +196,7 @@ Array [
|
|||||||
<div
|
<div
|
||||||
className="css-0 gf-form-select-box__placeholder"
|
className="css-0 gf-form-select-box__placeholder"
|
||||||
>
|
>
|
||||||
Select Aggregation
|
Select Reducer
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="css-0"
|
className="css-0"
|
||||||
|
@ -189,7 +189,7 @@ export const aggOptions = [
|
|||||||
ValueTypes.BOOL,
|
ValueTypes.BOOL,
|
||||||
ValueTypes.STRING,
|
ValueTypes.STRING,
|
||||||
],
|
],
|
||||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'count true',
|
text: 'count true',
|
||||||
@ -207,25 +207,25 @@ export const aggOptions = [
|
|||||||
text: '99th percentile',
|
text: '99th percentile',
|
||||||
value: 'REDUCE_PERCENTILE_99',
|
value: 'REDUCE_PERCENTILE_99',
|
||||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '95th percentile',
|
text: '95th percentile',
|
||||||
value: 'REDUCE_PERCENTILE_95',
|
value: 'REDUCE_PERCENTILE_95',
|
||||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '50th percentile',
|
text: '50th percentile',
|
||||||
value: 'REDUCE_PERCENTILE_50',
|
value: 'REDUCE_PERCENTILE_50',
|
||||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '5th percentile',
|
text: '5th percentile',
|
||||||
value: 'REDUCE_PERCENTILE_05',
|
value: 'REDUCE_PERCENTILE_05',
|
||||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ export function SeriesOverridesCtrl($scope, $element, popoverSrv) {
|
|||||||
const option = {
|
const option = {
|
||||||
text: name,
|
text: name,
|
||||||
propertyName: propertyName,
|
propertyName: propertyName,
|
||||||
index: $scope.overrideMenu.lenght,
|
index: $scope.overrideMenu.length,
|
||||||
values: values,
|
values: values,
|
||||||
submenu: _.map(values, value => {
|
submenu: _.map(values, value => {
|
||||||
return { text: String(value), value: value };
|
return { text: String(value), value: value };
|
||||||
|
@ -1,110 +1,194 @@
|
|||||||
|
<div class="editor-row">
|
||||||
|
<div class="section gf-form-group">
|
||||||
|
<h5 class="section-heading">Draw Modes</h5>
|
||||||
|
<gf-form-switch
|
||||||
|
class="gf-form"
|
||||||
|
label="Bars"
|
||||||
|
label-class="width-5"
|
||||||
|
checked="ctrl.panel.bars"
|
||||||
|
on-change="ctrl.render()"
|
||||||
|
></gf-form-switch>
|
||||||
|
<gf-form-switch
|
||||||
|
class="gf-form"
|
||||||
|
label="Lines"
|
||||||
|
label-class="width-5"
|
||||||
|
checked="ctrl.panel.lines"
|
||||||
|
on-change="ctrl.render()"
|
||||||
|
></gf-form-switch>
|
||||||
|
<gf-form-switch
|
||||||
|
class="gf-form"
|
||||||
|
label="Points"
|
||||||
|
label-class="width-5"
|
||||||
|
checked="ctrl.panel.points"
|
||||||
|
on-change="ctrl.render()"
|
||||||
|
></gf-form-switch>
|
||||||
|
</div>
|
||||||
|
<div class="section gf-form-group">
|
||||||
|
<h5 class="section-heading">Mode Options</h5>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-8">Fill</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.fill"
|
||||||
|
ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
ng-disabled="!ctrl.panel.lines"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-8">Line Width</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.linewidth"
|
||||||
|
ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
ng-disabled="!ctrl.panel.lines"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<gf-form-switch
|
||||||
|
ng-disabled="!ctrl.panel.lines"
|
||||||
|
class="gf-form"
|
||||||
|
label="Staircase"
|
||||||
|
label-class="width-8"
|
||||||
|
checked="ctrl.panel.steppedLine"
|
||||||
|
on-change="ctrl.render()"
|
||||||
|
>
|
||||||
|
</gf-form-switch>
|
||||||
|
<div class="gf-form" ng-if="ctrl.panel.points">
|
||||||
|
<label class="gf-form-label width-8">Point Radius</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-5">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.pointradius"
|
||||||
|
ng-options="f for f in [0.5,1,2,3,4,5,6,7,8,9,10]"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section gf-form-group">
|
||||||
|
<h5 class="section-heading">Hover tooltip</h5>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-9">Mode</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-8">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.tooltip.shared"
|
||||||
|
ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-9">Sort order</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-8">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.tooltip.sort"
|
||||||
|
ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form" ng-show="ctrl.panel.stack">
|
||||||
|
<label class="gf-form-label width-9">Stacked value</label>
|
||||||
|
<div class="gf-form-select-wrapper max-width-8">
|
||||||
|
<select
|
||||||
|
class="gf-form-input"
|
||||||
|
ng-model="ctrl.panel.tooltip.value_type"
|
||||||
|
ng-options="f for f in ['cumulative','individual']"
|
||||||
|
ng-change="ctrl.render()"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="editor-row">
|
<div class="section gf-form-group">
|
||||||
<div class="section gf-form-group">
|
<h5 class="section-heading">Stacking & Null value</h5>
|
||||||
<h5 class="section-heading">Draw Modes</h5>
|
<gf-form-switch
|
||||||
<gf-form-switch class="gf-form" label="Bars" label-class="width-5" checked="ctrl.panel.bars" on-change="ctrl.render()"></gf-form-switch>
|
class="gf-form"
|
||||||
<gf-form-switch class="gf-form" label="Lines" label-class="width-5" checked="ctrl.panel.lines" on-change="ctrl.render()"></gf-form-switch>
|
label="Stack"
|
||||||
<gf-form-switch class="gf-form" label="Points" label-class="width-5" checked="ctrl.panel.points" on-change="ctrl.render()"></gf-form-switch>
|
label-class="width-7"
|
||||||
</div>
|
checked="ctrl.panel.stack"
|
||||||
<div class="section gf-form-group">
|
on-change="ctrl.refresh()"
|
||||||
<h5 class="section-heading">Mode Options</h5>
|
>
|
||||||
<div class="gf-form">
|
</gf-form-switch>
|
||||||
<label class="gf-form-label width-8">Fill</label>
|
<gf-form-switch
|
||||||
<div class="gf-form-select-wrapper max-width-5">
|
class="gf-form"
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()" ng-disabled="!ctrl.panel.lines"></select>
|
ng-show="ctrl.panel.stack"
|
||||||
</div>
|
label="Percent"
|
||||||
</div>
|
label-class="width-7"
|
||||||
<div class="gf-form">
|
checked="ctrl.panel.percentage"
|
||||||
<label class="gf-form-label width-8">Line Width</label>
|
on-change="ctrl.render()"
|
||||||
<div class="gf-form-select-wrapper max-width-5">
|
>
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()" ng-disabled="!ctrl.panel.lines"></select>
|
</gf-form-switch>
|
||||||
</div>
|
<div class="gf-form">
|
||||||
</div>
|
<label class="gf-form-label width-7">Null value</label>
|
||||||
<gf-form-switch ng-disabled="!ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
|
<div class="gf-form-select-wrapper">
|
||||||
</gf-form-switch>
|
<select
|
||||||
<div class="gf-form" ng-if="ctrl.panel.points">
|
class="gf-form-input max-width-9"
|
||||||
<label class="gf-form-label width-8">Point Radius</label>
|
ng-model="ctrl.panel.nullPointMode"
|
||||||
<div class="gf-form-select-wrapper max-width-5">
|
ng-options="f for f in ['connected', 'null', 'null as zero']"
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.pointradius" ng-options="f for f in [0.5,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
ng-change="ctrl.render()"
|
||||||
</div>
|
></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section gf-form-group">
|
</div>
|
||||||
<h5 class="section-heading">Hover tooltip</h5>
|
</div>
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label width-9">Mode</label>
|
|
||||||
<div class="gf-form-select-wrapper max-width-8">
|
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.shared" ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]" ng-change="ctrl.render()"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label width-9">Sort order</label>
|
|
||||||
<div class="gf-form-select-wrapper max-width-8">
|
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.sort" ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]" ng-change="ctrl.render()"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form" ng-show="ctrl.panel.stack">
|
|
||||||
<label class="gf-form-label width-9">Stacked value</label>
|
|
||||||
<div class="gf-form-select-wrapper max-width-8">
|
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="ctrl.render()"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section gf-form-group">
|
<div>
|
||||||
<h5 class="section-heading">Stacking & Null value</h5>
|
<div class="gf-form-inline" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
|
||||||
<gf-form-switch class="gf-form" label="Stack" label-class="width-7" checked="ctrl.panel.stack" on-change="ctrl.refresh()">
|
<div class="gf-form">
|
||||||
</gf-form-switch>
|
<label class="gf-form-label">alias or regex</label>
|
||||||
<gf-form-switch class="gf-form" ng-show="ctrl.panel.stack" label="Percent" label-class="width-7" checked="ctrl.panel.percentage" on-change="ctrl.render()">
|
</div>
|
||||||
</gf-form-switch>
|
<div class="gf-form width-15">
|
||||||
<div class="gf-form">
|
<input
|
||||||
<label class="gf-form-label width-7">Null value</label>
|
type="text"
|
||||||
<div class="gf-form-select-wrapper">
|
ng-model="override.alias"
|
||||||
<select class="gf-form-input max-width-9" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="ctrl.render()"></select>
|
bs-typeahead="getSeriesNames"
|
||||||
</div>
|
ng-blur="ctrl.render()"
|
||||||
</div>
|
data-min-length="0"
|
||||||
</div>
|
data-items="100"
|
||||||
</div>
|
class="gf-form-input width-15"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form" ng-repeat="option in currentOverrides">
|
||||||
|
<label class="gf-form-label">
|
||||||
|
<i class="pointer fa fa-remove" ng-click="removeOverride(option)"></i>
|
||||||
|
<span ng-show="option.propertyName === 'color'">
|
||||||
|
Color: <i class="fa fa-circle" ng-style="{color:option.value}"></i>
|
||||||
|
</span>
|
||||||
|
<span ng-show="option.propertyName !== 'color'"> {{ option.name }}: {{ option.value }} </span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="gf-form">
|
||||||
<div class="gf-form-inline" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
|
<span
|
||||||
<div class="gf-form">
|
class="dropdown"
|
||||||
<label class="gf-form-label">alias or regex</label>
|
dropdown-typeahead2="overrideMenu"
|
||||||
</div>
|
dropdown-typeahead-on-select="setOverride($item, $subItem)"
|
||||||
<div class="gf-form width-15">
|
button-template-class="gf-form-label"
|
||||||
<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="ctrl.render()" data-min-length=0 data-items=100 class="gf-form-input width-15">
|
>
|
||||||
</div>
|
</span>
|
||||||
<div class="gf-form" ng-repeat="option in currentOverrides">
|
</div>
|
||||||
<label class="gf-form-label">
|
|
||||||
<i class="pointer fa fa-remove" ng-click="removeOverride(option)"></i>
|
|
||||||
<span ng-show="option.propertyName === 'color'">
|
|
||||||
Color: <i class="fa fa-circle" ng-style="{color:option.value}"></i>
|
|
||||||
</span>
|
|
||||||
<span ng-show="option.propertyName !== 'color'">
|
|
||||||
{{option.name}}: {{option.value}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form">
|
<div class="gf-form gf-form--grow">
|
||||||
<span class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form gf-form--grow">
|
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label">
|
|
||||||
<i class="fa fa-trash pointer" ng-click="ctrl.removeSeriesOverride(override)"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form-button-row">
|
|
||||||
<button class="btn btn-inverse" ng-click="ctrl.addSeriesOverride()">
|
|
||||||
<i class="fa fa-plus"></i> Add series override<tip>Regex match example: /server[0-3]/i </tip>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label">
|
||||||
|
<i class="fa fa-trash pointer" ng-click="ctrl.removeSeriesOverride(override)"></i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gf-form-button-row">
|
||||||
|
<button class="btn btn-inverse" ng-click="ctrl.addSeriesOverride()">
|
||||||
|
<i class="fa fa-plus"></i> Add series override<tip>Regex match example: /server[0-3]/i </tip>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user