diff --git a/conf/defaults.ini b/conf/defaults.ini index 15b8927e65a..caccebbd910 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -550,3 +550,5 @@ container_name = # Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer server_url = callback_url = +concurrent_limit = 10 +concurrent_limit_alerting = 5 diff --git a/conf/sample.ini b/conf/sample.ini index 2ef254f79b9..7a460faca0e 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -471,3 +471,5 @@ log_queries = # Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer ;server_url = ;callback_url = +;concurrent_limit = 10 +;concurrent_limit_alerting = 5 diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index 7fbd956f4f9..839893f3444 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -113,6 +113,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { Timeout: alertTimeout / 2, OrgId: context.Rule.OrgId, OrgRole: m.ROLE_ADMIN, + IsAlert: true, } ref, err := context.GetDashboardUID() diff --git a/pkg/services/alerting/result_handler.go b/pkg/services/alerting/result_handler.go index 363d06d1132..893cca948f9 100644 --- a/pkg/services/alerting/result_handler.go +++ b/pkg/services/alerting/result_handler.go @@ -100,7 +100,7 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error { } } } - handler.notifier.SendIfNeeded(evalContext) + handler.notifier.SendIfNeeded(evalContext) return nil } diff --git a/pkg/services/rendering/interface.go b/pkg/services/rendering/interface.go index 85c139cfc04..856e6e683ff 100644 --- a/pkg/services/rendering/interface.go +++ b/pkg/services/rendering/interface.go @@ -22,6 +22,7 @@ type Opts struct { Path string Encoding string Timezone string + IsAlert bool } type RenderResult struct { diff --git a/pkg/services/rendering/rendering.go b/pkg/services/rendering/rendering.go index ecef83d74d9..2b9d91771e9 100644 --- a/pkg/services/rendering/rendering.go +++ b/pkg/services/rendering/rendering.go @@ -24,12 +24,13 @@ func init() { } type RenderingService struct { - log log.Logger - pluginClient *plugin.Client - grpcPlugin pluginModel.RendererPlugin - pluginInfo *plugins.RendererPlugin - renderAction renderFunc - domain string + log log.Logger + pluginClient *plugin.Client + grpcPlugin pluginModel.RendererPlugin + pluginInfo *plugins.RendererPlugin + renderAction renderFunc + domain string + inProgressCount int Cfg *setting.Cfg `inject:""` } @@ -89,7 +90,27 @@ func (rs *RenderingService) Run(ctx context.Context) error { return err } +func (rs *RenderingService) getLimit(isAlerting bool) int { + if isAlerting { + return rs.Cfg.RendererLimitAlerting + } else { + return rs.Cfg.RendererLimit + } +} + func (rs *RenderingService) Render(ctx context.Context, opts Opts) (*RenderResult, error) { + if rs.inProgressCount > rs.getLimit(opts.IsAlert) { + return &RenderResult{ + FilePath: filepath.Join(setting.HomePath, "public/img/rendering_limit.png"), + }, nil + } + + defer func() { + rs.inProgressCount -= 1 + }() + + rs.inProgressCount += 1 + if rs.renderAction != nil { return rs.renderAction(ctx, opts) } else { diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 1a253b9b238..71e499f9298 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -196,10 +196,13 @@ type Cfg struct { Smtp SmtpSettings // Rendering - ImagesDir string - PhantomDir string - RendererUrl string - RendererCallbackUrl string + ImagesDir string + PhantomDir string + RendererUrl string + RendererCallbackUrl string + RendererLimit int + RendererLimitAlerting int + DisableBruteForceLoginProtection bool TempDataLifetime time.Duration @@ -645,6 +648,9 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { // Rendering renderSec := iniFile.Section("rendering") + cfg.RendererLimit = renderSec.Key("concurrent_limit").MustInt(10) + cfg.RendererLimitAlerting = renderSec.Key("concurrent_limit").MustInt(5) + cfg.RendererUrl = renderSec.Key("server_url").String() cfg.RendererCallbackUrl = renderSec.Key("callback_url").String() if cfg.RendererCallbackUrl == "" { diff --git a/public/img/rendering_error.png b/public/img/rendering_error.png new file mode 100644 index 00000000000..cc327c267be Binary files /dev/null and b/public/img/rendering_error.png differ diff --git a/public/img/rendering_limit.png b/public/img/rendering_limit.png new file mode 100644 index 00000000000..f2ba9aad0ba Binary files /dev/null and b/public/img/rendering_limit.png differ diff --git a/public/img/rendering_plugin_not_installed.png b/public/img/rendering_plugin_not_installed.png new file mode 100644 index 00000000000..f135ff7cc9f Binary files /dev/null and b/public/img/rendering_plugin_not_installed.png differ diff --git a/public/img/rendering_timeout.png b/public/img/rendering_timeout.png new file mode 100644 index 00000000000..07a87eb5de3 Binary files /dev/null and b/public/img/rendering_timeout.png differ