mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' into mssql_datasource
This commit is contained in:
commit
d2267643ed
@ -15,9 +15,13 @@
|
|||||||
* **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist)
|
* **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist)
|
||||||
* **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps)
|
* **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps)
|
||||||
|
|
||||||
# 5.0.2 (unrelease)
|
# 5.0.2 (2018-03-14)
|
||||||
|
* **Mysql**: Mysql panic occurring occasionally upon Grafana dashboard access [#11155](https://github.com/grafana/grafana/issues/11155)
|
||||||
|
* **Dashboards**: Should be possible to browse dashboard using only uid [#11231](https://github.com/grafana/grafana/issues/11231)
|
||||||
|
* **Alerting**: Fixes bug where alerts from hidden panels where deleted [#11222](https://github.com/grafana/grafana/issues/11222)
|
||||||
|
* **Import**: Fixes bug where dashboards with alerts couldn't be imported [#11227](https://github.com/grafana/grafana/issues/11227)
|
||||||
* **Teams**: Remove quota restrictions from teams [#11220](https://github.com/grafana/grafana/issues/11220)
|
* **Teams**: Remove quota restrictions from teams [#11220](https://github.com/grafana/grafana/issues/11220)
|
||||||
|
* **Render**: Fixes bug with legacy url redirection for panel rendering [#11180](https://github.com/grafana/grafana/issues/11180)
|
||||||
|
|
||||||
# 5.0.1 (2018-03-08)
|
# 5.0.1 (2018-03-08)
|
||||||
|
|
||||||
|
@ -9,9 +9,6 @@ Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Grafana v5 Alpha Preview
|
|
||||||
Grafana master is now v5.0 alpha. This is going to be the biggest and most foundational release Grafana has ever had, coming with a ton of UX improvements, a new dashboard grid engine, dashboard folders, user teams and permissions. Checkout out this [video preview](https://www.youtube.com/watch?v=BC_YRNpqj5k) of Grafana v5.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Head to [docs.grafana.org](http://docs.grafana.org/installation/) and [download](https://grafana.com/get)
|
Head to [docs.grafana.org](http://docs.grafana.org/installation/) and [download](https://grafana.com/get)
|
||||||
the latest release.
|
the latest release.
|
||||||
@ -27,7 +24,7 @@ the latest master builds [here](https://grafana.com/grafana/download)
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- Go 1.9
|
- Go 1.10
|
||||||
- NodeJS LTS
|
- NodeJS LTS
|
||||||
|
|
||||||
### Building the backend
|
### Building the backend
|
||||||
|
@ -6,3 +6,10 @@
|
|||||||
- "9300:9300"
|
- "9300:9300"
|
||||||
volumes:
|
volumes:
|
||||||
- ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
|
- ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
|
||||||
|
|
||||||
|
fake-elastic-data:
|
||||||
|
image: grafana/fake-data-gen
|
||||||
|
network_mode: bridge
|
||||||
|
environment:
|
||||||
|
FD_DATASOURCE: elasticsearch
|
||||||
|
FD_PORT: 9200
|
||||||
|
@ -6,3 +6,10 @@
|
|||||||
ports:
|
ports:
|
||||||
- "10200:9200"
|
- "10200:9200"
|
||||||
- "10300:9300"
|
- "10300:9300"
|
||||||
|
|
||||||
|
fake-elastic5-data:
|
||||||
|
image: grafana/fake-data-gen
|
||||||
|
network_mode: bridge
|
||||||
|
environment:
|
||||||
|
FD_DATASOURCE: elasticsearch
|
||||||
|
FD_PORT: 10200
|
||||||
|
1161
docker/blocks/graphite1/big-dashboard.json
Normal file
1161
docker/blocks/graphite1/big-dashboard.json
Normal file
File diff suppressed because it is too large
Load Diff
1179
docker/blocks/graphite11/big-dashboard.json
Normal file
1179
docker/blocks/graphite11/big-dashboard.json
Normal file
File diff suppressed because it is too large
Load Diff
18
docker/blocks/graphite11/docker-compose.yaml
Normal file
18
docker/blocks/graphite11/docker-compose.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
graphite11:
|
||||||
|
image: graphiteapp/graphite-statsd
|
||||||
|
ports:
|
||||||
|
- "8180:80"
|
||||||
|
- "2103-2104:2003-2004"
|
||||||
|
- "2123-2124:2023-2024"
|
||||||
|
- "8225:8125/udp"
|
||||||
|
- "8226:8126"
|
||||||
|
|
||||||
|
fake-graphite11-data:
|
||||||
|
image: grafana/fake-data-gen
|
||||||
|
network_mode: bridge
|
||||||
|
environment:
|
||||||
|
FD_DATASOURCE: graphite
|
||||||
|
FD_PORT: 2103
|
||||||
|
FD_GRAPHITE_VERSION: 1.1
|
||||||
|
depends_on:
|
||||||
|
- graphite11
|
@ -28,4 +28,4 @@
|
|||||||
build: blocks/prometheus_random_data
|
build: blocks/prometheus_random_data
|
||||||
network_mode: host
|
network_mode: host
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8081:8080"
|
||||||
|
@ -36,4 +36,4 @@ scrape_configs:
|
|||||||
|
|
||||||
- job_name: 'prometheus-random-data'
|
- job_name: 'prometheus-random-data'
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ['127.0.0.1:8080']
|
- targets: ['127.0.0.1:8081']
|
||||||
|
@ -28,4 +28,4 @@
|
|||||||
build: blocks/prometheus_random_data
|
build: blocks/prometheus_random_data
|
||||||
network_mode: host
|
network_mode: host
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8081:8080"
|
||||||
|
@ -36,4 +36,4 @@ scrape_configs:
|
|||||||
|
|
||||||
- job_name: 'prometheus-random-data'
|
- job_name: 'prometheus-random-data'
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ['127.0.0.1:8080']
|
- targets: ['127.0.0.1:8081']
|
||||||
|
@ -58,6 +58,8 @@ Recipient | allows you to override the Slack recipient.
|
|||||||
Mention | make it possible to include a mention in the Slack notification sent by Grafana. Ex @here or @channel
|
Mention | make it possible to include a mention in the Slack notification sent by Grafana. Ex @here or @channel
|
||||||
Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination.
|
Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination.
|
||||||
|
|
||||||
|
If you are using the token for a slack bot, then you have to invite the bot to the channel you want to send notifications and add the channel to the recipient field.
|
||||||
|
|
||||||
### PagerDuty
|
### PagerDuty
|
||||||
|
|
||||||
To set up PagerDuty, all you have to do is to provide an API key.
|
To set up PagerDuty, all you have to do is to provide an API key.
|
||||||
|
@ -15,7 +15,7 @@ weight = 1
|
|||||||
|
|
||||||
Description | Download
|
Description | Download
|
||||||
------------ | -------------
|
------------ | -------------
|
||||||
Stable for Debian-based Linux | [grafana_5.0.1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.1_amd64.deb)
|
Stable for Debian-based Linux | [grafana_5.0.2_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.2_amd64.deb)
|
||||||
|
|
||||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||||
installation.
|
installation.
|
||||||
@ -24,9 +24,9 @@ installation.
|
|||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.1_amd64.deb
|
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.2_amd64.deb
|
||||||
sudo apt-get install -y adduser libfontconfig
|
sudo apt-get install -y adduser libfontconfig
|
||||||
sudo dpkg -i grafana_5.0.1_amd64.deb
|
sudo dpkg -i grafana_5.0.2_amd64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
## APT Repository
|
## APT Repository
|
||||||
|
@ -83,7 +83,7 @@ $ docker run \
|
|||||||
-d \
|
-d \
|
||||||
-p 3000:3000 \
|
-p 3000:3000 \
|
||||||
--name grafana \
|
--name grafana \
|
||||||
grafana/grafana:4.5.2
|
grafana/grafana:5.0.2
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuring AWS Credentials for CloudWatch Support
|
## Configuring AWS Credentials for CloudWatch Support
|
||||||
|
@ -15,7 +15,7 @@ weight = 2
|
|||||||
|
|
||||||
Description | Download
|
Description | Download
|
||||||
------------ | -------------
|
------------ | -------------
|
||||||
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.1 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.1-1.x86_64.rpm)
|
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.2 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm)
|
||||||
|
|
||||||
|
|
||||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||||
@ -26,7 +26,7 @@ installation.
|
|||||||
You can install Grafana using Yum directly.
|
You can install Grafana using Yum directly.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.1-1.x86_64.rpm
|
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm
|
||||||
```
|
```
|
||||||
|
|
||||||
Or install manually using `rpm`.
|
Or install manually using `rpm`.
|
||||||
@ -34,15 +34,15 @@ Or install manually using `rpm`.
|
|||||||
#### On CentOS / Fedora / Redhat:
|
#### On CentOS / Fedora / Redhat:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.1-1.x86_64.rpm
|
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2-1.x86_64.rpm
|
||||||
$ sudo yum install initscripts fontconfig
|
$ sudo yum install initscripts fontconfig
|
||||||
$ sudo rpm -Uvh grafana-5.0.1-1.x86_64.rpm
|
$ sudo rpm -Uvh grafana-5.0.2-1.x86_64.rpm
|
||||||
```
|
```
|
||||||
|
|
||||||
#### On OpenSuse:
|
#### On OpenSuse:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ sudo rpm -i --nodeps grafana-5.0.1-1.x86_64.rpm
|
$ sudo rpm -i --nodeps grafana-5.0.2-1.x86_64.rpm
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install via YUM Repository
|
## Install via YUM Repository
|
||||||
|
@ -13,7 +13,7 @@ weight = 3
|
|||||||
|
|
||||||
Description | Download
|
Description | Download
|
||||||
------------ | -------------
|
------------ | -------------
|
||||||
Latest stable package for Windows | [grafana-5.0.1.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.1.windows-x64.zip)
|
Latest stable package for Windows | [grafana-5.0.2.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.2.windows-x64.zip)
|
||||||
|
|
||||||
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
|
||||||
installation.
|
installation.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env bash
|
#! /usr/bin/env bash
|
||||||
version=5.0.1
|
version=5.0.2
|
||||||
|
|
||||||
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${version}_amd64.deb
|
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${version}_amd64.deb
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ func (hs *HttpServer) registerRoutes() {
|
|||||||
r.Get("/plugins/:id/page/:page", reqSignedIn, Index)
|
r.Get("/plugins/:id/page/:page", reqSignedIn, Index)
|
||||||
|
|
||||||
r.Get("/d/:uid/:slug", reqSignedIn, Index)
|
r.Get("/d/:uid/:slug", reqSignedIn, Index)
|
||||||
|
r.Get("/d/:uid", reqSignedIn, Index)
|
||||||
r.Get("/dashboard/db/:slug", reqSignedIn, redirectFromLegacyDashboardUrl, Index)
|
r.Get("/dashboard/db/:slug", reqSignedIn, redirectFromLegacyDashboardUrl, Index)
|
||||||
r.Get("/dashboard/script/*", reqSignedIn, Index)
|
r.Get("/dashboard/script/*", reqSignedIn, Index)
|
||||||
r.Get("/dashboard-solo/snapshot/*", Index)
|
r.Get("/dashboard-solo/snapshot/*", Index)
|
||||||
|
@ -72,7 +72,9 @@ func RenderToPng(params *RenderOpts) (string, error) {
|
|||||||
localDomain = setting.HttpAddr
|
localDomain = setting.HttpAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("%s://%s:%s/%s", setting.Protocol, localDomain, setting.HttpPort, params.Path)
|
// &render=1 signals to the legacy redirect layer to
|
||||||
|
// avoid redirect these requests.
|
||||||
|
url := fmt.Sprintf("%s://%s:%s/%s&render=1", setting.Protocol, localDomain, setting.HttpPort, params.Path)
|
||||||
|
|
||||||
binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, executable))
|
binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, executable))
|
||||||
scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js"))
|
scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js"))
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,9 +37,14 @@ func RedirectFromLegacyDashboardUrl() macaron.Handler {
|
|||||||
func RedirectFromLegacyDashboardSoloUrl() macaron.Handler {
|
func RedirectFromLegacyDashboardSoloUrl() macaron.Handler {
|
||||||
return func(c *m.ReqContext) {
|
return func(c *m.ReqContext) {
|
||||||
slug := c.Params("slug")
|
slug := c.Params("slug")
|
||||||
|
renderRequest := c.QueryBool("render")
|
||||||
|
|
||||||
if slug != "" {
|
if slug != "" {
|
||||||
if url, err := getDashboardUrlBySlug(c.OrgId, slug); err == nil {
|
if url, err := getDashboardUrlBySlug(c.OrgId, slug); err == nil {
|
||||||
|
if renderRequest && strings.Contains(url, setting.AppSubUrl) {
|
||||||
|
url = strings.Replace(url, setting.AppSubUrl, "", 1)
|
||||||
|
}
|
||||||
|
|
||||||
url = strings.Replace(url, "/d/", "/d-solo/", 1)
|
url = strings.Replace(url, "/d/", "/d-solo/", 1)
|
||||||
url = fmt.Sprintf("%s?%s", url, c.Req.URL.RawQuery)
|
url = fmt.Sprintf("%s?%s", url, c.Req.URL.RawQuery)
|
||||||
c.Redirect(url, 301)
|
c.Redirect(url, 301)
|
||||||
|
@ -80,7 +80,7 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
|||||||
User: cmd.User,
|
User: cmd.User,
|
||||||
}
|
}
|
||||||
|
|
||||||
savedDash, err := dashboards.NewService().SaveDashboard(dto)
|
savedDash, err := dashboards.NewService().ImportDashboard(dto)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,6 +74,21 @@ func (e *DashAlertExtractor) GetAlertFromPanels(jsonWithPanels *simplejson.Json)
|
|||||||
|
|
||||||
for _, panelObj := range jsonWithPanels.Get("panels").MustArray() {
|
for _, panelObj := range jsonWithPanels.Get("panels").MustArray() {
|
||||||
panel := simplejson.NewFromAny(panelObj)
|
panel := simplejson.NewFromAny(panelObj)
|
||||||
|
|
||||||
|
collapsedJson, collapsed := panel.CheckGet("collapsed")
|
||||||
|
// check if the panel is collapsed
|
||||||
|
if collapsed && collapsedJson.MustBool() {
|
||||||
|
|
||||||
|
// extract alerts from sub panels for collapsed panels
|
||||||
|
als, err := e.GetAlertFromPanels(panel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
alerts = append(alerts, als...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
jsonAlert, hasAlert := panel.CheckGet("alert")
|
jsonAlert, hasAlert := panel.CheckGet("alert")
|
||||||
|
|
||||||
if !hasAlert {
|
if !hasAlert {
|
||||||
|
@ -22,6 +22,7 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|||||||
defaultDs := &m.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true}
|
defaultDs := &m.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true}
|
||||||
graphite2Ds := &m.DataSource{Id: 15, OrgId: 1, Name: "graphite2"}
|
graphite2Ds := &m.DataSource{Id: 15, OrgId: 1, Name: "graphite2"}
|
||||||
influxDBDs := &m.DataSource{Id: 16, OrgId: 1, Name: "InfluxDB"}
|
influxDBDs := &m.DataSource{Id: 16, OrgId: 1, Name: "InfluxDB"}
|
||||||
|
prom := &m.DataSource{Id: 17, OrgId: 1, Name: "Prometheus"}
|
||||||
|
|
||||||
bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
|
bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
|
||||||
query.Result = []*m.DataSource{defaultDs, graphite2Ds}
|
query.Result = []*m.DataSource{defaultDs, graphite2Ds}
|
||||||
@ -38,6 +39,10 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|||||||
if query.Name == influxDBDs.Name {
|
if query.Name == influxDBDs.Name {
|
||||||
query.Result = influxDBDs
|
query.Result = influxDBDs
|
||||||
}
|
}
|
||||||
|
if query.Name == prom.Name {
|
||||||
|
query.Result = prom
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -214,5 +219,26 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Should be able to extract collapsed panels", func() {
|
||||||
|
json, err := ioutil.ReadFile("./test-data/collapsed-panels.json")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
dashJson, err := simplejson.NewJson(json)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
dash := m.NewDashboardFromJson(dashJson)
|
||||||
|
extractor := NewDashAlertExtractor(dash, 1)
|
||||||
|
|
||||||
|
alerts, err := extractor.GetAlerts()
|
||||||
|
|
||||||
|
Convey("Get rules without error", func() {
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("should be able to extract collapsed alerts", func() {
|
||||||
|
So(len(alerts), ShouldEqual, 4)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
597
pkg/services/alerting/test-data/collapsed-panels.json
Normal file
597
pkg/services/alerting/test-data/collapsed-panels.json
Normal file
@ -0,0 +1,597 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"builtIn": 1,
|
||||||
|
"datasource": "-- Grafana --",
|
||||||
|
"enable": true,
|
||||||
|
"hide": true,
|
||||||
|
"iconColor": "rgba(0, 211, 255, 1)",
|
||||||
|
"name": "Annotations & Alerts",
|
||||||
|
"type": "dashboard"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editable": true,
|
||||||
|
"gnetId": null,
|
||||||
|
"graphTooltip": 0,
|
||||||
|
"id": 127,
|
||||||
|
"links": [],
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"gridPos": {
|
||||||
|
"h": 1,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 9,
|
||||||
|
"title": "Row title",
|
||||||
|
"type": "row"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alert": {
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"evaluator": {
|
||||||
|
"params": [
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"type": "gt"
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "and"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"params": [
|
||||||
|
"A",
|
||||||
|
"5m",
|
||||||
|
"now"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reducer": {
|
||||||
|
"params": [],
|
||||||
|
"type": "avg"
|
||||||
|
},
|
||||||
|
"type": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"executionErrorState": "alerting",
|
||||||
|
"frequency": "10s",
|
||||||
|
"handler": 1,
|
||||||
|
"name": "Panel Title alert",
|
||||||
|
"noDataState": "no_data",
|
||||||
|
"notifications": []
|
||||||
|
},
|
||||||
|
"aliasColors": {},
|
||||||
|
"bars": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"dashes": false,
|
||||||
|
"datasource": "Prometheus",
|
||||||
|
"fill": 1,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 9,
|
||||||
|
"w": 12,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
"id": 10,
|
||||||
|
"legend": {
|
||||||
|
"avg": false,
|
||||||
|
"current": false,
|
||||||
|
"max": false,
|
||||||
|
"min": false,
|
||||||
|
"show": true,
|
||||||
|
"total": false,
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"lines": true,
|
||||||
|
"linewidth": 1,
|
||||||
|
"nullPointMode": "null",
|
||||||
|
"percentage": false,
|
||||||
|
"pointradius": 5,
|
||||||
|
"points": false,
|
||||||
|
"renderer": "flot",
|
||||||
|
"seriesOverrides": [],
|
||||||
|
"spaceLength": 10,
|
||||||
|
"stack": false,
|
||||||
|
"steppedLine": false,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "go_goroutines",
|
||||||
|
"format": "time_series",
|
||||||
|
"intervalFactor": 1,
|
||||||
|
"legendFormat": "{{job}}",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"colorMode": "critical",
|
||||||
|
"fill": true,
|
||||||
|
"line": true,
|
||||||
|
"op": "gt",
|
||||||
|
"value": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "Panel Title",
|
||||||
|
"tooltip": {
|
||||||
|
"shared": true,
|
||||||
|
"sort": 0,
|
||||||
|
"value_type": "individual"
|
||||||
|
},
|
||||||
|
"type": "graph",
|
||||||
|
"xaxis": {
|
||||||
|
"buckets": null,
|
||||||
|
"mode": "time",
|
||||||
|
"name": null,
|
||||||
|
"show": true,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"yaxes": [
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridPos": {
|
||||||
|
"h": 9,
|
||||||
|
"w": 12,
|
||||||
|
"x": 12,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
"id": 14,
|
||||||
|
"limit": 10,
|
||||||
|
"links": [],
|
||||||
|
"onlyAlertsOnDashboard": true,
|
||||||
|
"show": "current",
|
||||||
|
"sortOrder": 1,
|
||||||
|
"stateFilter": [],
|
||||||
|
"title": "Panel Title",
|
||||||
|
"type": "alertlist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsed": true,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 1,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 10
|
||||||
|
},
|
||||||
|
"id": 6,
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"alert": {
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"evaluator": {
|
||||||
|
"params": [
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"type": "gt"
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "and"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"params": [
|
||||||
|
"A",
|
||||||
|
"5m",
|
||||||
|
"now"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reducer": {
|
||||||
|
"params": [],
|
||||||
|
"type": "avg"
|
||||||
|
},
|
||||||
|
"type": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"executionErrorState": "alerting",
|
||||||
|
"frequency": "10s",
|
||||||
|
"handler": 1,
|
||||||
|
"name": "Panel 2 alert",
|
||||||
|
"noDataState": "no_data",
|
||||||
|
"notifications": []
|
||||||
|
},
|
||||||
|
"aliasColors": {},
|
||||||
|
"bars": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"dashes": false,
|
||||||
|
"datasource": "Prometheus",
|
||||||
|
"fill": 1,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 9,
|
||||||
|
"w": 12,
|
||||||
|
"x": 0,
|
||||||
|
"y": 11
|
||||||
|
},
|
||||||
|
"id": 11,
|
||||||
|
"legend": {
|
||||||
|
"avg": false,
|
||||||
|
"current": false,
|
||||||
|
"max": false,
|
||||||
|
"min": false,
|
||||||
|
"show": true,
|
||||||
|
"total": false,
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"lines": true,
|
||||||
|
"linewidth": 1,
|
||||||
|
"links": [],
|
||||||
|
"nullPointMode": "null",
|
||||||
|
"percentage": false,
|
||||||
|
"pointradius": 5,
|
||||||
|
"points": false,
|
||||||
|
"renderer": "flot",
|
||||||
|
"seriesOverrides": [],
|
||||||
|
"spaceLength": 10,
|
||||||
|
"stack": false,
|
||||||
|
"steppedLine": false,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "go_goroutines",
|
||||||
|
"format": "time_series",
|
||||||
|
"intervalFactor": 1,
|
||||||
|
"legendFormat": "{{job}}",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"colorMode": "critical",
|
||||||
|
"fill": true,
|
||||||
|
"line": true,
|
||||||
|
"op": "gt",
|
||||||
|
"value": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "Panel 2",
|
||||||
|
"tooltip": {
|
||||||
|
"shared": true,
|
||||||
|
"sort": 0,
|
||||||
|
"value_type": "individual"
|
||||||
|
},
|
||||||
|
"type": "graph",
|
||||||
|
"xaxis": {
|
||||||
|
"buckets": null,
|
||||||
|
"mode": "time",
|
||||||
|
"name": null,
|
||||||
|
"show": true,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"yaxes": [
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alert": {
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"evaluator": {
|
||||||
|
"params": [
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"type": "gt"
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "and"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"params": [
|
||||||
|
"A",
|
||||||
|
"5m",
|
||||||
|
"now"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reducer": {
|
||||||
|
"params": [],
|
||||||
|
"type": "avg"
|
||||||
|
},
|
||||||
|
"type": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"executionErrorState": "alerting",
|
||||||
|
"frequency": "10s",
|
||||||
|
"handler": 1,
|
||||||
|
"name": "Panel 4 alert",
|
||||||
|
"noDataState": "no_data",
|
||||||
|
"notifications": []
|
||||||
|
},
|
||||||
|
"aliasColors": {},
|
||||||
|
"bars": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"dashes": false,
|
||||||
|
"datasource": "Prometheus",
|
||||||
|
"fill": 1,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 9,
|
||||||
|
"w": 12,
|
||||||
|
"x": 12,
|
||||||
|
"y": 11
|
||||||
|
},
|
||||||
|
"id": 15,
|
||||||
|
"legend": {
|
||||||
|
"avg": false,
|
||||||
|
"current": false,
|
||||||
|
"max": false,
|
||||||
|
"min": false,
|
||||||
|
"show": true,
|
||||||
|
"total": false,
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"lines": true,
|
||||||
|
"linewidth": 1,
|
||||||
|
"links": [],
|
||||||
|
"nullPointMode": "null",
|
||||||
|
"percentage": false,
|
||||||
|
"pointradius": 5,
|
||||||
|
"points": false,
|
||||||
|
"renderer": "flot",
|
||||||
|
"seriesOverrides": [],
|
||||||
|
"spaceLength": 10,
|
||||||
|
"stack": false,
|
||||||
|
"steppedLine": false,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "go_goroutines",
|
||||||
|
"format": "time_series",
|
||||||
|
"intervalFactor": 1,
|
||||||
|
"legendFormat": "{{job}}",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"colorMode": "critical",
|
||||||
|
"fill": true,
|
||||||
|
"line": true,
|
||||||
|
"op": "gt",
|
||||||
|
"value": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "Panel 4",
|
||||||
|
"tooltip": {
|
||||||
|
"shared": true,
|
||||||
|
"sort": 0,
|
||||||
|
"value_type": "individual"
|
||||||
|
},
|
||||||
|
"type": "graph",
|
||||||
|
"xaxis": {
|
||||||
|
"buckets": null,
|
||||||
|
"mode": "time",
|
||||||
|
"name": null,
|
||||||
|
"show": true,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"yaxes": [
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Row title",
|
||||||
|
"type": "row"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridPos": {
|
||||||
|
"h": 1,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 11
|
||||||
|
},
|
||||||
|
"id": 4,
|
||||||
|
"title": "Row title",
|
||||||
|
"type": "row"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alert": {
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"evaluator": {
|
||||||
|
"params": [
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"type": "gt"
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "and"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"params": [
|
||||||
|
"A",
|
||||||
|
"5m",
|
||||||
|
"now"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reducer": {
|
||||||
|
"params": [],
|
||||||
|
"type": "avg"
|
||||||
|
},
|
||||||
|
"type": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"executionErrorState": "alerting",
|
||||||
|
"frequency": "10s",
|
||||||
|
"handler": 1,
|
||||||
|
"name": "Panel 3 alert",
|
||||||
|
"noDataState": "no_data",
|
||||||
|
"notifications": []
|
||||||
|
},
|
||||||
|
"aliasColors": {},
|
||||||
|
"bars": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"dashes": false,
|
||||||
|
"datasource": "Prometheus",
|
||||||
|
"fill": 1,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 9,
|
||||||
|
"w": 12,
|
||||||
|
"x": 0,
|
||||||
|
"y": 12
|
||||||
|
},
|
||||||
|
"id": 12,
|
||||||
|
"legend": {
|
||||||
|
"avg": false,
|
||||||
|
"current": false,
|
||||||
|
"max": false,
|
||||||
|
"min": false,
|
||||||
|
"show": true,
|
||||||
|
"total": false,
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"lines": true,
|
||||||
|
"linewidth": 1,
|
||||||
|
"links": [],
|
||||||
|
"nullPointMode": "null",
|
||||||
|
"percentage": false,
|
||||||
|
"pointradius": 5,
|
||||||
|
"points": false,
|
||||||
|
"renderer": "flot",
|
||||||
|
"seriesOverrides": [],
|
||||||
|
"spaceLength": 10,
|
||||||
|
"stack": false,
|
||||||
|
"steppedLine": false,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "go_goroutines",
|
||||||
|
"format": "time_series",
|
||||||
|
"intervalFactor": 1,
|
||||||
|
"legendFormat": "{{job}}",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"colorMode": "critical",
|
||||||
|
"fill": true,
|
||||||
|
"line": true,
|
||||||
|
"op": "gt",
|
||||||
|
"value": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "Panel 3",
|
||||||
|
"tooltip": {
|
||||||
|
"shared": true,
|
||||||
|
"sort": 0,
|
||||||
|
"value_type": "individual"
|
||||||
|
},
|
||||||
|
"type": "graph",
|
||||||
|
"xaxis": {
|
||||||
|
"buckets": null,
|
||||||
|
"mode": "time",
|
||||||
|
"name": null,
|
||||||
|
"show": true,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"yaxes": [
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schemaVersion": 16,
|
||||||
|
"style": "dark",
|
||||||
|
"tags": [],
|
||||||
|
"templating": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"from": "now-6h",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"timepicker": {
|
||||||
|
"refresh_intervals": [
|
||||||
|
"5s",
|
||||||
|
"10s",
|
||||||
|
"30s",
|
||||||
|
"1m",
|
||||||
|
"5m",
|
||||||
|
"15m",
|
||||||
|
"30m",
|
||||||
|
"1h",
|
||||||
|
"2h",
|
||||||
|
"1d"
|
||||||
|
],
|
||||||
|
"time_options": [
|
||||||
|
"5m",
|
||||||
|
"15m",
|
||||||
|
"1h",
|
||||||
|
"6h",
|
||||||
|
"12h",
|
||||||
|
"24h",
|
||||||
|
"2d",
|
||||||
|
"7d",
|
||||||
|
"30d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"timezone": "",
|
||||||
|
"title": "New dashboard Copy",
|
||||||
|
"uid": "6v5pg36zk",
|
||||||
|
"version": 17
|
||||||
|
}
|
@ -13,6 +13,7 @@ import (
|
|||||||
// DashboardService service for operating on dashboards
|
// DashboardService service for operating on dashboards
|
||||||
type DashboardService interface {
|
type DashboardService interface {
|
||||||
SaveDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error)
|
SaveDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error)
|
||||||
|
ImportDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DashboardProvisioningService service for operating on provisioned dashboards
|
// DashboardProvisioningService service for operating on provisioned dashboards
|
||||||
@ -214,6 +215,20 @@ func (dr *dashboardServiceImpl) SaveDashboard(dto *SaveDashboardDTO) (*models.Da
|
|||||||
return cmd.Result, nil
|
return cmd.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dr *dashboardServiceImpl) ImportDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error) {
|
||||||
|
cmd, err := dr.buildSaveDashboardCommand(dto, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bus.Dispatch(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd.Result, nil
|
||||||
|
}
|
||||||
|
|
||||||
type FakeDashboardService struct {
|
type FakeDashboardService struct {
|
||||||
SaveDashboardResult *models.Dashboard
|
SaveDashboardResult *models.Dashboard
|
||||||
SaveDashboardError error
|
SaveDashboardError error
|
||||||
@ -230,6 +245,10 @@ func (s *FakeDashboardService) SaveDashboard(dto *SaveDashboardDTO) (*models.Das
|
|||||||
return s.SaveDashboardResult, s.SaveDashboardError
|
return s.SaveDashboardResult, s.SaveDashboardError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FakeDashboardService) ImportDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error) {
|
||||||
|
return s.SaveDashboard(dto)
|
||||||
|
}
|
||||||
|
|
||||||
func MockDashboardService(mock *FakeDashboardService) {
|
func MockDashboardService(mock *FakeDashboardService) {
|
||||||
NewService = func() DashboardService {
|
NewService = func() DashboardService {
|
||||||
return mock
|
return mock
|
||||||
|
@ -105,6 +105,18 @@ type SessionWrapper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SessionWrapper) Start(c *macaron.Context) error {
|
func (s *SessionWrapper) Start(c *macaron.Context) error {
|
||||||
|
// See https://github.com/grafana/grafana/issues/11155 for details on why
|
||||||
|
// a recover and retry is needed
|
||||||
|
defer func() error {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
var retryErr error
|
||||||
|
s.session, retryErr = s.manager.Start(c)
|
||||||
|
return retryErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
s.session, err = s.manager.Start(c)
|
s.session, err = s.manager.Start(c)
|
||||||
return err
|
return err
|
||||||
|
@ -22,6 +22,12 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
pageClass: 'page-dashboard',
|
pageClass: 'page-dashboard',
|
||||||
})
|
})
|
||||||
|
.when('/d/:uid', {
|
||||||
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
|
controller: 'LoadDashboardCtrl',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
pageClass: 'page-dashboard',
|
||||||
|
})
|
||||||
.when('/dashboard/:type/:slug', {
|
.when('/dashboard/:type/:slug', {
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
controller: 'LoadDashboardCtrl',
|
controller: 'LoadDashboardCtrl',
|
||||||
@ -98,6 +104,11 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
controller: 'FolderDashboardsCtrl',
|
controller: 'FolderDashboardsCtrl',
|
||||||
controllerAs: 'ctrl',
|
controllerAs: 'ctrl',
|
||||||
})
|
})
|
||||||
|
.when('/dashboards/f/:uid', {
|
||||||
|
templateUrl: 'public/app/features/dashboard/partials/folder_dashboards.html',
|
||||||
|
controller: 'FolderDashboardsCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
})
|
||||||
.when('/org', {
|
.when('/org', {
|
||||||
templateUrl: 'public/app/features/org/partials/orgDetails.html',
|
templateUrl: 'public/app/features/org/partials/orgDetails.html',
|
||||||
controller: 'OrgDetailsCtrl',
|
controller: 'OrgDetailsCtrl',
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
<link rel="icon" type="image/png" href="public/img/fav32.png">
|
<link rel="icon" type="image/png" href="public/img/fav32.png">
|
||||||
<link rel="mask-icon" href="public/img/grafana_mask_icon.svg" color="#F05A28">
|
<link rel="mask-icon" href="public/img/grafana_mask_icon.svg" color="#F05A28">
|
||||||
|
<link rel="apple-touch-icon" href="public/img/fav32.png">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user