mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' of github.com:grafana/grafana
This commit is contained in:
commit
63caedb094
@ -14,6 +14,8 @@
|
|||||||
* **OAuth**: Add support for generic oauth, closes [#4718](https://github.com/grafana/grafana/pull/4718)
|
* **OAuth**: Add support for generic oauth, closes [#4718](https://github.com/grafana/grafana/pull/4718)
|
||||||
* **Cloudwatch**: Add support to expand multi select template variable, closes [#5003](https://github.com/grafana/grafana/pull/5003)
|
* **Cloudwatch**: Add support to expand multi select template variable, closes [#5003](https://github.com/grafana/grafana/pull/5003)
|
||||||
* **Graph Panel**: Now supports flexible lower/upper bounds on Y-Max and Y-Min, PR [#5720](https://github.com/grafana/grafana/pull/5720)
|
* **Graph Panel**: Now supports flexible lower/upper bounds on Y-Max and Y-Min, PR [#5720](https://github.com/grafana/grafana/pull/5720)
|
||||||
|
* **Background Tasks**: Now support automatic purging of old snapshots, closes [#4087](https://github.com/grafana/grafana/issues/4087)
|
||||||
|
* **Background Tasks**: Now support automatic purging of old rendered images, closes [#2172](https://github.com/grafana/grafana/issues/2172)
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
* **SystemD**: Change systemd description, closes [#5971](https://github.com/grafana/grafana/pull/5971)
|
* **SystemD**: Change systemd description, closes [#5971](https://github.com/grafana/grafana/pull/5971)
|
||||||
|
@ -161,6 +161,12 @@ external_enabled = true
|
|||||||
external_snapshot_url = https://snapshots-origin.raintank.io
|
external_snapshot_url = https://snapshots-origin.raintank.io
|
||||||
external_snapshot_name = Publish to snapshot.raintank.io
|
external_snapshot_name = Publish to snapshot.raintank.io
|
||||||
|
|
||||||
|
# remove expired snapshot
|
||||||
|
snapshot_remove_expired = true
|
||||||
|
|
||||||
|
# remove snapshots after 90 days
|
||||||
|
snapshot_TTL_days = 90
|
||||||
|
|
||||||
#################################### Users ####################################
|
#################################### Users ####################################
|
||||||
[users]
|
[users]
|
||||||
# disable user signup / registration
|
# disable user signup / registration
|
||||||
@ -267,6 +273,9 @@ from_address = admin@grafana.localhost
|
|||||||
welcome_email_on_sign_up = false
|
welcome_email_on_sign_up = false
|
||||||
templates_pattern = emails/*.html
|
templates_pattern = emails/*.html
|
||||||
|
|
||||||
|
[tmp.files]
|
||||||
|
rendered_image_ttl_days = 14
|
||||||
|
|
||||||
#################################### Logging ##########################
|
#################################### Logging ##########################
|
||||||
[log]
|
[log]
|
||||||
# Either "console", "file", "syslog". Default is console and file
|
# Either "console", "file", "syslog". Default is console and file
|
||||||
|
@ -149,6 +149,12 @@ check_for_updates = true
|
|||||||
;external_snapshot_url = https://snapshots-origin.raintank.io
|
;external_snapshot_url = https://snapshots-origin.raintank.io
|
||||||
;external_snapshot_name = Publish to snapshot.raintank.io
|
;external_snapshot_name = Publish to snapshot.raintank.io
|
||||||
|
|
||||||
|
# remove expired snapshot
|
||||||
|
;snapshot_remove_expired = true
|
||||||
|
|
||||||
|
# remove snapshots after 90 days
|
||||||
|
;snapshot_TTL_days = 90
|
||||||
|
|
||||||
#################################### Users ####################################
|
#################################### Users ####################################
|
||||||
[users]
|
[users]
|
||||||
# disable user signup / registration
|
# disable user signup / registration
|
||||||
|
@ -525,3 +525,9 @@ Set root url to a Grafana instance where you want to publish external snapshots
|
|||||||
|
|
||||||
### external_snapshot_name
|
### external_snapshot_name
|
||||||
Set name for external snapshot button. Defaults to `Publish to snapshot.raintank.io`
|
Set name for external snapshot button. Defaults to `Publish to snapshot.raintank.io`
|
||||||
|
|
||||||
|
### remove expired snapshot
|
||||||
|
Enabled to automatically remove expired snapshots
|
||||||
|
|
||||||
|
### remove snapshots after 90 days
|
||||||
|
Time to live for snapshots.
|
||||||
|
@ -14,7 +14,7 @@ func RenderToPng(c *middleware.Context) {
|
|||||||
queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery)
|
queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery)
|
||||||
|
|
||||||
renderOpts := &renderer.RenderOpts{
|
renderOpts := &renderer.RenderOpts{
|
||||||
Url: c.Params("*") + queryParams,
|
Path: c.Params("*") + queryParams,
|
||||||
Width: queryReader.Get("width", "800"),
|
Width: queryReader.Get("width", "800"),
|
||||||
Height: queryReader.Get("height", "400"),
|
Height: queryReader.Get("height", "400"),
|
||||||
OrgId: c.OrgId,
|
OrgId: c.OrgId,
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/metrics"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
alertingInit "github.com/grafana/grafana/pkg/services/alerting/init"
|
alertingInit "github.com/grafana/grafana/pkg/services/alerting/init"
|
||||||
|
"github.com/grafana/grafana/pkg/services/backgroundtasks"
|
||||||
"github.com/grafana/grafana/pkg/services/eventpublisher"
|
"github.com/grafana/grafana/pkg/services/eventpublisher"
|
||||||
"github.com/grafana/grafana/pkg/services/notifications"
|
"github.com/grafana/grafana/pkg/services/notifications"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
@ -62,13 +63,13 @@ func main() {
|
|||||||
writePIDFile()
|
writePIDFile()
|
||||||
initRuntime()
|
initRuntime()
|
||||||
metrics.Init()
|
metrics.Init()
|
||||||
|
|
||||||
search.Init()
|
search.Init()
|
||||||
login.Init()
|
login.Init()
|
||||||
social.NewOAuthService()
|
social.NewOAuthService()
|
||||||
eventpublisher.Init()
|
eventpublisher.Init()
|
||||||
plugins.Init()
|
plugins.Init()
|
||||||
alertingInit.Init()
|
alertingInit.Init()
|
||||||
|
backgroundtasks.Init()
|
||||||
|
|
||||||
if err := notifications.Init(); err != nil {
|
if err := notifications.Init(); err != nil {
|
||||||
log.Fatal(3, "Notification service failed to initialize", err)
|
log.Fatal(3, "Notification service failed to initialize", err)
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type RenderOpts struct {
|
type RenderOpts struct {
|
||||||
Url string
|
Path string
|
||||||
Width string
|
Width string
|
||||||
Height string
|
Height string
|
||||||
Timeout string
|
Timeout string
|
||||||
@ -28,14 +28,14 @@ type RenderOpts struct {
|
|||||||
var rendererLog log.Logger = log.New("png-renderer")
|
var rendererLog log.Logger = log.New("png-renderer")
|
||||||
|
|
||||||
func RenderToPng(params *RenderOpts) (string, error) {
|
func RenderToPng(params *RenderOpts) (string, error) {
|
||||||
rendererLog.Info("Rendering", "url", params.Url)
|
rendererLog.Info("Rendering", "path", params.Path)
|
||||||
|
|
||||||
var executable = "phantomjs"
|
var executable = "phantomjs"
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
executable = executable + ".exe"
|
executable = executable + ".exe"
|
||||||
}
|
}
|
||||||
|
|
||||||
params.Url = fmt.Sprintf("%s://localhost:%s/%s", setting.Protocol, setting.HttpPort, params.Url)
|
url := fmt.Sprintf("%s://localhost:%s/%s", setting.Protocol, 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"))
|
||||||
@ -48,7 +48,7 @@ func RenderToPng(params *RenderOpts) (string, error) {
|
|||||||
cmdArgs := []string{
|
cmdArgs := []string{
|
||||||
"--ignore-ssl-errors=true",
|
"--ignore-ssl-errors=true",
|
||||||
scriptPath,
|
scriptPath,
|
||||||
"url=" + params.Url,
|
"url=" + url,
|
||||||
"width=" + params.Width,
|
"width=" + params.Width,
|
||||||
"height=" + params.Height,
|
"height=" + params.Height,
|
||||||
"png=" + pngPath,
|
"png=" + pngPath,
|
||||||
|
7
pkg/models/timer.go
Normal file
7
pkg/models/timer.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type HourCommand struct {
|
||||||
|
Time time.Time
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -85,7 +86,15 @@ func checkForUpdates() {
|
|||||||
for _, gplug := range gNetPlugins {
|
for _, gplug := range gNetPlugins {
|
||||||
if gplug.Slug == plug.Id {
|
if gplug.Slug == plug.Id {
|
||||||
plug.GrafanaNetVersion = gplug.Version
|
plug.GrafanaNetVersion = gplug.Version
|
||||||
|
|
||||||
|
plugVersion, err1 := version.NewVersion(plug.Info.Version)
|
||||||
|
gplugVersion, err2 := version.NewVersion(gplug.Version)
|
||||||
|
|
||||||
|
if err1 != nil || err2 != nil {
|
||||||
plug.GrafanaNetHasUpdate = plug.Info.Version != plug.GrafanaNetVersion
|
plug.GrafanaNetHasUpdate = plug.Info.Version != plug.GrafanaNetVersion
|
||||||
|
} else {
|
||||||
|
plug.GrafanaNetHasUpdate = plugVersion.LessThan(gplugVersion)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,4 +126,11 @@ func checkForUpdates() {
|
|||||||
GrafanaLatestVersion = githubLatest.Stable
|
GrafanaLatestVersion = githubLatest.Stable
|
||||||
GrafanaHasUpdate = githubLatest.Stable != setting.BuildVersion
|
GrafanaHasUpdate = githubLatest.Stable != setting.BuildVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currVersion, err1 := version.NewVersion(setting.BuildVersion)
|
||||||
|
latestVersion, err2 := version.NewVersion(GrafanaLatestVersion)
|
||||||
|
|
||||||
|
if err1 == nil && err2 == nil {
|
||||||
|
GrafanaHasUpdate = currVersion.LessThan(latestVersion)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,5 +184,6 @@ func validateToValue(to string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("cannot parse to value %s", to)
|
_, err := time.ParseDuration(to)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
@ -93,14 +93,18 @@ func (e *Engine) executeJob(job *Job) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) resultDispatcher() {
|
func (e *Engine) resultDispatcher() {
|
||||||
|
for result := range e.resultQueue {
|
||||||
|
go e.handleResponse(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Engine) handleResponse(result *EvalContext) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
e.log.Error("Panic in resultDispatcher", "error", err, "stack", log.Stack(1))
|
e.log.Error("Panic in resultDispatcher", "error", err, "stack", log.Stack(1))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for result := range e.resultQueue {
|
|
||||||
e.log.Debug("Alert Rule Result", "ruleId", result.Rule.Id, "firing", result.Firing)
|
e.log.Debug("Alert Rule Result", "ruleId", result.Rule.Id, "firing", result.Firing)
|
||||||
e.resultHandler.Handle(result)
|
e.resultHandler.Handle(result)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -71,7 +71,7 @@ func (c *EvalContext) GetNotificationTitle() string {
|
|||||||
return "[" + c.GetStateModel().Text + "] " + c.Rule.Name
|
return "[" + c.GetStateModel().Text + "] " + c.Rule.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EvalContext) getDashboardSlug() (string, error) {
|
func (c *EvalContext) GetDashboardSlug() (string, error) {
|
||||||
if c.dashboardSlug != "" {
|
if c.dashboardSlug != "" {
|
||||||
return c.dashboardSlug, nil
|
return c.dashboardSlug, nil
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ func (c *EvalContext) getDashboardSlug() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *EvalContext) GetRuleUrl() (string, error) {
|
func (c *EvalContext) GetRuleUrl() (string, error) {
|
||||||
if slug, err := c.getDashboardSlug(); err != nil {
|
if slug, err := c.GetDashboardSlug(); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else {
|
} else {
|
||||||
ruleUrl := fmt.Sprintf("%sdashboard/db/%s?fullscreen&edit&tab=alert&panelId=%d", setting.AppUrl, slug, c.Rule.PanelId)
|
ruleUrl := fmt.Sprintf("%sdashboard/db/%s?fullscreen&edit&tab=alert&panelId=%d", setting.AppUrl, slug, c.Rule.PanelId)
|
||||||
@ -94,15 +94,6 @@ func (c *EvalContext) GetRuleUrl() (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EvalContext) GetImageUrl() (string, error) {
|
|
||||||
if slug, err := c.getDashboardSlug(); err != nil {
|
|
||||||
return "", err
|
|
||||||
} else {
|
|
||||||
ruleUrl := fmt.Sprintf("%sdashboard-solo/db/%s?&panelId=%d", setting.AppUrl, slug, c.Rule.PanelId)
|
|
||||||
return ruleUrl, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEvalContext(rule *Rule) *EvalContext {
|
func NewEvalContext(rule *Rule) *EvalContext {
|
||||||
return &EvalContext{
|
return &EvalContext{
|
||||||
StartTime: time.Now(),
|
StartTime: time.Now(),
|
||||||
|
@ -20,7 +20,7 @@ type DefaultEvalHandler struct {
|
|||||||
func NewEvalHandler() *DefaultEvalHandler {
|
func NewEvalHandler() *DefaultEvalHandler {
|
||||||
return &DefaultEvalHandler{
|
return &DefaultEvalHandler{
|
||||||
log: log.New("alerting.evalHandler"),
|
log: log.New("alerting.evalHandler"),
|
||||||
alertJobTimeout: time.Second * 10,
|
alertJobTimeout: time.Second * 15,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package alerting
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"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"
|
||||||
@ -60,22 +61,22 @@ func (n *RootNotifier) sendNotifications(notifiers []Notifier, context *EvalCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *RootNotifier) uploadImage(context *EvalContext) error {
|
func (n *RootNotifier) uploadImage(context *EvalContext) (err error) {
|
||||||
uploader, _ := imguploader.NewImageUploader()
|
uploader, _ := imguploader.NewImageUploader()
|
||||||
|
|
||||||
imageUrl, err := context.GetImageUrl()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
renderOpts := &renderer.RenderOpts{
|
renderOpts := &renderer.RenderOpts{
|
||||||
Url: imageUrl,
|
|
||||||
Width: "800",
|
Width: "800",
|
||||||
Height: "400",
|
Height: "400",
|
||||||
Timeout: "30",
|
Timeout: "30",
|
||||||
OrgId: context.Rule.OrgId,
|
OrgId: context.Rule.OrgId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if slug, err := context.GetDashboardSlug(); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
renderOpts.Path = fmt.Sprintf("dashboard-solo/db/%s?&panelId=%d", slug, context.Rule.PanelId)
|
||||||
|
}
|
||||||
|
|
||||||
if imagePath, err := renderer.RenderToPng(renderOpts); err != nil {
|
if imagePath, err := renderer.RenderToPng(renderOpts); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,9 +52,8 @@ func (this *WebhookNotifier) Notify(context *alerting.EvalContext) {
|
|||||||
bodyJSON.Set("rule_url", ruleUrl)
|
bodyJSON.Set("rule_url", ruleUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
imageUrl, err := context.GetImageUrl()
|
if context.ImagePublicUrl != "" {
|
||||||
if err == nil {
|
bodyJSON.Set("image_url", context.ImagePublicUrl)
|
||||||
bodyJSON.Set("image_url", imageUrl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _ := bodyJSON.MarshalJSON()
|
body, _ := bodyJSON.MarshalJSON()
|
||||||
|
39
pkg/services/backgroundtasks/background_tasks.go
Normal file
39
pkg/services/backgroundtasks/background_tasks.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//"I want to be a cleaner, just like you," said Mathilda
|
||||||
|
//"Okay," replied Leon
|
||||||
|
|
||||||
|
package backgroundtasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tlog log.Logger = log.New("ticker")
|
||||||
|
)
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
go start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
go cleanup(time.Now())
|
||||||
|
|
||||||
|
ticker := time.NewTicker(time.Hour * 1)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case tick := <-ticker.C:
|
||||||
|
go cleanup(tick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanup(now time.Time) {
|
||||||
|
err := bus.Publish(&models.HourCommand{Time: now})
|
||||||
|
if err != nil {
|
||||||
|
tlog.Error("Cleanup job failed", "error", err)
|
||||||
|
}
|
||||||
|
}
|
38
pkg/services/backgroundtasks/remove_tmp_images.go
Normal file
38
pkg/services/backgroundtasks/remove_tmp_images.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package backgroundtasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
bus.AddEventListener(CleanTmpFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CleanTmpFiles(cmd *models.HourCommand) error {
|
||||||
|
files, err := ioutil.ReadDir(setting.ImagesDir)
|
||||||
|
|
||||||
|
var toDelete []os.FileInfo
|
||||||
|
for _, file := range files {
|
||||||
|
if file.ModTime().AddDate(0, 0, setting.RenderedImageTTLDays).Before(cmd.Time) {
|
||||||
|
toDelete = append(toDelete, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range toDelete {
|
||||||
|
fullPath := path.Join(setting.ImagesDir, file.Name())
|
||||||
|
err := os.Remove(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tlog.Debug("Found old rendered image to delete", "deleted", len(toDelete), "keept", len(files))
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
@ -5,7 +5,9 @@ import (
|
|||||||
|
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -13,6 +15,31 @@ func init() {
|
|||||||
bus.AddHandler("sql", GetDashboardSnapshot)
|
bus.AddHandler("sql", GetDashboardSnapshot)
|
||||||
bus.AddHandler("sql", DeleteDashboardSnapshot)
|
bus.AddHandler("sql", DeleteDashboardSnapshot)
|
||||||
bus.AddHandler("sql", SearchDashboardSnapshots)
|
bus.AddHandler("sql", SearchDashboardSnapshots)
|
||||||
|
bus.AddEventListener(DeleteExpiredSnapshots)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteExpiredSnapshots(cmd *m.HourCommand) error {
|
||||||
|
return inTransaction(func(sess *xorm.Session) error {
|
||||||
|
var expiredCount int64 = 0
|
||||||
|
var oldCount int64 = 0
|
||||||
|
|
||||||
|
if setting.SnapShotRemoveExpired {
|
||||||
|
deleteExpiredSql := "DELETE FROM dashboard_snapshot WHERE expires < ?"
|
||||||
|
expiredResponse, err := x.Exec(deleteExpiredSql, cmd.Time)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
expiredCount, _ = expiredResponse.RowsAffected()
|
||||||
|
}
|
||||||
|
|
||||||
|
oldSnapshotsSql := "DELETE FROM dashboard_snapshot WHERE created < ?"
|
||||||
|
oldResponse, err := x.Exec(oldSnapshotsSql, cmd.Time.AddDate(0, 0, setting.SnapShotTTLDays*-1))
|
||||||
|
oldCount, _ = oldResponse.RowsAffected()
|
||||||
|
|
||||||
|
log.Debug2("Deleted old/expired snaphots", "to old", oldCount, "expired", expiredCount)
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
|
func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
|
||||||
|
@ -81,6 +81,8 @@ var (
|
|||||||
ExternalSnapshotUrl string
|
ExternalSnapshotUrl string
|
||||||
ExternalSnapshotName string
|
ExternalSnapshotName string
|
||||||
ExternalEnabled bool
|
ExternalEnabled bool
|
||||||
|
SnapShotTTLDays int
|
||||||
|
SnapShotRemoveExpired bool
|
||||||
|
|
||||||
// User settings
|
// User settings
|
||||||
AllowUserSignUp bool
|
AllowUserSignUp bool
|
||||||
@ -120,6 +122,7 @@ var (
|
|||||||
// PhantomJs Rendering
|
// PhantomJs Rendering
|
||||||
ImagesDir string
|
ImagesDir string
|
||||||
PhantomDir string
|
PhantomDir string
|
||||||
|
RenderedImageTTLDays int
|
||||||
|
|
||||||
// for logging purposes
|
// for logging purposes
|
||||||
configFiles []string
|
configFiles []string
|
||||||
@ -495,6 +498,8 @@ func NewConfigContext(args *CommandLineArgs) error {
|
|||||||
ExternalSnapshotUrl = snapshots.Key("external_snapshot_url").String()
|
ExternalSnapshotUrl = snapshots.Key("external_snapshot_url").String()
|
||||||
ExternalSnapshotName = snapshots.Key("external_snapshot_name").String()
|
ExternalSnapshotName = snapshots.Key("external_snapshot_name").String()
|
||||||
ExternalEnabled = snapshots.Key("external_enabled").MustBool(true)
|
ExternalEnabled = snapshots.Key("external_enabled").MustBool(true)
|
||||||
|
SnapShotRemoveExpired = snapshots.Key("snapshot_remove_expired").MustBool(true)
|
||||||
|
SnapShotTTLDays = snapshots.Key("snapshot_TTL_days").MustInt(90)
|
||||||
|
|
||||||
// read data source proxy white list
|
// read data source proxy white list
|
||||||
DataProxyWhiteList = make(map[string]bool)
|
DataProxyWhiteList = make(map[string]bool)
|
||||||
@ -535,6 +540,9 @@ func NewConfigContext(args *CommandLineArgs) error {
|
|||||||
ImagesDir = filepath.Join(DataPath, "png")
|
ImagesDir = filepath.Join(DataPath, "png")
|
||||||
PhantomDir = filepath.Join(HomePath, "vendor/phantomjs")
|
PhantomDir = filepath.Join(HomePath, "vendor/phantomjs")
|
||||||
|
|
||||||
|
tmpFilesSection := Cfg.Section("tmp.files")
|
||||||
|
RenderedImageTTLDays = tmpFilesSection.Key("rendered_image_ttl_days").MustInt(14)
|
||||||
|
|
||||||
analytics := Cfg.Section("analytics")
|
analytics := Cfg.Section("analytics")
|
||||||
ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
|
ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
|
||||||
CheckForUpdates = analytics.Key("check_for_updates").MustBool(true)
|
CheckForUpdates = analytics.Key("check_for_updates").MustBool(true)
|
||||||
|
@ -38,7 +38,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpClient = http.Client{
|
HttpClient = http.Client{
|
||||||
Timeout: time.Duration(10 * time.Second),
|
Timeout: time.Duration(15 * time.Second),
|
||||||
Transport: tr,
|
Transport: tr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,9 +102,9 @@ func (e *GraphiteExecutor) parseResponse(res *http.Response) ([]TargetResponseDT
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode == http.StatusUnauthorized {
|
if res.StatusCode/100 != 2 {
|
||||||
glog.Info("Request is Unauthorized", "status", res.Status, "body", string(body))
|
glog.Info("Request failed", "status", res.Status, "body", string(body))
|
||||||
return nil, fmt.Errorf("Request is Unauthorized status: %v body: %s", res.Status, string(body))
|
return nil, fmt.Errorf("Request failed status: %v", res.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
var data []TargetResponseDTO
|
var data []TargetResponseDTO
|
||||||
|
@ -64,13 +64,13 @@
|
|||||||
<a href="http://grafana.org" target="_blank">Grafana</a>
|
<a href="http://grafana.org" target="_blank">Grafana</a>
|
||||||
<span>v[[.BuildVersion]] (commit: [[.BuildCommit]])</span>
|
<span>v[[.BuildVersion]] (commit: [[.BuildCommit]])</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
[[if .NewGrafanaVersionExists]]
|
[[if .NewGrafanaVersionExists]]
|
||||||
|
<li>
|
||||||
<a href="http://grafana.org/download" target="_blank" bs-tooltip="'[[.NewGrafanaVersion]]'">
|
<a href="http://grafana.org/download" target="_blank" bs-tooltip="'[[.NewGrafanaVersion]]'">
|
||||||
New version available!
|
New version available!
|
||||||
</a>
|
</a>
|
||||||
[[end]]
|
|
||||||
</li>
|
</li>
|
||||||
|
[[end]]
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
Loading…
Reference in New Issue
Block a user